| /*=============================================================================# |
| # Copyright (c) 2007, 2019 Stephan Wahlbrink and others. |
| # |
| # This program and the accompanying materials are made available under the |
| # terms of the Eclipse Public License 2.0 which is available at |
| # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 |
| # which is available at https://www.apache.org/licenses/LICENSE-2.0. |
| # |
| # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 |
| # |
| # Contributors: |
| # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation |
| #=============================================================================*/ |
| |
| package org.eclipse.statet.rj.renv.core; |
| |
| import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert; |
| import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullElse; |
| import static org.eclipse.statet.jcommons.lang.SystemUtils.OS_WIN; |
| import static org.eclipse.statet.rj.renv.core.REnvUtils.standardizePathString; |
| |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| import java.nio.file.Path; |
| import java.nio.file.Paths; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Objects; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.eclipse.statet.jcommons.collections.ImCollections; |
| import org.eclipse.statet.jcommons.collections.ImList; |
| import org.eclipse.statet.jcommons.lang.NonNullByDefault; |
| import org.eclipse.statet.jcommons.lang.Nullable; |
| import org.eclipse.statet.jcommons.lang.SystemUtils; |
| import org.eclipse.statet.jcommons.status.ErrorStatus; |
| import org.eclipse.statet.jcommons.status.MultiStatus; |
| import org.eclipse.statet.jcommons.status.Status; |
| import org.eclipse.statet.jcommons.status.Statuses; |
| |
| import org.eclipse.statet.internal.rj.renv.core.REnvCoreInternals; |
| |
| |
| @NonNullByDefault |
| public abstract class BasicREnvConfiguration implements REnvConfiguration { |
| |
| |
| public static final String DEFAULT_R_DOC_DIRECTORY= |
| R_HOME_DIRECTORY_VAR_STRING + "/doc"; //$NON-NLS-1$ |
| public static final String DEFAULT_R_SHARE_DIRECTORY= |
| R_HOME_DIRECTORY_VAR_STRING + "/share"; //$NON-NLS-1$ |
| public static final String DEFAULT_R_INCLUDE_DIRECTORY= |
| R_HOME_DIRECTORY_VAR_STRING + "/include"; //$NON-NLS-1$ |
| |
| public static final ImList<String> DEFAULT_LIB_GROUP_IDS= ImCollections.newList( |
| RLibGroup.R_OTHER, |
| RLibGroup.R_USER, |
| RLibGroup.R_SITE, |
| RLibGroup.R_DEFAULT ); |
| |
| public static final String DEFAULT_R_DEFAULT_LOCATION_DIRECTORY= |
| R_HOME_DIRECTORY_VAR_STRING + "/library"; //$NON-NLS-1$ |
| public static final String DEFAULT_R_SITE_LOCATION_DIRECTORY= |
| R_HOME_DIRECTORY_VAR_STRING + "/site-library"; //$NON-NLS-1$ |
| |
| |
| protected static final String NAME_KEY= "name"; //$NON-NLS-1$ |
| protected static final String R_HOME_DIRECTORY_PATH_KEY= "RHomeDirectory.path"; //$NON-NLS-1$ |
| protected static final String R_ARCH_CODE_KEY= "RArch.code"; //$NON-NLS-1$ |
| protected static final String R_SHARE_DIRECTORY_PATH_KEY= "RShareDirectory.path"; //$NON-NLS-1$ |
| protected static final String R_INCLUDE_DIRECTORY_PATH_KEY= "RIncludeDirectory.path"; //$NON-NLS-1$ |
| protected static final String R_DOC_DIRECTORY_PATH_KEY= "RDocDirectory.path"; //$NON-NLS-1$ |
| protected static final String R_LIBS_KEY= "RLibs"; //$NON-NLS-1$ |
| protected static final String R_LIBS_SITE_DIRECTORY_PATHS_KEY= R_LIBS_KEY + ".SiteDirectory.paths"; //$NON-NLS-1$ |
| protected static final String R_LIBS_USER_DIRECTORY_PATHS_KEY= R_LIBS_KEY + ".UserDirectory.paths"; //$NON-NLS-1$ |
| protected static final String R_LIBS_OTHER_DIRECTORY_PATHS_KEY= R_LIBS_KEY + ".OtherDirectory.paths"; //$NON-NLS-1$ |
| protected static final String STATE_SHARED_TYPE_KEY= "State.Shared.type"; //$NON-NLS-1$ |
| protected static final String STATE_SHARED_DIRECTORY_PATH_KEY= "State.Shared.Directory.path"; //$NON-NLS-1$ |
| protected static final String STATE_SHARED_SERVER_URI_KEY= "State.Shared.Server.uri"; //$NON-NLS-1$ |
| |
| private static final Pattern PATHS_SEPARATOR_PATTERN= Pattern.compile(":,:", Pattern.LITERAL); //$NON-NLS-1$ |
| |
| protected static final Pattern R_HOME_DIRECTORY_VAR_PATTERN= Pattern.compile(R_HOME_DIRECTORY_VAR_STRING, Pattern.LITERAL); |
| |
| |
| protected static final int LOCAL= 1 << 0; |
| protected static final int REMOTE= 1 << 1; |
| |
| protected static final int SPEC_SETUP= 1 << 2; |
| |
| |
| private static @Nullable String objToString(final @Nullable Object o) { |
| return (o instanceof String) ? (String) o : null; |
| } |
| |
| private static List<String> objToPathStringList(final @Nullable Object o) { |
| Object[] array= null; |
| if (o instanceof String) { |
| array= PATHS_SEPARATOR_PATTERN.split((String) o); |
| } |
| else if (o instanceof List) { |
| array= ((List) o).toArray(); |
| } |
| else if (o instanceof Object[]) { |
| array= (Object[]) o; |
| } |
| ARRAY: if (array != null && array.length > 0) { |
| final List<String> paths= new ArrayList<>(array.length); |
| for (int i= 0; i < array.length; i++) { |
| if (array[i] instanceof String) { |
| final String s= standardizePathString((String) array[i]); |
| if (s != null) { |
| paths.add((String) array[i]); |
| } |
| } |
| else { |
| break ARRAY; |
| } |
| } |
| return paths; |
| } |
| return ImCollections.emptyList(); |
| } |
| |
| |
| private final REnv rEnv; |
| |
| private int flags; |
| |
| private String name; |
| |
| private @Nullable String rHomeDirectory; |
| private @Nullable Path rHomeDirectoryPath; |
| |
| private @Nullable String rArch; |
| |
| private @Nullable String rDocDirectory; |
| private @Nullable Path rDocDirectoryPath; |
| private @Nullable String rShareDirectory; |
| private @Nullable Path rShareDirectoryPath; |
| private @Nullable String rIncludeDirectory; |
| private @Nullable Path rIncludeDirectoryPath; |
| |
| private ImList<? extends RLibGroup> rLibGroups= ImCollections.emptyList(); |
| private ImList<? extends RLibLocation> rLibLocations= ImCollections.emptyList(); |
| |
| private final Path stateRootDirectoryPath; |
| private String stateSharedType; |
| private @Nullable String stateSharedDirectory; |
| private @Nullable Path stateSharedDirectoryPath; |
| private @Nullable String stateSharedServer; |
| private @Nullable URI stateSharedServerUri; |
| private Path stateLocalDirectoryPath; |
| |
| private final List<Status> pathStatus= new ArrayList<>(); |
| private @Nullable Status status; |
| |
| |
| public BasicREnvConfiguration(final REnv rEnv, |
| final Path stateRootDirectoryPath) { |
| this.rEnv= nonNullAssert(rEnv); |
| this.name= ""; //$NON-NLS-1$ |
| this.stateSharedType= SHARED_DIRECTORY; |
| this.stateRootDirectoryPath= stateRootDirectoryPath; |
| } |
| |
| |
| @Override |
| public REnv getREnv() { |
| return this.rEnv; |
| } |
| |
| |
| protected void onChanged(final String key) { |
| this.status= null; |
| } |
| |
| |
| protected final int getFlags() { |
| return this.flags; |
| } |
| |
| protected void setFlags(final int flags) { |
| if (Integer.bitCount(flags & (LOCAL | REMOTE)) > 1) { |
| throw new IllegalArgumentException(String.format("flags= 0x%1$08X", flags)); |
| } |
| if (flags != this.flags) { |
| this.flags= flags; |
| onChanged("flags"); |
| } |
| } |
| |
| @Override |
| public String getName() { |
| return this.name; |
| } |
| |
| protected void setName(final String name) { |
| nonNullAssert(name); |
| if (!Objects.equals(name, this.name)) { |
| this.name= name; |
| onChanged(NAME_KEY); |
| } |
| } |
| |
| |
| @Override |
| public boolean isLocal() { |
| return ((this.flags & LOCAL) != 0); |
| } |
| |
| @Override |
| public boolean isRemote() { |
| return ((this.flags & REMOTE) != 0); |
| } |
| |
| @Override |
| public synchronized Status getValidationStatus() { |
| Status status= this.status; |
| if (status == null) { |
| resolvePaths(); |
| status= nonNullAssert(this.status); |
| } |
| return status; |
| } |
| |
| |
| @Override |
| public @Nullable String getRHomeDirectory() { |
| return this.rHomeDirectory; |
| } |
| |
| @Override |
| public @Nullable Path getRHomeDirectoryPath() { |
| return this.rHomeDirectoryPath; |
| } |
| |
| protected void setRHomeDirectory(@Nullable String directory) { |
| directory= standardizePathString(directory); |
| if (!Objects.equals(directory, this.rHomeDirectory)) { |
| this.rHomeDirectory= directory; |
| onChanged(R_HOME_DIRECTORY_PATH_KEY); |
| } |
| } |
| |
| |
| @Override |
| public @Nullable String getRArch() { |
| return this.rArch; |
| } |
| |
| protected void setRArch(@Nullable String arch) { |
| arch= normalizeRArch(arch); |
| if (!Objects.equals(arch, this.rArch)) { |
| this.rArch= arch; |
| onChanged(R_ARCH_CODE_KEY); |
| } |
| } |
| |
| protected @Nullable String normalizeRArch(@Nullable String arch) { |
| if (arch == null || arch.isEmpty()) { |
| return null; |
| } |
| if (arch.charAt(0) == '/') { |
| if (arch.length() == 1) { |
| return null; |
| } |
| arch= arch.substring(1); |
| } |
| if (arch.equals("exec")) { //$NON-NLS-1$ |
| return null; |
| } |
| if (SystemUtils.getLocalOs() == OS_WIN) { |
| final String knownArch= SystemUtils.getArch(arch); |
| if (knownArch != null) { |
| return knownArch; |
| } |
| } |
| return arch; |
| } |
| |
| |
| @Override |
| public @Nullable String getRShareDirectory() { |
| return this.rDocDirectory; |
| } |
| |
| @Override |
| public @Nullable Path getRShareDirectoryPath() { |
| return this.rShareDirectoryPath; |
| } |
| |
| protected void setRShareDirectory(@Nullable String directory) { |
| directory= standardizePathString(directory); |
| if (!Objects.equals(directory, this.rShareDirectory)) { |
| this.rShareDirectory= directory; |
| onChanged(R_SHARE_DIRECTORY_PATH_KEY); |
| } |
| } |
| |
| @Override |
| public @Nullable String getRIncludeDirectory() { |
| return this.rIncludeDirectory; |
| } |
| |
| @Override |
| public @Nullable Path getRIncludeDirectoryPath() { |
| return this.rIncludeDirectoryPath; |
| } |
| |
| protected void setRIncludeDirectory(@Nullable String directory) { |
| directory= standardizePathString(directory); |
| if (!Objects.equals(directory, this.rIncludeDirectory)) { |
| this.rIncludeDirectory= directory; |
| onChanged(R_INCLUDE_DIRECTORY_PATH_KEY); |
| } |
| } |
| |
| @Override |
| public @Nullable String getRDocDirectory() { |
| return this.rDocDirectory; |
| } |
| |
| @Override |
| public @Nullable Path getRDocDirectoryPath() { |
| return this.rDocDirectoryPath; |
| } |
| |
| protected void setRDocDirectory(@Nullable String directory) { |
| directory= standardizePathString(directory); |
| if (!Objects.equals(directory, this.rDocDirectory)) { |
| this.rDocDirectory= directory; |
| onChanged(R_DOC_DIRECTORY_PATH_KEY); |
| } |
| this.rDocDirectory= standardizePathString(directory); |
| } |
| |
| |
| @Override |
| public ImList<? extends RLibGroup> getRLibGroups() { |
| return this.rLibGroups; |
| } |
| |
| @Override |
| public @Nullable RLibGroup getRLibGroup(final String id) { |
| for (final RLibGroup group : this.rLibGroups) { |
| if (group.getId() == id) { |
| return group; |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public ImList<? extends RLibLocation> getRLibLocations() { |
| return this.rLibLocations; |
| } |
| |
| protected void setRLibGroups(final ImList<? extends RLibGroup> libGroups) { |
| nonNullAssert(libGroups); |
| if (!Objects.equals(libGroups, this.rLibGroups)) { |
| this.rLibGroups= libGroups; |
| this.rLibLocations= REnvCoreInternals.listRLibLocations(libGroups); |
| onChanged(R_LIBS_KEY); |
| } |
| } |
| |
| |
| @Override |
| public String getStateSharedType() { |
| return this.stateSharedType; |
| } |
| |
| protected void setStateSharedType(final String type) { |
| nonNullAssert(type); |
| if (!Objects.equals(type, this.stateSharedType)) { |
| this.stateSharedType= type.intern(); |
| onChanged(STATE_SHARED_TYPE_KEY); |
| } |
| } |
| |
| @Override |
| public @Nullable String getStateSharedDirectory() { |
| return this.stateSharedDirectory; |
| } |
| |
| @Override |
| public @Nullable Path getStateSharedDirectoryPath() { |
| return this.stateSharedDirectoryPath; |
| } |
| |
| protected void setStateSharedDirectory(@Nullable String directory) { |
| directory= standardizePathString(directory); |
| if (!Objects.equals(directory, this.stateSharedDirectory)) { |
| this.stateSharedDirectory= directory; |
| this.stateSharedDirectoryPath= null; |
| onChanged(STATE_SHARED_DIRECTORY_PATH_KEY); |
| } |
| } |
| |
| @Override |
| public @Nullable String getStateSharedServer() { |
| return this.stateSharedServer; |
| } |
| |
| @Override |
| public @Nullable URI getStateSharedServerUri() { |
| return this.stateSharedServerUri; |
| } |
| |
| protected void setStateSharedServer(final @Nullable String uri) { |
| if (!Objects.equals(uri, this.stateSharedServer)) { |
| this.stateSharedServer= uri; |
| this.stateSharedServerUri= null; |
| onChanged(STATE_SHARED_SERVER_URI_KEY); |
| } |
| } |
| |
| @Override |
| public Path getStateLocalDirectoryPath() { |
| return this.stateLocalDirectoryPath; |
| } |
| |
| protected Path getDataRootDirectory() { |
| return this.stateRootDirectoryPath; |
| } |
| |
| |
| protected void resolvePaths() { |
| this.pathStatus.clear(); |
| if ((this.flags & (LOCAL | SPEC_SETUP)) == (LOCAL | SPEC_SETUP)) { |
| this.rHomeDirectoryPath= resolveDirectoryPath(getRHomeDirectory(), |
| true, "R home directory" ); |
| if (this.rHomeDirectoryPath != null) { |
| this.rDocDirectoryPath= resolveRDirectoryPath(this.rDocDirectory, |
| false, "R documentation installation directory" ); |
| this.rShareDirectoryPath= resolveRDirectoryPath(this.rShareDirectory, |
| false, "R share installation directory" ); |
| this.rIncludeDirectoryPath= resolveRDirectoryPath(this.rIncludeDirectory, |
| false, "R include installation directory" ); |
| for (final RLibLocation libLocation : this.rLibLocations) { |
| if (libLocation instanceof BasicRLibLocation) { |
| ((BasicRLibLocation) libLocation).setDirectoryPath( |
| resolveRDirectoryPath(libLocation.getDirectory(), |
| false, "R library location directory") ); |
| } |
| } |
| } |
| else { |
| this.rDocDirectoryPath= null; |
| this.rShareDirectoryPath= null; |
| this.rIncludeDirectoryPath= null; |
| for (final RLibLocation libLocation : this.rLibLocations) { |
| if (libLocation instanceof BasicRLibLocation) { |
| ((BasicRLibLocation) libLocation).setDirectoryPath(null); |
| } |
| } |
| } |
| } |
| |
| if (getStateSharedType() == SHARED_DIRECTORY && this.stateSharedDirectory != null) { |
| this.stateSharedDirectoryPath= resolveDirectoryPath(this.stateSharedDirectory, |
| true, "shared state directory" ); |
| } |
| else { |
| this.stateSharedDirectoryPath= getDataRootDirectory().resolve("shared"); |
| } |
| this.stateLocalDirectoryPath= getDataRootDirectory().resolve("local"); |
| |
| if (getStateSharedType() == SHARED_SERVER) { |
| URI url= resolveURL(this.stateSharedServer, |
| true, "shared state server" ); |
| if (url != null) { |
| try { |
| String scheme= url.getScheme(); |
| if (scheme == null) { |
| scheme= "http"; |
| } |
| String path= url.getPath(); |
| if (path == null || path.isEmpty() || path.equals("/")) { |
| path= "/default"; //$NON-NLS-1$ |
| } |
| else if (path.endsWith("/")) { |
| path= path.substring(0, path.length() - 1); |
| } |
| url= new URI(scheme, url.getUserInfo(), url.getHost(), url.getPort(), path, null, null); |
| } |
| catch (final URISyntaxException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| this.stateSharedServerUri= url; |
| } |
| |
| if (!this.pathStatus.isEmpty()) { |
| this.status= new MultiStatus(REnvCoreInternals.BUNDLE_ID, |
| String.format("Issues detected in R environment configuration '%1$s'.", getName() ), |
| null, |
| ImCollections.toList(this.pathStatus) ); |
| REnvCoreInternals.log(this.status); |
| } |
| else { |
| this.status= Statuses.OK_STATUS; |
| } |
| } |
| |
| protected @Nullable Path resolveDirectoryPath(final @Nullable String spec, |
| final boolean required, final String label) { |
| if (spec == null) { |
| if (required) { |
| this.pathStatus.add(new ErrorStatus(REnvCoreInternals.BUNDLE_ID, |
| String.format("%1$s: the specification of the resource path is missing.", label) )); |
| } |
| return null; |
| } |
| try { |
| return resolvePath(spec); |
| } |
| catch (final Exception e) { |
| this.pathStatus.add(Statuses.newStatus((required) ? Status.ERROR : Status.WARNING, |
| REnvCoreInternals.BUNDLE_ID, 0, |
| String.format("%1$s: failed to resolve the specified resource path '%2$s'.", label, spec), |
| e )); |
| return null; |
| } |
| } |
| |
| protected @Nullable Path resolveRDirectoryPath(@Nullable String spec, |
| final boolean required, final String label) { |
| if (spec == null) { |
| if (required) { |
| this.pathStatus.add(new ErrorStatus(REnvCoreInternals.BUNDLE_ID, |
| String.format("%1$s: the specification of the resource path is missing.", label) )); |
| } |
| return null; |
| } |
| try { |
| final Matcher matcher= R_HOME_DIRECTORY_VAR_PATTERN.matcher(spec); |
| if (matcher.find()) { |
| spec= matcher.replaceAll(Matcher.quoteReplacement( |
| this.rHomeDirectoryPath.toString() )); |
| } |
| return resolvePath(spec); |
| } |
| catch (final Exception e) { |
| this.pathStatus.add(Statuses.newStatus((required) ? Status.ERROR : Status.WARNING, |
| REnvCoreInternals.BUNDLE_ID, 0, |
| String.format("%1$s: failed to resolve the specified resource path '%2$s'.", label, spec), |
| e )); |
| return null; |
| } |
| } |
| |
| protected @Nullable URI resolveURL(final @Nullable String spec, |
| final boolean required, final String label) { |
| if (spec == null) { |
| if (required) { |
| this.pathStatus.add(new ErrorStatus(REnvCoreInternals.BUNDLE_ID, |
| String.format("%1$s: the specification of the url is missing.", label) )); |
| } |
| return null; |
| } |
| try { |
| final URI url= new URI(spec); |
| |
| final String host= url.getHost(); |
| if (host == null || host.isEmpty()) { |
| this.pathStatus.add(new ErrorStatus(REnvCoreInternals.BUNDLE_ID, |
| String.format("%1$s: The specified url '%2$s' is invalid, a host is required.", label, spec) )); |
| return null; |
| } |
| |
| return url; |
| } |
| catch (final Exception e) { |
| this.pathStatus.add(new ErrorStatus(REnvCoreInternals.BUNDLE_ID, |
| String.format("%1$s: The specified url '%2$s' is invalid.", label, spec), |
| e )); |
| return null; |
| } |
| } |
| |
| protected void load(final Map<?, ?> settings) { |
| setName(nonNullElse(objToString(settings.get(NAME_KEY)), "")); //$NON-NLS-1$ |
| if ((getFlags() & SPEC_SETUP) != 0) { |
| setRHomeDirectory(objToString(settings.get(R_HOME_DIRECTORY_PATH_KEY))); |
| setRArch(objToString(settings.get(R_ARCH_CODE_KEY))); |
| setRShareDirectory(objToString(settings.get(R_SHARE_DIRECTORY_PATH_KEY))); |
| setRIncludeDirectory(objToString(settings.get(R_INCLUDE_DIRECTORY_PATH_KEY))); |
| setRDocDirectory(objToString(settings.get(R_DOC_DIRECTORY_PATH_KEY))); |
| |
| final ImList<String> libGroupIds= DEFAULT_LIB_GROUP_IDS; |
| final List<RLibGroup> libGroups= new ArrayList<>(libGroupIds.size()); |
| for (final String groupId : libGroupIds) { |
| final List<RLibLocation> locations= new ArrayList<>(); |
| final String key= getLibGroupDirectoryPathsKey(groupId); |
| if (key != null) { |
| final List<String> pathList= objToPathStringList(settings.get(key)); |
| for (final String path : pathList) { |
| locations.add(new BasicRLibLocation(RLibLocation.USER, path, null)); |
| } |
| } |
| if (completeLibGroup(groupId, locations)) { |
| libGroups.add(new BasicRLibGroup(groupId, |
| getLibGroupLabel(groupId, libGroups.size() + 1), |
| ImCollections.toList(locations) )); |
| } |
| } |
| setRLibGroups(ImCollections.toList(libGroups)); |
| |
| setStateSharedType(nonNullElse(objToString(settings.get(STATE_SHARED_TYPE_KEY)), SHARED_DIRECTORY)); |
| switch (getStateSharedType()) { |
| case SHARED_DIRECTORY: |
| setStateSharedDirectory(objToString(settings.get(STATE_SHARED_DIRECTORY_PATH_KEY))); |
| break; |
| case SHARED_SERVER: |
| setStateSharedServer(objToString(settings.get(STATE_SHARED_SERVER_URI_KEY))); |
| break; |
| default: |
| break; |
| } |
| } |
| } |
| |
| protected @Nullable String getLibGroupDirectoryPathsKey(final String id) { |
| switch (id) { |
| case RLibGroup.R_SITE: |
| return R_LIBS_SITE_DIRECTORY_PATHS_KEY; |
| case RLibGroup.R_USER: |
| return R_LIBS_USER_DIRECTORY_PATHS_KEY; |
| case RLibGroup.R_OTHER: |
| return R_LIBS_OTHER_DIRECTORY_PATHS_KEY; |
| default: |
| return null; |
| } |
| } |
| |
| protected String getLibGroupLabel(final String id, final int num) { |
| final String label= REnvCoreInternals.getRLibGroupLabel(id); |
| return (label != null) ? |
| label : |
| String.format("Libraries %1$s", num); |
| } |
| |
| protected boolean completeLibGroup(final String id, final List<RLibLocation> locations) { |
| switch (id) { |
| case RLibGroup.R_DEFAULT: |
| locations.clear(); |
| locations.add(new BasicRLibLocation(RLibLocation.R, |
| DEFAULT_R_DEFAULT_LOCATION_DIRECTORY, null )); |
| return true; |
| default: |
| return true; |
| } |
| } |
| |
| |
| protected @Nullable Path resolvePath(final String spec) throws Exception { |
| return Paths.get(spec); |
| } |
| |
| |
| @Override |
| public int hashCode() { |
| return this.rEnv.hashCode(); |
| } |
| |
| protected boolean equalsType(final REnvConfiguration other) { |
| return (other instanceof BasicREnvConfiguration |
| && this.flags == ((BasicREnvConfiguration) other).flags ); |
| } |
| |
| @Override |
| public boolean equals(final @Nullable Object obj) { |
| if (this == obj) { |
| return true; |
| } |
| if (obj instanceof REnvConfiguration) { |
| final REnvConfiguration other= (REnvConfiguration) obj; |
| return (this.rEnv.equals(other.getREnv()) |
| && equalsType(other) |
| && ((this.flags & SPEC_SETUP) == 0 || ( |
| (Objects.equals(this.rHomeDirectory, other.getRHomeDirectory()) |
| && Objects.equals(this.rArch, other.getRArch()) |
| && Objects.equals(this.rDocDirectory, other.getRDocDirectory()) |
| && Objects.equals(this.rShareDirectory, other.getRShareDirectory()) |
| && Objects.equals(this.rIncludeDirectory, other.getRIncludeDirectory()) |
| && Objects.equals(this.rLibGroups, other.getRLibGroups())) ) |
| ) |
| && Objects.equals(this.stateSharedDirectory, other.getStateSharedDirectory()) |
| && Objects.equals(this.stateSharedServer, other.getStateSharedServer()) ); |
| } |
| return false; |
| } |
| |
| |
| @Override |
| public String toString() { |
| return this.rEnv.getId() + " (" + getName() + ", " + getRHomeDirectory() + ")"; |
| } |
| |
| } |