blob: d8ee7066693a410d6ead751db504013dbad6e643 [file] [log] [blame]
package org.eclipse.core.internal.plugins;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.model.*;
import org.eclipse.core.runtime.PluginVersionIdentifier;
import org.eclipse.core.internal.runtime.InternalPlatform;
import org.eclipse.core.internal.runtime.Policy;
public class RegistryResolver {
private Map idmap;
private PluginRegistryModel reg;
private MultiStatus status;
private boolean trimPlugins = true;
private boolean crossLink = true;
public static final int MATCH_EXACT = 0;
public static final int MATCH_COMPATIBLE = 1;
public static final int MATCH_LATEST = 2;
private boolean DEBUG_RESOLVE = false;
private static final String OPTION_DEBUG_RESOLVE = "org.eclipse.core.runtime/registry/debug/resolve";
// constraint entry
private class Constraint {
private PluginDescriptorModel parent;
private PluginPrerequisiteModel prq;
private PluginVersionIdentifier ver;
private int type = MATCH_LATEST;
private ConstraintsEntry cEntry = null;
private Constraint(PluginDescriptorModel parent, PluginPrerequisiteModel prq) {
this.parent = parent;
this.prq = prq;
if (prq != null) {
ver = RegistryResolver.this.getVersionIdentifier(prq);
if (ver == null)
type = MATCH_LATEST;
else
if (prq.getMatch())
type = MATCH_EXACT;
else
type = MATCH_COMPATIBLE;
}
}
private int getMatchType() {
return type;
}
private ConstraintsEntry getConstraintsEntry() {
return cEntry;
}
private void setConstraintsEntry(ConstraintsEntry entry) {
cEntry = entry;
}
private PluginDescriptorModel getParent() {
return parent;
}
private PluginPrerequisiteModel getPrerequisite() {
return prq;
}
private PluginVersionIdentifier getVersionIdentifier() {
return ver;
}
public String toString() {
if (prq == null)
return "(null)";
String s = parent.toString() + "->" + prq.getPlugin();
String v = prq.getVersion();
s += v == null ? "(any)" : (prq.getMatch() ? "(" + v + ",exact)" : "(" + v + ",compatible)");
return s;
}
}
// constraint index structure
private class ConstraintsEntry {
private IndexEntry parent;
private List constraintList = new LinkedList();
private PluginDescriptorModel lastResolved = null;
private boolean isResolved = false;
private PluginDescriptorModel bestMatch = null;
private boolean bestMatchEnabled = false;
private ConstraintsEntry(IndexEntry parent) {
this.parent = parent;
}
private int constraintCount() {
return constraintList.size();
}
private PluginDescriptorModel addConstraint(Constraint c) {
constraintList.add(c);
c.setConstraintsEntry(this);
List constrained = getMatchingDescriptors();
if (constrained.size() <= 0) {
constraintList.remove(c);
c.setConstraintsEntry(null);
return null;
} else {
PluginDescriptorModel match = (PluginDescriptorModel) constrained.get(0);
if (!match.equals(lastResolved)) {
lastResolved = match;
isResolved = false;
}
return match;
}
}
private void removeConstraint(Constraint c) {
if (DEBUG_RESOLVE)
debug("removing constraint " + c.toString());
constraintList.remove(c);
c.setConstraintsEntry(null);
lastResolved = null;
isResolved = false;
}
private void removeConstraintFor(PluginPrerequisiteModel prereq) {
List remove = new ArrayList();
for (Iterator list = constraintList.iterator(); list.hasNext();) {
Constraint c = (Constraint) list.next();
if (c.getPrerequisite() == prereq)
remove.add(c);
}
for (Iterator list = remove.iterator(); list.hasNext();)
removeConstraint((Constraint) list.next());
}
private PluginDescriptorModel getMatchingDescriptor() {
List constrained = getMatchingDescriptors();
if (constrained.size() <= 0)
return null;
else
return (PluginDescriptorModel) constrained.get(0);
}
private List getMatchingDescriptors() {
List constrained = new LinkedList();
for (Iterator list = parent.versions().iterator(); list.hasNext();) {
PluginDescriptorModel pd = (PluginDescriptorModel) list.next();
if (pd.getEnabled())
constrained.add(pd);
}
for (Iterator list = constraintList.iterator(); list.hasNext();) {
Constraint c = (Constraint) list.next();
if (c.getMatchType() == MATCH_LATEST)
continue;
for (Iterator list2 = parent.versions().iterator(); list2.hasNext();) {
PluginDescriptorModel pd = (PluginDescriptorModel) list2.next();
if (!pd.getEnabled())
continue;
if (c.getMatchType() == MATCH_EXACT) {
if (!getVersionIdentifier(pd).isEquivalentTo(c.getVersionIdentifier()))
constrained.remove(pd);
} else {
if (!getVersionIdentifier(pd).isCompatibleWith(c.getVersionIdentifier()))
constrained.remove(pd);
}
}
}
return constrained;
}
private void preresolve(List roots) {
if (constraintList.size() <= 0) {
if (roots.contains(parent.getId())) {
bestMatch = (PluginDescriptorModel) parent.versions().get(0);
if (bestMatch == null) {
if (DEBUG_RESOLVE)
debug("*ERROR* no resolved descriptor for " + parent.getId());
} else
bestMatchEnabled = bestMatch.getEnabled();
}
} else {
bestMatch = getMatchingDescriptor();
if (bestMatch == null) {
if (DEBUG_RESOLVE)
debug("*ERROR* no resolved descriptor for " + parent.getId());
} else
bestMatchEnabled = true;
}
}
private void resolve() {
if (bestMatch != null) {
bestMatch.setEnabled(bestMatchEnabled);
if (bestMatchEnabled) {
if (DEBUG_RESOLVE)
debug("configured " + bestMatch.toString());
if (constraintList.size() > 0) {
for (int i = 0; i < constraintList.size(); i++) {
PluginPrerequisiteModel prq = (PluginPrerequisiteModel) ((Constraint) constraintList.get(i)).getPrerequisite();
prq.setResolvedVersion(getVersionIdentifier(bestMatch).toString());
}
}
}
}
}
private boolean isResolved() {
return this.isResolved;
}
private void isResolved(boolean isResolved) {
this.isResolved = isResolved;
}
}
// plugin descriptor index structure
private class IndexEntry {
private String id;
private List verList = new LinkedList();
private List concurrentList = new ArrayList();
private IndexEntry(String id) {
this.id = id;
concurrentList.add(new ConstraintsEntry(this));
}
private String getId() {
return id;
}
private ConstraintsEntry getConstraintsEntryFor(Constraint c) {
ConstraintsEntry ce = c.getConstraintsEntry();
if (ce != null)
return ce;
ce = (ConstraintsEntry) concurrentList.get(0);
if (c.getPrerequisite() == null)
c.setConstraintsEntry(ce);
return ce;
}
private PluginDescriptorModel addConstraint(Constraint c) {
int concurrentCount = concurrentList.size();
// try to find constraits entry that can accommodate new constraint
for (Iterator list = concurrentList.iterator(); list.hasNext();) {
ConstraintsEntry cie = (ConstraintsEntry) list.next();
PluginDescriptorModel pd = cie.addConstraint(c);
if (pd != null) {
// constraint added OK and no concurrency
if (concurrentCount <= 1)
return pd;
// constraint added OK but have concurrency
if (allowConcurrencyFor(pd))
return pd;
else {
cie.removeConstraint(c); // cannot be concurrent
return null;
}
}
}
// attempt to create new constraints entry
ConstraintsEntry cie;
PluginDescriptorModel pd;
if (concurrentList.size() == 1) {
// ensure base entry allows concurrency
cie = (ConstraintsEntry) concurrentList.get(0);
pd = cie.getMatchingDescriptor();
if (!allowConcurrencyFor(pd))
return null;
}
cie = new ConstraintsEntry(this);
pd = cie.addConstraint(c);
if (pd == null) {
cie.removeConstraint(c); // no matching target
return null;
}
if (!allowConcurrencyFor(pd)) {
cie.removeConstraint(c); // cannot be concurrent
return null;
}
if (DEBUG_RESOLVE)
debug("creating new constraints list in " + id + " for " + c.toString());
concurrentList.add(cie);
return pd;
}
private boolean allowConcurrencyFor(PluginDescriptorModel pd) {
if (pd == null)
return false;
if (pd.getDeclaredExtensions() != null && pd.getDeclaredExtensions().length > 0)
return false;
if (pd.getDeclaredExtensionPoints() != null && pd.getDeclaredExtensionPoints().length > 0)
return false;
return true;
}
private void removeConstraint(Constraint c) {
ConstraintsEntry cie = getConstraintsEntryFor(c);
cie.removeConstraint(c);
if (concurrentList.get(0) != cie && cie.constraintCount() == 0)
concurrentList.remove(cie);
}
private void removeConstraintFor(PluginPrerequisiteModel prereq) {
for (Iterator list = concurrentList.iterator(); list.hasNext();)
((ConstraintsEntry) list.next()).removeConstraintFor(prereq);
}
private PluginDescriptorModel getMatchingDescriptorFor(Constraint c) {
ConstraintsEntry cie = getConstraintsEntryFor(c);
return cie.getMatchingDescriptor();
}
private void disableAllDescriptors() {
for (Iterator list = verList.iterator(); list.hasNext();) {
PluginDescriptorModel pd = (PluginDescriptorModel) list.next();
pd.setEnabled(false);
}
}
private void resolveDependencies(List roots) {
for (Iterator list = concurrentList.iterator(); list.hasNext();)
((ConstraintsEntry) list.next()).preresolve(roots);
disableAllDescriptors();
for (Iterator list = concurrentList.iterator(); list.hasNext();)
((ConstraintsEntry) list.next()).resolve();
}
private List versions() {
return verList;
}
private boolean isResolvedFor(Constraint c) {
ConstraintsEntry cie = getConstraintsEntryFor(c);
return cie.isResolved();
}
private void isResolvedFor(Constraint c, boolean value) {
ConstraintsEntry cie = getConstraintsEntryFor(c);
cie.isResolved(value);
}
}
// subtree resolution "cookie" (composite change list)
private class Cookie {
private boolean ok = true;
private List changes = new ArrayList();
private Cookie() {
}
private boolean addChange(Constraint c) {
PluginPrerequisiteModel prereq = c.getPrerequisite();
for (Iterator list = changes.iterator(); list.hasNext();)
if (prereq == ((Constraint)list.next()).getPrerequisite())
return false; // prereq loop
changes.add(c);
return true;
}
private List getChanges() {
return changes;
}
private void clearChanges() {
if (changes.size() >= 0)
changes = new ArrayList();
}
private boolean isOk() {
return ok;
}
private void isOk(boolean value) {
ok = value;
}
}
public RegistryResolver() {
String debug = Platform.getDebugOption(OPTION_DEBUG_RESOLVE);
DEBUG_RESOLVE = debug==null ? false : ( debug.equalsIgnoreCase("true") ? true : false );
}
private void add(PluginDescriptorModel pd) {
String key = pd.getId();
List verList;
IndexEntry ix = (IndexEntry) idmap.get(key);
// create new index entry if one does not exist for plugin
if (ix == null) {
ix = new IndexEntry(key);
idmap.put(key, ix);
}
// insert plugin into list maintaining version order
verList = ix.versions();
int i = 0;
for (i = 0; i < verList.size(); i++) {
PluginDescriptorModel element = (PluginDescriptorModel) verList.get(i);
if (getVersionIdentifier(pd).equals(getVersionIdentifier(element)))
return; // ignore duplicates
if (getVersionIdentifier(pd).isGreaterThan(getVersionIdentifier(element)))
break;
}
verList.add(i, pd);
}
private void addAll(Collection c) {
for (Iterator list = c.iterator(); list.hasNext();)
add((PluginDescriptorModel) list.next());
}
private void addExtension(ExtensionModel extension, PluginDescriptorModel plugin) {
ExtensionModel[] list = plugin.getDeclaredExtensions();
ExtensionModel[] result = null;
if (list == null)
result = new ExtensionModel[1];
else {
result = new ExtensionModel[list.length + 1];
System.arraycopy(list, 0, result, 0, list.length);
}
result[result.length - 1] = extension;
plugin.setDeclaredExtensions(result);
extension.setParent(plugin);
}
private void addExtensionPoint(ExtensionPointModel extensionPoint, PluginDescriptorModel plugin) {
ExtensionPointModel[] list = plugin.getDeclaredExtensionPoints();
ExtensionPointModel[] result = null;
if (list == null)
result = new ExtensionPointModel[1];
else {
result = new ExtensionPointModel[list.length + 1];
System.arraycopy(list, 0, result, 0, list.length);
}
result[result.length - 1] = extensionPoint;
plugin.setDeclaredExtensionPoints(result);
extensionPoint.setParent(plugin);
}
private void addLibrary(LibraryModel library, PluginDescriptorModel plugin) {
LibraryModel[] list = plugin.getRuntime();
LibraryModel[] result = null;
if (list == null)
result = new LibraryModel[1];
else {
result = new LibraryModel[list.length + 1];
System.arraycopy(list, 0, result, 0, list.length);
}
result[result.length - 1] = library;
plugin.setRuntime(result);
}
private void debug(String s) {
System.out.println("Registry Resolve: "+s);
}
private void error(String message) {
Status error = new Status(IStatus.WARNING, Platform.PI_RUNTIME, Platform.PARSE_PROBLEM, message, null);
status.add(error);
if (InternalPlatform.DEBUG && DEBUG_RESOLVE)
System.out.println(error.toString());
}
public IExtensionPoint getExtensionPoint(PluginDescriptorModel plugin, String extensionPointId) {
if (extensionPointId == null)
return null;
ExtensionPointModel[] list = plugin.getDeclaredExtensionPoints();
if (list == null)
return null;
for (int i = 0; i < list.length; i++) {
if (extensionPointId.equals(list[i].getId()))
return (IExtensionPoint) list[i];
}
return null;
}
private PluginVersionIdentifier getVersionIdentifier(PluginDescriptorModel descriptor) {
String version = descriptor.getVersion();
if (version == null)
return new PluginVersionIdentifier("1.0.0");
try {
return new PluginVersionIdentifier(version);
} catch (Throwable e) {
return new PluginVersionIdentifier("1.0.0");
}
}
private PluginVersionIdentifier getVersionIdentifier(PluginPrerequisiteModel prereq) {
String version = prereq.getVersion();
return version == null ? null : new PluginVersionIdentifier(version);
}
private void removeConstraintFor(PluginPrerequisiteModel prereq) {
String id = prereq.getPlugin();
IndexEntry ix = (IndexEntry) idmap.get(id);
if (ix == null) {
if (DEBUG_RESOLVE)
debug("unable to locate index entry for " + id);
return;
}
ix.removeConstraintFor(prereq);
}
private void resolve() {
// resolve root descriptors
List rd = resolveRootDescriptors();
if (rd.size() == 0) {
// no roots ... quit
idmap = null;
reg = null;
error("Unable to resolve plugin registry");
return;
}
// sort roots
Object[] a = rd.toArray();
Arrays.sort(a);
ArrayList roots = new ArrayList(Arrays.asList(a));
// walk the dependencies and setup constraints
ArrayList orphans = new ArrayList();
for (int i = 0; i < roots.size(); i++)
resolveNode((String) roots.get(i), null, null, null, orphans);
for (int i = 0; i < orphans.size(); i++) {
if (!roots.contains(orphans.get(i))) {
roots.add(orphans.get(i));
if (DEBUG_RESOLVE)
debug("orphan " + orphans.get(i));
}
}
// resolve dependencies
Iterator plugins = idmap.entrySet().iterator();
while (plugins.hasNext()) {
IndexEntry ix = (IndexEntry) ((Map.Entry) plugins.next()).getValue();
ix.resolveDependencies(roots);
}
// walk down the registry structure and resolve links
resolvePluginRegistry();
// unhook registry and index
idmap = null;
reg = null;
}
public IStatus resolve(PluginRegistryModel registry) {
status = new MultiStatus(Platform.PI_RUNTIME, IStatus.OK, "", null);
if (registry.isResolved())
return status;
reg = registry;
idmap = new HashMap();
addAll(Arrays.asList(reg.getPlugins()));
resolve();
registry.markResolved();
return status;
}
private void resolveExtension(ExtensionModel ext) {
String target = ext.getExtensionPoint();
int ix = target.lastIndexOf(".");
String pluginId = target.substring(0, ix);
String extPtId = target.substring(ix + 1);
String message;
PluginDescriptorModel plugin = (PluginDescriptorModel) reg.getPlugin(pluginId);
if (plugin == null) {
message = Policy.bind("extPointUnknown", new String[] { target, ext.getParentPluginDescriptor().getId()});
error(message);
return;
}
if (!plugin.getEnabled()) {
message = Policy.bind("extPointDisabled", new String[] { target, ext.getParentPluginDescriptor().getId()});
error(message);
return;
}
ExtensionPointModel extPt = (ExtensionPointModel) getExtensionPoint(plugin, extPtId);
if (extPt == null) {
message = Policy.bind("extPointUnknown", new String[] { target, ext.getParentPluginDescriptor().getId()});
error(message);
return;
}
ExtensionModel[] oldValues = extPt.getDeclaredExtensions();
ExtensionModel[] newValues = null;
if (oldValues == null)
newValues = new ExtensionModel[1];
else {
newValues = new ExtensionModel[oldValues.length + 1];
System.arraycopy(oldValues, 0, newValues, 0, oldValues.length);
}
newValues[newValues.length - 1] = ext;
extPt.setDeclaredExtensions(newValues);
}
private void resolveFragments() {
ArrayList retained = new ArrayList(5);
PluginFragmentModel[] fragments = reg.getFragments();
HashSet seen = new HashSet(5);
for (int i = 0; i < fragments.length; i++) {
PluginFragmentModel fragment = fragments[i];
if (seen.contains(fragment.getId()))
continue;
seen.add(fragment.getId());
PluginDescriptorModel plugin = reg.getPlugin(fragment.getPluginId(), fragment.getPluginVersion());
if (plugin == null)
// XXX log something here?
continue;
PluginFragmentModel[] list = reg.getFragments(fragment.getId());
resolvePluginFragments(list, plugin);
}
}
private Cookie resolveNode(String child, PluginDescriptorModel parent, PluginPrerequisiteModel prq, Cookie cookie, List orphans) {
// This method is called recursively to setup dependency constraints.
// Top invocation is passed null parent and null prerequisite.
if (DEBUG_RESOLVE)
debug("PUSH> " + child);
if (cookie == null)
cookie = new Cookie();
// lookup child entry
IndexEntry ix = (IndexEntry) idmap.get(child);
if (ix == null) {
if (parent != null)
error(Policy.bind("pluginPrereqDisabled", new String[] { parent.getId(), child }));
if (DEBUG_RESOLVE)
debug("<POP " + child + " not found");
cookie.isOk(false);
return cookie;
}
// try to add new dependency constraint
Constraint currentConstraint = new Constraint(parent, prq);
PluginDescriptorModel childPd = null;
if (parent != null) {
childPd = ix.addConstraint(currentConstraint);
if (childPd == null) {
error("Unable to satisfy prerequisite constraint from " + parent.getId() + " to " + child);
if (DEBUG_RESOLVE)
debug("<POP " + child + " unable to satisfy constraint");
cookie.isOk(false);
return cookie;
} else
if (!cookie.addChange(currentConstraint)) {
error("Detected prerequisite loop from " + parent.getId() + " to " + child);
if (DEBUG_RESOLVE)
debug("<POP " + child + " prerequisite loop");
cookie.isOk(false);
return cookie;
}
} else {
childPd = ix.getMatchingDescriptorFor(currentConstraint);
if (childPd == null) {
if (DEBUG_RESOLVE)
debug("<POP " + child + " not found (missing descriptor entry)");
cookie.isOk(false);
return cookie;
}
}
// check to see if subtree is already resolved
if (ix.isResolvedFor(currentConstraint)) {
if (DEBUG_RESOLVE)
debug("<POP " + child + " already resolved");
return cookie;
}
// select the subtree to resolve
PluginPrerequisiteModel[] prereqs = childPd.getRequires();
PluginPrerequisiteModel prereq;
prereqs = prereqs == null ? new PluginPrerequisiteModel[0] : prereqs;
for (int i = 0; cookie.isOk() && i < prereqs.length; i++) {
prereq = (PluginPrerequisiteModel) prereqs[i];
cookie = resolveNode(prereq.getPlugin(), childPd, prereq, cookie, orphans);
}
// if we failed, remove any constraints we added
if (!cookie.isOk()) {
Constraint cookieConstraint;
for (Iterator change = cookie.getChanges().iterator(); change.hasNext();) {
cookieConstraint = (Constraint) change.next();
if (childPd == cookieConstraint.getParent()) {
prereq = cookieConstraint.getPrerequisite();
removeConstraintFor(prereq);
if (!orphans.contains(prereq.getPlugin())) // keep track of orphaned subtrees
orphans.add(prereq.getPlugin());
}
}
if (parent != null)
error(Policy.bind("pluginPrereqDisabled", new String[] { parent.getId(), child }));
childPd.setEnabled(false);
if (DEBUG_RESOLVE)
debug("<POP " + child + " failed to resolve subtree");
return cookie;
} else {
// we're done
ix.isResolvedFor(currentConstraint, true);
if (DEBUG_RESOLVE)
debug("<POP " + child + " " + getVersionIdentifier(childPd));
return cookie;
}
}
private void resolvePluginDescriptor(PluginDescriptorModel pd) {
ExtensionModel[] list = pd.getDeclaredExtensions();
if (list == null || list.length == 0)
return;
for (int i = 0; i < list.length; i++)
resolveExtension((ExtensionModel) list[i]);
}
private void resolvePluginFragment(PluginFragmentModel fragment, PluginDescriptorModel plugin) {
ExtensionModel[] extensions = fragment.getDeclaredExtensions();
if (extensions != null)
for (int i = 0; i < extensions.length; i++)
addExtension(extensions[i], plugin);
ExtensionPointModel[] points = fragment.getDeclaredExtensionPoints();
if (points != null)
for (int i = 0; i < points.length; i++)
addExtensionPoint(points[i], plugin);
LibraryModel[] libraries= fragment.getRuntime();
if (libraries!= null)
for (int i = 0; i < libraries.length; i++)
addLibrary(libraries[i], plugin);
}
private void resolvePluginFragments(PluginFragmentModel[] fragments, PluginDescriptorModel plugin) {
PluginFragmentModel latestFragment = null;
PluginVersionIdentifier latestVersion = null;
PluginVersionIdentifier targetVersion = new PluginVersionIdentifier(plugin.getVersion());
for (int i = 0; i < fragments.length; i++) {
PluginFragmentModel fragment = fragments[i];
PluginVersionIdentifier fragmentVersion = new PluginVersionIdentifier(fragment.getVersion());
PluginVersionIdentifier pluginVersion = new PluginVersionIdentifier(fragment.getPluginVersion());
if (pluginVersion.getMajorComponent() == targetVersion.getMajorComponent() && pluginVersion.getMinorComponent() == targetVersion.getMinorComponent())
if (latestFragment == null || fragmentVersion.isGreaterThan(latestVersion)) {
latestFragment = fragment;
latestVersion = fragmentVersion;
}
}
if (latestFragment != null)
resolvePluginFragment(latestFragment, plugin);
}
private void resolvePluginRegistry() {
// filter out disabled plugins from "live" registry
if (trimPlugins)
trimRegistry();
// resolve relationships
if (crossLink) {
// knit the fragments into the plugins. This must be done after any trimming
// so that fragments for disabled plugins are not added.
resolveFragments();
// cross link all of the extensions and extension points.
PluginDescriptorModel[] plugins = reg.getPlugins();
for (int i = 0; i < plugins.length; i++)
resolvePluginDescriptor(plugins[i]);
}
}
private List resolveRootDescriptors() {
// Determine the roots of the dependency tree. Disable all
// but one versions of the root descriptors.
// get list of all plugin identifiers in the registry
List ids = new ArrayList();
ids.addAll(idmap.keySet());
// iterate over the list eliminating targets of <requires> entries
Iterator p = idmap.entrySet().iterator();
while (p.hasNext()) {
IndexEntry ix = (IndexEntry) ((Map.Entry) p.next()).getValue();
if (ix != null) {
List list = ix.versions();
if (list.size() > 0) {
PluginDescriptorModel pd = (PluginDescriptorModel) list.get(0);
PluginPrerequisiteModel[] prereqs = pd.getRequires();
for (int i = 0; prereqs != null && i < prereqs.length; i++) {
ids.remove(prereqs[i].getPlugin());
}
}
}
}
if (ids.size() > 0) {
// disable all but the most recent version of root descriptors
String id;
p = ids.iterator();
while (p.hasNext()) {
id = (String) p.next();
IndexEntry ix = (IndexEntry) idmap.get(id);
if (ix != null) {
List list = ix.versions();
for (int i = 0; i < list.size(); i++) {
PluginDescriptorModel pd = (PluginDescriptorModel) list.get(i);
if (i == 0) {
if (DEBUG_RESOLVE)
debug("root " + pd);
} else {
if (DEBUG_RESOLVE)
debug(" " + pd + " disabled");
pd.setEnabled(false);
}
}
}
}
} else {
if (DEBUG_RESOLVE)
debug("NO ROOTS");
}
return ids;
}
/**
* Specifies whether extensions and extension points should be cross
* linked during the resolve process.
*/
public void setCrossLink(boolean value) {
crossLink = value;
}
/**
* Specified whether disabled plugins should to be removed when the resolve
* is completed.
*/
public void setTrimPlugins(boolean value) {
trimPlugins = value;
}
private void trimRegistry() {
PluginDescriptorModel[] list = reg.getPlugins();
for (int i = 0; i < list.length; i++) {
PluginDescriptorModel pd = (PluginDescriptorModel) list[i];
if (!pd.getEnabled()) {
if (DEBUG_RESOLVE)
debug("removing " + pd.toString());
reg.removePlugin(pd.getId(), pd.getVersion());
}
}
}
}