blob: 29f899e51145c18cfbe54446cc11f0b99581a821 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.osgi.internal.resolver;
import java.util.*;
import org.eclipse.core.dependencies.*;
import org.eclipse.core.internal.dependencies.DependencySystem;
import org.eclipse.osgi.service.resolver.*;
import org.osgi.framework.Constants;
public class ResolverHelper {
private final static Version NULL_VERSION = new Version(0, 0, 0);
static class BundleVersionComparator implements Comparator {
public int compare(Object arg0, Object arg1) {
Version v1 = (Version) arg0;
Version v2 = (Version) arg1;
return v1.isGreaterThan(v2) ? 1 : v1.matchQualifier(v2) ? 0 : -1;
}
}
private static final IMatchRule MAJOR = new MatchMajorRule();
private static final IMatchRule MINOR = new MatchMinorRule();
private static final IMatchRule MICRO = new MatchMicroRule();
private static final IMatchRule GREATER_OR_EQUAL = new MatchGreaterOrEqualRule();
private static final IMatchRule QUALIFIER = new MatchQualifierRule();
public static IMatchRule getMatchRule(int b) {
switch (b) {
case VersionConstraint.MINOR_MATCH :
return MINOR;
case VersionConstraint.MICRO_MATCH :
return MICRO;
case VersionConstraint.GREATER_EQUAL_MATCH :
return GREATER_OR_EQUAL;
case VersionConstraint.QUALIFIER_MATCH :
return QUALIFIER;
case VersionConstraint.MAJOR_MATCH :
return MAJOR;
case VersionConstraint.NO_MATCH :
return MAJOR;
}
throw new IllegalArgumentException("match byte: " + b); //$NON-NLS-1$
}
private final static class UnsatisfiableRule implements IMatchRule {
public boolean isSatisfied(Object required, Object available) {
return false;
}
public String toString() {
return "unsatisfiable"; //$NON-NLS-1$
}
}
private final static class MatchQualifierRule implements IMatchRule {
public boolean isSatisfied(Object required, Object available) {
return ((Version) available).matchQualifier((Version) required);
}
public String toString() {
return Constants.VERSION_MATCH_QUALIFIER;
}
}
private final static class MatchMajorRule implements IMatchRule {
public boolean isSatisfied(Object required, Object available) {
return ((Version) available).matchMajor((Version) required);
}
public String toString() {
return Constants.VERSION_MATCH_MAJOR;
}
}
private final static class MatchGreaterOrEqualRule implements IMatchRule {
public boolean isSatisfied(Object required, Object available) {
return ((Version) available).matchGreaterOrEqualTo((Version) required);
}
public String toString() {
return Constants.VERSION_MATCH_GREATERTHANOREQUAL;
}
}
private final static class MatchMinorRule implements IMatchRule {
public boolean isSatisfied(Object required, Object available) {
return ((Version) available).matchMinor((Version) required);
}
public String toString() {
return Constants.VERSION_MATCH_MINOR;
}
}
private final static class MatchMicroRule implements IMatchRule {
public boolean isSatisfied(Object required, Object available) {
return ((Version) available).matchMicro((Version) required);
}
public String toString() {
return Constants.VERSION_MATCH_MICRO;
}
}
public static IElement createElement(BundleDescription bundleDescription, IDependencySystem system) {
String uniqueId = getUniqueId(bundleDescription);
Version version = getVersion(bundleDescription);
return system.createElement(uniqueId, version, createPrerequisites(bundleDescription, system), bundleDescription.isSingleton(), bundleDescription);
}
private static Version getVersion(BundleDescription bundleDescription) {
Version version = bundleDescription.getVersion();
if (version == null)
version = Version.emptyVersion;
return version;
}
private static String getUniqueId(BundleDescription bundleDescription) {
String uniqueId = bundleDescription.getUniqueId();
if (uniqueId == null)
// could not be null
uniqueId = Long.toString(bundleDescription.getBundleId());
return uniqueId;
}
private static IDependency[] createPrerequisites(BundleDescription bundleDesc, IDependencySystem system) {
BundleSpecification[] required = bundleDesc.getRequiredBundles();
HostSpecification host = bundleDesc.getHost();
int dependencyCount = required == null ? 0 : required.length;
if (host != null)
dependencyCount++;
if (dependencyCount == 0)
return new IDependency[0];
List prereqs = new ArrayList(dependencyCount);
for (int i = 0; i < required.length; i++)
// ignore if a bundle requires itself (bug 48568 comment 2)
if (!required[i].getName().equals(bundleDesc.getUniqueId()))
prereqs.add(createPrerequisite(system, required[i]));
if (host != null)
prereqs.add(createPrerequisite(system, host));
return (IDependency[]) prereqs.toArray(new IDependency[prereqs.size()]);
}
private static IDependency createPrerequisite(IDependencySystem system, VersionConstraint constraint) {
boolean optional = (constraint instanceof BundleSpecification) && ((BundleSpecification) constraint).isOptional();
Version requiredVersion = constraint.getVersionSpecification();
if (NULL_VERSION.equals(requiredVersion))
requiredVersion = null;
return system.createDependency(constraint.getName(), getMatchRule(constraint.getMatchingRule()), requiredVersion, optional, constraint);
}
public static IDependencySystem createDependencySystem(ISelectionPolicy policy) {
return new DependencySystem(new ResolverHelper.BundleVersionComparator(), policy);
}
public static IDependencySystem buildDependencySystem(State state, ISelectionPolicy selectionPolicy) {
IDependencySystem dependencySystem = createDependencySystem(selectionPolicy);
BundleDescription[] bundles = state.getBundles();
for (int i = 0; i < bundles.length; i++)
dependencySystem.addElement(ResolverHelper.createElement(bundles[i], dependencySystem));
return dependencySystem;
}
public static void remove(BundleDescription description, IDependencySystem system) {
system.removeElement(getUniqueId(description), getVersion(description));
}
public static void add(BundleDescription description, IDependencySystem system) {
system.addElement(createElement(description, system));
}
public static void unresolve(BundleDescription bundle, IDependencySystem system) {
IElement element = system.getElement(getUniqueId(bundle), getVersion(bundle));
if (element != null)
system.unresolve(new IElement[]{element});
}
public static void update(BundleDescription newDescription, BundleDescription existing, IDependencySystem system) {
system.removeElement(getUniqueId(existing), getVersion(existing));
system.addElement(createElement(newDescription, system));
}
}