blob: 3a2bc4f328f4fd4013f8dc1404383ba491eec7d8 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2012, 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.internal.r.core.pkgmanager;
import static org.eclipse.statet.rj.renv.core.REnvUtils.standardizePathString;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.status.ErrorStatus;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.internal.r.core.renv.REnvManagerLibGroup;
import org.eclipse.statet.r.core.RCore;
import org.eclipse.statet.rj.data.RCharacterStore;
import org.eclipse.statet.rj.data.RDataUtils;
import org.eclipse.statet.rj.data.UnexpectedRDataException;
import org.eclipse.statet.rj.renv.core.BasicRLibGroup;
import org.eclipse.statet.rj.renv.core.BasicRLibLocation;
import org.eclipse.statet.rj.renv.core.RLibGroup;
import org.eclipse.statet.rj.renv.core.RLibLocation;
import org.eclipse.statet.rj.renv.runtime.RuntimeRLibPathsLoader;
import org.eclipse.statet.rj.services.RService;
@NonNullByDefault
public class REnvLibGroups {
private static String normalizePath(final String path) {
try {
return new URI("file", null, (path.charAt(0) == '/') ? path : '/' + path, null) //$NON-NLS-1$
.normalize()
.getPath();
}
catch (final URISyntaxException e) {}
return path;
}
private static RLibGroup newLibGroup(final String id, final List<RLibLocation> locations) {
return new BasicRLibGroup(id, REnvManagerLibGroup.getLabel(id), locations);
}
static RuntimeRLibPathsLoader loadFromR(final RService r,
final ProgressMonitor m) throws StatusException {
try {
final RLibGroup[] libGroups= new @NonNull RLibGroup[4];
final String rHome= standardizePathString(
RDataUtils.checkSingleCharValue(r.evalData("R.home()", m)) ); //$NON-NLS-1$
if (rHome == null) {
throw new UnexpectedRDataException("null");
}
final Pattern varPattern= Pattern.compile(r.getPlatform().getPathSep(), Pattern.LITERAL);
final Set<String> added= new HashSet<>();
{ final String userVar= RDataUtils.checkSingleCharValue(
r.evalData("Sys.getenv('R_LIBS_USER')", m) ); //$NON-NLS-1$
final String[] paths= varPattern.split(userVar);
final List<RLibLocation> locations= new ArrayList<>(paths.length);
for (String pathString : paths) {
pathString= standardizePathString(pathString);
if (pathString != null) {
added.add(normalizePath(pathString));
locations.add(new BasicRLibLocation(RLibLocation.R, pathString, null));
}
}
libGroups[1]= newLibGroup(RLibGroup.R_USER, locations);
}
{ final RCharacterStore paths= RDataUtils.checkRCharVector(
r.evalData(".Library.site", m) ).getData(); //$NON-NLS-1$
final int l= RDataUtils.checkIntLength(paths);
final List<RLibLocation> locations= new ArrayList<>(l);
for (int i= 0; i < l; i++) {
String pathString= paths.get(i);
pathString= standardizePathString(pathString);
if (pathString != null) {
added.add(normalizePath(pathString));
locations.add(new BasicRLibLocation(RLibLocation.R, pathString, null));
}
}
libGroups[2]= newLibGroup(RLibGroup.R_SITE, locations);
}
{ final RCharacterStore paths= RDataUtils.checkRCharVector(
r.evalData(".Library", m) ).getData(); //$NON-NLS-1$
final int l= RDataUtils.checkIntLength(paths);
final List<RLibLocation> locations= new ArrayList<>(l);
for (int i= 0; i < l; i++) {
String pathString= paths.get(i);
pathString= standardizePathString(pathString);
if (pathString != null) {
added.add(normalizePath(pathString));
locations.add(new BasicRLibLocation(RLibLocation.R, pathString, null));
}
}
libGroups[3]= newLibGroup(RLibGroup.R_DEFAULT, locations);
}
{ final RCharacterStore paths= RDataUtils.checkRCharVector(
r.evalData(".libPaths()", m) ).getData(); //$NON-NLS-1$
final int l= RDataUtils.checkIntLength(paths);
final List<RLibLocation> locations= new ArrayList<>(l);
for (int i= 0; i < l; i++) {
String pathString= paths.get(i);
pathString= standardizePathString(pathString);
if (pathString != null && added.add(normalizePath(pathString))) {
locations.add(new BasicRLibLocation(RLibLocation.R, pathString, null));
}
}
libGroups[0]= newLibGroup(RLibGroup.R_OTHER, locations);
}
return new RuntimeRLibPathsLoader(rHome, ImCollections.newList(libGroups));
}
catch (final StatusException | UnexpectedRDataException e) {
throw new StatusException(new ErrorStatus(RCore.BUNDLE_ID,
"An error occurred when detecting the R library path.",
e ));
}
}
}