blob: 64226d36cfebb3a703c6e44c3ecc8de4d5a56169 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2012, 2020 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 java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.SortedArraySet;
import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.r.core.pkgmanager.IRPkgData;
import org.eclipse.statet.r.core.pkgmanager.IRPkgSet;
import org.eclipse.statet.r.core.pkgmanager.RPkgUtils;
import org.eclipse.statet.rj.renv.core.BasicRPkg;
import org.eclipse.statet.rj.renv.core.BasicRPkgCompilation;
import org.eclipse.statet.rj.renv.core.REnv;
import org.eclipse.statet.rj.renv.core.RLibPaths;
import org.eclipse.statet.rj.renv.core.RNumVersion;
import org.eclipse.statet.rj.renv.core.RPkg;
import org.eclipse.statet.rj.renv.core.RPkgCompilation;
import org.eclipse.statet.rj.renv.core.RPkgList;
import org.eclipse.statet.rj.renv.runtime.RPkgManager;
public class FullRPkgSet implements IRPkgSet.Ext {
public static final FullRPkgSet DUMMY= new FullRPkgSet();
private final REnv rEnv;
private int providing;
private final RLibPaths rLibPaths;
private final BasicRPkgCompilation<RPkgInfoAndData> installed;
private final List<String> priorities= new ArrayList<>(DEFAULT_PRIORITIES);
private final RPkgCompilation<IRPkgData> available;
private final RPkgListImpl<RPkgData> reverse;
private List<String> names;
private FullRPkgSet() { // DUMMY
this.rEnv= null;
this.rLibPaths= null;
this.installed= new BasicRPkgCompilation<>(0);
this.available= new BasicRPkgCompilation<>(0);
this.reverse= new RPkgListImpl<>(0);
}
public FullRPkgSet(final REnv rEnv, final RLibPaths rLibPaths,
final RPkgCompilation<IRPkgData> available) {
this.rEnv= rEnv;
this.providing= RPkgManager.INSTALLED | RPkgManager.AVAILABLE_REPOS;
if (!available.getSources().isEmpty()) {
this.providing |= RPkgManager.AVAILABLE_PKGS;
}
this.rLibPaths= rLibPaths;
this.installed= new BasicRPkgCompilation<>(rLibPaths.getRLibLocations().size());
this.available= available;
this.reverse= new RPkgListImpl<>(4);
}
@Override
public @NonNull REnv getREnv() {
return this.rEnv;
}
@Override
public int getProviding() {
return this.providing;
}
@Override
public @NonNull RLibPaths getRLibPaths() {
return this.rLibPaths;
}
@Override
public synchronized List<String> getNames() {
if (this.names == null) {
final List<String> availableNames= this.available.getNames();
final SortedArraySet<String> names= new SortedArraySet<>(
availableNames.toArray(new String[availableNames.size() + 16]),
availableNames.size(), RPkgUtils.NAMES_COLLATOR );
names.addAll(this.installed.getNames());
this.names= Collections.unmodifiableList(names);
}
return this.names;
}
@Override
public BasicRPkgCompilation<RPkgInfoAndData> getInstalled() {
return this.installed;
}
@Override
public List<String> getPriorities() {
return this.priorities;
}
@Override
public RPkgCompilation<IRPkgData> getAvailable() {
return this.available;
}
private List<RPkgList<? extends IRPkgData>> getAll() {
return ImCollections.concatList(this.installed.getAll(), this.available.getAll());
}
@Override
public IRPkgData getReverse(final String name) {
final int idx= this.reverse.indexOf(name);
RPkgData info;
if (idx >= 0) {
info= this.reverse.get(idx);
}
else {
info= new RPkgData(name, RNumVersion.NONE, null);
RPkgListImpl<VersionListRPkg> depends= null;
RPkgListImpl<VersionListRPkg> imports= null;
RPkgListImpl<VersionListRPkg> linkingTo= null;
RPkgListImpl<VersionListRPkg> suggests= null;
RPkgListImpl<VersionListRPkg> enhances= null;
for (final RPkgList<? extends IRPkgData> list : getAll()) {
for (int i= 0; i < list.size(); i++) {
final IRPkgData pkg= list.get(i);
if (name.equals(pkg.getName())) {
continue;
}
if (Util.findPkg(pkg.getDepends(), name) >= 0) {
if (depends == null) {
depends= new RPkgListImpl<>(4);
}
addRev(depends, pkg);
}
if (Util.findPkg(pkg.getImports(), name) >= 0) {
if (imports == null) {
imports= new RPkgListImpl<>(4);
}
addRev(imports, pkg);
}
if (Util.findPkg(pkg.getLinkingTo(), name) >= 0) {
if (linkingTo == null) {
linkingTo= new RPkgListImpl<>(4);
}
addRev(linkingTo, pkg);
}
if (Util.findPkg(pkg.getSuggests(), name) >= 0) {
if (suggests == null) {
suggests= new RPkgListImpl<>(4);
}
addRev(suggests, pkg);
}
if (Util.findPkg(pkg.getEnhances(), name) >= 0) {
if (enhances == null) {
enhances= new RPkgListImpl<>(4);
}
addRev(enhances, pkg);
}
}
}
info.setDepends((depends != null) ? depends : Collections.<BasicRPkg>emptyList());
info.setImports((imports != null) ? imports : Collections.<BasicRPkg>emptyList());
info.setLinkingTo((linkingTo != null) ? linkingTo : Collections.<BasicRPkg>emptyList());
info.setSuggests((suggests != null) ? suggests : Collections.<BasicRPkg>emptyList());
info.setEnhances((enhances != null) ? enhances : Collections.<BasicRPkg>emptyList());
this.reverse.add(-(idx + 1), info);
}
return info;
}
private void addRev(final RPkgListImpl<VersionListRPkg> depends, final RPkg v) {
final int idx= depends.indexOf(v.getName());
if (idx >= 0) {
final VersionListRPkg ref= depends.get(idx);
ref.addVersion(v.getVersion());
}
else {
depends.add(-idx - 1, new VersionListRPkg(v.getName(), v.getVersion()));
}
}
public void checkPkgInfo(final RPkgData pkg) {
{ final String priority= pkg.getPriority();
if (!this.priorities.contains(priority)) {
pkg.setPriority("other"); //$NON-NLS-1$
}
}
}
}