Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Arthorne2007-09-30 18:11:02 +0000
committerJohn Arthorne2007-09-30 18:11:02 +0000
commit2ccb446cc885495686cc9eb430c4a98031b3cfc5 (patch)
tree207e30d5f61856ece926ed3548297aa3958132c9 /bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse
parentc4f6662ccd02bb75cba95a6ae56a2da38c6cadde (diff)
downloadrt.equinox.p2-2ccb446cc885495686cc9eb430c4a98031b3cfc5.tar.gz
rt.equinox.p2-2ccb446cc885495686cc9eb430c4a98031b3cfc5.tar.xz
rt.equinox.p2-2ccb446cc885495686cc9eb430c4a98031b3cfc5.zip
Renamed prov bundles to p2
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse')
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/ArtifactKey.java84
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/InternalInstallableUnit.java16
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/Messages.java26
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/MetadataActivator.java32
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/messages.properties14
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ConstrainableElement.java14
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IArtifactKey.java54
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnit.java72
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnitConstants.java36
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnitFragment.java19
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IMetadataVisitor.java20
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IResolvedInstallableUnit.java16
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IResolvedInstallableUnitFragment.java13
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Inclusion.java21
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/InstallableUnit.java217
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/InstallableUnitFragment.java67
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ProvidedCapability.java73
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Recommendation.java125
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/RecommendationDescriptor.java116
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/RequiredCapability.java158
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ResolvedInstallableUnit.java148
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ResolvedInstallableUnitFragment.java26
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Selector.java44
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/TouchpointData.java55
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/TouchpointType.java78
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/CompoundIterator.java98
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/IQueryable.java25
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/Query.java73
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/QueryableArray.java47
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/ResolutionHelper.java171
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/StateMetadataMap.java34
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/Transformer.java141
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/UnsatisfiedCapability.java56
33 files changed, 2189 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/ArtifactKey.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/ArtifactKey.java
new file mode 100644
index 000000000..71546915b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/ArtifactKey.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.prov.metadata;
+
+import org.eclipse.equinox.prov.metadata.IArtifactKey;
+import org.osgi.framework.Version;
+
+/**
+ * The concrete type for representing IArtifactKey's.
+ * <p>
+ * See {link IArtifact for a description of the lifecycle of artifact keys)
+ */
+public class ArtifactKey implements IArtifactKey {
+
+ static final int NO_SEGMENTS = 5;
+ private static final char SEP_CHAR = ',';
+
+ private String namespace;
+ private String id;
+ private String classifier;
+ private transient Version versionObject;
+ private String version;
+
+ public ArtifactKey(String namespace, String classifier, String id, Version aVersion) {
+ super();
+ if (namespace.indexOf(SEP_CHAR) != -1)
+ throw new IllegalArgumentException("comma not allowed in namespace"); //$NON-NLS-1$
+ if (classifier.indexOf(SEP_CHAR) != -1)
+ throw new IllegalArgumentException("comma not allowed in classifier"); //$NON-NLS-1$
+ if (id.indexOf(SEP_CHAR) != -1)
+ throw new IllegalArgumentException("comma not allowed in id"); //$NON-NLS-1$
+ this.namespace = namespace;
+ this.classifier = classifier;
+ this.id = id;
+ this.versionObject = aVersion;
+ this.version = aVersion == null ? null : aVersion.toString();
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public String getClassifier() {
+ return classifier;
+ }
+
+ public Version getVersion() {
+ if (versionObject == null)
+ versionObject = version == null ? Version.emptyVersion : new Version(version);
+ return versionObject;
+ }
+
+ public int hashCode() {
+ int hash = id.hashCode();
+ hash = 17 * hash + getVersion().hashCode();
+ hash = 17 * hash + namespace.hashCode();
+ hash = 17 * hash + classifier.hashCode();
+ return hash;
+ }
+
+ public String toString() {
+ return "ArtifactKey=" + id + '/' + namespace + '/' + classifier + '/' + getVersion(); //$NON-NLS-1$
+ }
+
+ public boolean equals(Object obj) {
+ if (!(obj instanceof ArtifactKey))
+ return false;
+ ArtifactKey ak = (ArtifactKey) obj;
+ return ak.id.equals(id) && ak.getVersion().equals(getVersion()) && ak.namespace.equals(namespace) && ak.classifier.equals(classifier);
+ }
+
+ public String getId() {
+ return id;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/InternalInstallableUnit.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/InternalInstallableUnit.java
new file mode 100644
index 000000000..6ab875e14
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/InternalInstallableUnit.java
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.internal.prov.metadata;
+
+import org.eclipse.equinox.prov.metadata.IInstallableUnit;
+import org.eclipse.equinox.prov.metadata.IResolvedInstallableUnit;
+
+public interface InternalInstallableUnit extends IInstallableUnit {
+ public IResolvedInstallableUnit getResolved();
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/Messages.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/Messages.java
new file mode 100644
index 000000000..00c7aef16
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/Messages.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.prov.metadata;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.equinox.internal.prov.metadata.messages"; //$NON-NLS-1$
+
+ static {
+ // load message values from bundle file and assign to fields below
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ public static String QUERY_PROGRESS;
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/MetadataActivator.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/MetadataActivator.java
new file mode 100644
index 000000000..9e717f490
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/MetadataActivator.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.prov.metadata;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class MetadataActivator implements BundleActivator {
+ public static final String PI_METADATA = "org.eclipse.equinox.prov.metadata"; //$NON-NLS-1$
+ public static BundleContext context;
+
+ public static BundleContext getContext() {
+ return context;
+ }
+
+ public void start(BundleContext context) throws Exception {
+ MetadataActivator.context = context;
+ }
+
+ public void stop(BundleContext context) throws Exception {
+ MetadataActivator.context = null;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/messages.properties b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/messages.properties
new file mode 100644
index 000000000..138d56215
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/messages.properties
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (c) 2007 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+
+QUERY_PROGRESS=Executing query.
+
+
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ConstrainableElement.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ConstrainableElement.java
new file mode 100644
index 000000000..a45c91031
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ConstrainableElement.java
@@ -0,0 +1,14 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+public class ConstrainableElement {
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IArtifactKey.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IArtifactKey.java
new file mode 100644
index 000000000..3f45b9f9c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IArtifactKey.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+import org.osgi.framework.Version;
+
+/**
+ * Provide standardized artifact information to uniquely identify the
+ * corresponding bytes (perhaps not stored as a file).
+ * <p>
+ * Artifact keys represent both a unique opaque identifier as well as structured
+ * and standardized pieces of information.
+ */
+
+public interface IArtifactKey {
+
+ /**
+ * The namespace.
+ * @return This returns the namespace segment of the artifact. Never
+ * null or empty.
+ */
+ String getNamespace();
+
+ /**
+ * The classifier.
+ * @return This returns the classifier segment of the key. Never
+ * null. Can be empty.
+ */
+ String getClassifier();
+
+ /**
+ * The identity of the artifact.
+ * @return This returns the id segment of the artifact. Can
+ * be empty.
+ *
+ * TODO: consider renaming this to getIdentity.
+ */
+ String getId();
+
+ /**
+ * The version of the artifact.
+ * @return This returns the version of the artifact. Never null. Can
+ * be empty (Version.emptyVersion).
+ */
+ Version getVersion();
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnit.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnit.java
new file mode 100644
index 000000000..399747f34
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnit.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+import org.osgi.framework.Version;
+
+public interface IInstallableUnit extends Comparable {
+
+ /**
+ * A capability namespace representing a particular kind of installable unit.
+ * For example, an InstallableUnit may specify that it provides the "group" kind
+ * capability to express that it represents a group of instalable units.
+ */
+ public static final String IU_KIND_NAMESPACE = "org.eclipse.equinox.prov.type"; //$NON-NLS-1$
+ /**
+ * A capability namespace representing a particular InstallableUnit by name.
+ * Each InstallableUnit automatically provides an instance of this namespace representing
+ * itself, and other InstallableUnits can require such a capability to state that they
+ * require a particular InstallableUnit to be present.
+ */
+ public static final String IU_NAMESPACE = "org.eclipse.equinox.prov.iunamespace"; //$NON-NLS-1$
+ /**
+ * A capability namespace representing a particular profile flavor.
+ */
+ public static final String FLAVOR_NAMESPACE = "flavor"; //$NON-NLS-1$
+ //These two constants needs to be moved somewhere more appropriate...
+ public static final String CAPABILITY_ECLIPSE_TYPES = "org.eclipse.equinox.prov.eclipsetouchpoint.types"; //$NON-NLS-1$
+ public static final String CAPABILITY_ECLIPSE_BUNDLE = "bundle"; //$NON-NLS-1$
+
+ public abstract TouchpointType getTouchpointType();
+
+ public abstract String getId();
+
+ /**
+ * Returns the filter on this installable unit. The filter is matched against
+ * the selection context of the profile the unit is installed into. An IU will not
+ * be installed if it has a filter condition that is not satisfied by the context.
+ *
+ * See Profile#getSelectionContext.
+ */
+ public abstract String getFilter();
+
+ public abstract Version getVersion();
+
+ public abstract IArtifactKey[] getArtifacts();
+
+ public abstract RequiredCapability[] getRequiredCapabilities();
+
+ // public ProvidedCapability[] getProvidedCapabilities() {
+ // return providedCapabilities;
+ // }
+ //
+ public abstract ProvidedCapability[] getProvidedCapabilities();
+
+ public abstract boolean isSingleton();
+
+ public abstract String getProperty(String key);
+
+ public abstract TouchpointData[] getTouchpointData();
+
+ public abstract boolean isFragment();
+
+ public abstract String getApplicabilityFilter();
+
+ public abstract void accept(IMetadataVisitor visitor);
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnitConstants.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnitConstants.java
new file mode 100644
index 000000000..36c73a0b8
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnitConstants.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.equinox.prov.metadata;
+
+/**
+ * Definitions for constants associated with InstallableUnits.
+ */
+public interface IInstallableUnitConstants {
+
+ /*
+ * Keys for common properties that optionally
+ * be defined in InstallableUnits.
+ */
+ public String NAME = "equinox.prov.name"; //$NON-NLS-1$
+ public String DESCRIPTION = "equinox.prov.description"; //$NON-NLS-1$
+ public String DOC_URL = "equinox.prov.doc.url"; //$NON-NLS-1$
+ public String PROVIDER = "equinox.prov.provider"; //$NON-NLS-1$
+ public String CONTACT = "equinox.prov.contact"; //$NON-NLS-1$
+ public String LICENSE = "equinox.prov.license"; //$NON-NLS-1$
+ public String COPYRIGHT = "equinox.prov.copyright"; //$NON-NLS-1$
+ public String UPDATE_SITE = "equinox.prov.update.site"; //$NON-NLS-1$
+ public String UPDATE_FROM = "equinox.prov.update.from"; //$NON-NLS-1$
+ public String UPDATE_RANGE = "equinox.prov.update.range"; //$NON-NLS-1$
+
+ //TODO This is not the ideal location for these constants
+ public String ENTRYPOINT_IU_KEY = "entryPoint"; //$NON-NLS-1$
+ public static final String PROFILE_IU_KEY = "profileIU"; //$NON-NLS-1$
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnitFragment.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnitFragment.java
new file mode 100644
index 000000000..5f11ed83b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnitFragment.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+public interface IInstallableUnitFragment extends IInstallableUnit {
+
+ public abstract String getHostId();
+
+ public abstract VersionRange getHostVersionRange();
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IMetadataVisitor.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IMetadataVisitor.java
new file mode 100644
index 000000000..737afd742
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IMetadataVisitor.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+public interface IMetadataVisitor {
+ public void visitInstallableUnit(IInstallableUnit iu);
+
+ public void visitCapability(ProvidedCapability capability);
+
+ public void visitRequiredCapability(RequiredCapability capability);
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IResolvedInstallableUnit.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IResolvedInstallableUnit.java
new file mode 100644
index 000000000..e73ad5565
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IResolvedInstallableUnit.java
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+public interface IResolvedInstallableUnit extends IInstallableUnit {
+
+ public abstract IInstallableUnitFragment[] getFragments();
+
+ public abstract IInstallableUnit getOriginal();
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IResolvedInstallableUnitFragment.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IResolvedInstallableUnitFragment.java
new file mode 100644
index 000000000..eb1b34e6a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IResolvedInstallableUnitFragment.java
@@ -0,0 +1,13 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+public interface IResolvedInstallableUnitFragment extends IInstallableUnitFragment, IResolvedInstallableUnit {
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Inclusion.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Inclusion.java
new file mode 100644
index 000000000..7ba050b2d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Inclusion.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+public abstract class Inclusion {
+ String selectorId;
+
+ public String getSelectorId() {
+ return selectorId;
+ }
+
+ public abstract void accept(IMetadataVisitor visitor);
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/InstallableUnit.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/InstallableUnit.java
new file mode 100644
index 000000000..000911032
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/InstallableUnit.java
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+import org.eclipse.equinox.internal.prov.metadata.InternalInstallableUnit;
+import org.eclipse.equinox.prov.core.helpers.OrderedProperties;
+import org.eclipse.equinox.prov.core.helpers.UnmodifiableProperties;
+import org.osgi.framework.Version;
+
+public class InstallableUnit implements IInstallableUnitConstants, IInstallableUnit, InternalInstallableUnit {
+ private static final RequiredCapability[] NO_REQUIRES = new RequiredCapability[0];
+ private static final OrderedProperties NO_PROPERTIES = new OrderedProperties();
+
+ private String id;
+ private transient Version versionObject;
+ private String version;
+ private boolean singleton;
+
+ private OrderedProperties properties;
+
+ private IArtifactKey[] artifacts;
+ private TouchpointType touchpointType;
+ private TouchpointData immutableTouchpointData;
+
+ private RequiredCapability[] requires;
+
+ private String filter;
+
+ String applicabilityFilter;
+
+ ProvidedCapability[] providedCapabilities = new ProvidedCapability[0];
+
+ public InstallableUnit() {
+ super();
+ }
+
+ public TouchpointType getTouchpointType() {
+ return touchpointType == null ? TouchpointType.NONE : touchpointType;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getFilter() {
+ return filter;
+ }
+
+ public Version getVersion() {
+ if (versionObject == null)
+ versionObject = version == null ? Version.emptyVersion : new Version(version);
+ return versionObject;
+ }
+
+ public IArtifactKey[] getArtifacts() {
+ return artifacts;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public void setVersion(Version newVersion) {
+ this.versionObject = newVersion;
+ this.version = newVersion == null ? null : newVersion.toString();
+ }
+
+ public void setTouchpointType(TouchpointType type) {
+ this.touchpointType = type == TouchpointType.NONE ? null : type;
+ }
+
+ public void setArtifacts(IArtifactKey[] value) {
+ artifacts = value;
+ }
+
+ public RequiredCapability[] getRequiredCapabilities() {
+ return requires != null ? requires : NO_REQUIRES;
+
+ }
+
+ public ProvidedCapability[] getProvidedCapabilities() {
+ ProvidedCapability self = new ProvidedCapability(IU_NAMESPACE, id, getVersion());
+ if (providedCapabilities == null)
+ return new ProvidedCapability[] {self};
+
+ ProvidedCapability[] result = new ProvidedCapability[providedCapabilities.length + 1];
+ result[0] = self;
+ System.arraycopy(providedCapabilities, 0, result, 1, providedCapabilities.length);
+ return result;
+ }
+
+ public void setRequiredCapabilities(RequiredCapability[] capabilities) {
+ if (capabilities == NO_REQUIRES) {
+ this.requires = null;
+ } else {
+ //copy array for safety
+ this.requires = (RequiredCapability[]) capabilities.clone();
+ }
+ }
+
+ public void accept(IMetadataVisitor visitor) {
+ visitor.visitInstallableUnit(this);
+ }
+
+ public boolean isSingleton() {
+ return singleton;
+ }
+
+ public void setSingleton(boolean singleton) {
+ this.singleton = singleton;
+ }
+
+ public String getProperty(String key) {
+ return getProperties().getProperty(key);
+ }
+
+ public String setProperty(String key, String value) {
+ if (properties == null)
+ properties = new OrderedProperties();
+ return (String) properties.setProperty(key, value);
+ }
+
+ public String toString() {
+ return id + ' ' + getVersion();
+ }
+
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
+ result = prime * result + ((getVersion() == null) ? 0 : getVersion().hashCode());
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (!(obj instanceof IInstallableUnit))
+ return false;
+ final IInstallableUnit other = (IInstallableUnit) obj;
+ if (id == null) {
+ if (other.getId() != null)
+ return false;
+ } else if (!id.equals(other.getId()))
+ return false;
+ if (getVersion() == null) {
+ if (other.getVersion() != null)
+ return false;
+ } else if (!getVersion().equals(other.getVersion()))
+ return false;
+ return true;
+ }
+
+ public void setFilter(String filter) {
+ this.filter = filter;
+ }
+
+ public TouchpointData[] getTouchpointData() {
+ return immutableTouchpointData == null ? TouchpointData.NO_TOUCHPOINT_DATA : new TouchpointData[] {immutableTouchpointData};
+ }
+
+ public void setImmutableTouchpointData(TouchpointData immutableData) {
+ this.immutableTouchpointData = immutableData;
+ }
+
+ OrderedProperties getProperties() {
+ return properties == null ? NO_PROPERTIES : properties;
+ }
+
+ /**
+ * Get an <i>unmodifiable copy</i> of the properties
+ * associated with the installable unit.
+ *
+ * @return an <i>unmodifiable copy</i> of the IU properties.
+ */
+ public OrderedProperties copyProperties() {
+ return (properties != null ? new UnmodifiableProperties(getProperties()) : new UnmodifiableProperties(new OrderedProperties()));
+ }
+
+ public boolean isFragment() {
+ return false;
+ }
+
+ public void setCapabilities(ProvidedCapability[] exportedCapabilities) {
+ providedCapabilities = exportedCapabilities;
+ }
+
+ public void setApplicabilityFilter(String ldapFilter) {
+ applicabilityFilter = ldapFilter;
+ }
+
+ public String getApplicabilityFilter() {
+ return applicabilityFilter;
+ }
+
+ public IResolvedInstallableUnit getResolved() {
+ return new ResolvedInstallableUnit(this);
+ }
+
+ public int compareTo(Object toCompareTo) {
+ if (!(toCompareTo instanceof IInstallableUnit)) {
+ return -1;
+ }
+ IInstallableUnit other = (IInstallableUnit) toCompareTo;
+ if (getId().compareTo(other.getId()) == 0)
+ return (getVersion().compareTo(other.getVersion()));
+ return getId().compareTo(other.getId());
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/InstallableUnitFragment.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/InstallableUnitFragment.java
new file mode 100644
index 000000000..74180a9c8
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/InstallableUnitFragment.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class InstallableUnitFragment extends InstallableUnit implements IInstallableUnitFragment, IInstallableUnit {
+ public static ProvidedCapability FRAGMENT_CAPABILITY = new ProvidedCapability(IU_KIND_NAMESPACE, "iu.fragment", new Version(1, 0, 0));
+
+ private String hostId;
+ private transient VersionRange hostRangeObject;
+ private String hostRange;
+
+ public ProvidedCapability[] getProvidedCapabilities() {
+ ProvidedCapability[] otherCapabilities = super.getProvidedCapabilities();
+ if (otherCapabilities.length == 0)
+ return new ProvidedCapability[] {FRAGMENT_CAPABILITY};
+ ProvidedCapability[] result = new ProvidedCapability[otherCapabilities.length + 1];
+ System.arraycopy(otherCapabilities, 0, result, 1, otherCapabilities.length);
+ result[0] = FRAGMENT_CAPABILITY;
+ return result;
+ }
+
+ public void setHost(String iuId, VersionRange versionRange) {
+ if (iuId == null || versionRange == null)
+ throw new IllegalArgumentException();
+ hostId = iuId;
+ hostRangeObject = versionRange;
+ hostRange = versionRange == null ? null : versionRange.toString();
+ addRequiredCapability(RequiredCapability.createRequiredCapabilityForName(iuId, versionRange, false));
+ }
+
+ public String getHostId() {
+ return hostId;
+ }
+
+ public VersionRange getHostVersionRange() {
+ if (hostRangeObject == null)
+ hostRangeObject = hostRange == null ? VersionRange.emptyRange : new VersionRange(hostRange);
+ return hostRangeObject;
+ }
+
+ private void addRequiredCapability(RequiredCapability toAdd) {
+ RequiredCapability[] current = super.getRequiredCapabilities();
+ RequiredCapability[] result = new RequiredCapability[current.length + 1];
+ System.arraycopy(current, 0, result, 0, current.length);
+ result[current.length] = toAdd;
+ setRequiredCapabilities(result);
+ }
+
+ public boolean isFragment() {
+ return true;
+ }
+
+ public IResolvedInstallableUnit getResolved() {
+ return new ResolvedInstallableUnitFragment(this);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ProvidedCapability.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ProvidedCapability.java
new file mode 100644
index 000000000..ffe074ded
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ProvidedCapability.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+import org.osgi.framework.Version;
+
+/**
+ * Describes a capability as exposed or required by an installable unit
+ */
+public class ProvidedCapability {
+ String namespace;
+ String name;
+ transient Version versionObject;
+ String version;
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Version getVersion() {
+ if (versionObject == null)
+ versionObject = version == null ? Version.emptyVersion : new Version(version);
+ return versionObject;
+ }
+
+ public ProvidedCapability(String namespace, String name, Version newVersion) {
+ this.name = name;
+ this.versionObject = newVersion;
+ this.version = newVersion == null ? null : newVersion.toString();
+ this.namespace = namespace;
+ }
+
+ public boolean isSatisfiedBy(RequiredCapability candidate) {
+ if (getName() == null || !getName().equals(candidate.getName()))
+ return false;
+ if (getNamespace() == null || !getNamespace().equals(candidate.getNamespace()))
+ return false;
+ return candidate.getRange().isIncluded(getVersion());
+ }
+
+ public void accept(IMetadataVisitor visitor) {
+ visitor.visitCapability(this);
+ }
+
+ public boolean equals(Object other) {
+ if (other instanceof ProvidedCapability) {
+ ProvidedCapability otherCapability = (ProvidedCapability) other;
+ return otherCapability.namespace.equals(namespace) && otherCapability.name.equals(name) && otherCapability.getVersion().equals(getVersion());
+ }
+ return false;
+ }
+
+ public int hashCode() {
+ return namespace.hashCode() * name.hashCode() * getVersion().hashCode();
+ }
+
+ public String toString() {
+ return namespace + '/' + name + '/' + getVersion();
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Recommendation.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Recommendation.java
new file mode 100644
index 000000000..e3ff45ca4
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Recommendation.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class Recommendation {
+ private RequiredCapability applyOn;
+ private RequiredCapability newValue;
+
+ public Recommendation(RequiredCapability applyOn2, RequiredCapability newValue2) {
+ this.applyOn = applyOn2;
+ this.newValue = newValue2;
+ }
+
+ public RequiredCapability applyOn() {
+ return applyOn;
+ }
+
+ public RequiredCapability newValue() {
+ return newValue;
+ }
+
+ public boolean matches(RequiredCapability toMatch) {
+ if (!toMatch.getNamespace().equals(applyOn.getNamespace()))
+ return false;
+ if (!toMatch.getName().equals(applyOn.getName()))
+ return false;
+ if (toMatch.getRange().equals(applyOn.getRange()))
+ return true;
+
+ //TODO Here, in the long run we want to be smarter .for example we could check that the range of the match is a subset of the range specified on applyOn.
+ return false;
+ }
+
+ boolean matches(Recommendation toMatch) {
+ return matches(toMatch.applyOn());
+ }
+
+ protected Recommendation merge(Recommendation r2) {
+ VersionRange result = intersect(newValue().getRange(), r2.newValue().getRange());
+ if (result == null)
+ return null;
+ return new Recommendation(applyOn, new RequiredCapability(applyOn.getNamespace(), applyOn.getName(), result));
+ }
+
+ private VersionRange intersect(VersionRange r1, VersionRange r2) {
+ Version resultMin = null;
+ boolean resultMinIncluded = false;
+ Version resultMax = null;
+ boolean resultMaxIncluded = false;
+
+ int minCompare = r1.getMinimum().compareTo(r2.getMinimum());
+ if (minCompare < 0) {
+ resultMin = r2.getMinimum();
+ resultMinIncluded = r2.getIncludeMinimum();
+ } else if (minCompare > 0) {
+ resultMin = r1.getMinimum();
+ resultMinIncluded = r1.getIncludeMinimum();
+ } else if (minCompare == 0) {
+ resultMin = r1.getMinimum();
+ resultMinIncluded = r1.getIncludeMinimum() && r2.getIncludeMinimum();
+ }
+
+ int maxCompare = r1.getMaximum().compareTo(r2.getMaximum());
+ if (maxCompare > 0) {
+ resultMax = r2.getMaximum();
+ resultMaxIncluded = r2.getIncludeMaximum();
+ } else if (maxCompare < 0) {
+ resultMax = r1.getMaximum();
+ resultMaxIncluded = r1.getIncludeMaximum();
+ } else if (maxCompare == 0) {
+ resultMax = r1.getMaximum();
+ resultMaxIncluded = r1.getIncludeMaximum() && r2.getIncludeMaximum();
+ }
+
+ int resultRangeComparison = resultMin.compareTo(resultMax);
+ if (resultRangeComparison < 0)
+ return new VersionRange(resultMin, resultMinIncluded, resultMax, resultMaxIncluded);
+ else if (resultRangeComparison == 0 && resultMinIncluded == resultMaxIncluded)
+ return new VersionRange(resultMin, resultMinIncluded, resultMax, resultMaxIncluded);
+ else
+ return null;
+ }
+
+ public boolean isCompatible(Recommendation other) {
+ return intersect(newValue.getRange(), other.newValue.getRange()) != null;
+ }
+
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((applyOn == null) ? 0 : applyOn.hashCode());
+ result = prime * result + ((newValue == null) ? 0 : newValue.hashCode());
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final Recommendation other = (Recommendation) obj;
+ if (applyOn == null) {
+ if (other.applyOn != null)
+ return false;
+ } else if (!applyOn.equals(other.applyOn))
+ return false;
+ if (newValue == null) {
+ if (other.newValue != null)
+ return false;
+ } else if (!newValue.equals(other.newValue))
+ return false;
+ return true;
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/RecommendationDescriptor.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/RecommendationDescriptor.java
new file mode 100644
index 000000000..4a6722074
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/RecommendationDescriptor.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+import java.util.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.internal.prov.metadata.MetadataActivator;
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+public class RecommendationDescriptor {
+ public static final String TOUCHPOINT_DATA_KEY = "recommendations";
+ public static final String KIND = "recommendation";
+
+ private Set recommendations;
+
+ public RecommendationDescriptor(Set recommendations) {
+ this.recommendations = recommendations;
+ }
+
+ public Set getRecommendations() {
+ return recommendations;
+ }
+
+ public Recommendation findRecommendation(RequiredCapability toMatch) {
+ for (Iterator iterator = recommendations.iterator(); iterator.hasNext();) {
+ Recommendation name = (Recommendation) iterator.next();
+ if (name.matches(toMatch))
+ return name;
+ }
+ return null;
+ }
+
+ public Recommendation findRecommendation(Recommendation toMatch) {
+ for (Iterator iterator = recommendations.iterator(); iterator.hasNext();) {
+ Recommendation name = (Recommendation) iterator.next();
+ if (name.matches(toMatch))
+ return name;
+ }
+ return null;
+ }
+
+ //Merge the other descriptor into this one. Return an OK Status is the merged succeeded, otherwise return an INFO Status
+ public IStatus merge(RecommendationDescriptor other) {
+ MultiStatus result = null;
+ for (Iterator it = other.recommendations.iterator(); it.hasNext();) {
+ Recommendation otherRecommendation = (Recommendation) it.next();
+ Recommendation matchInThis = findRecommendation(otherRecommendation);
+ if (matchInThis == null) {
+ recommendations.add(otherRecommendation);
+ continue;
+ }
+ Recommendation newRec = otherRecommendation.merge(matchInThis);
+ if (newRec != null) {
+ recommendations.remove(matchInThis);
+ recommendations.add(newRec);
+ continue;
+ } else {
+ if (result == null)
+ result = new MultiStatus(MetadataActivator.PI_METADATA, 0, "Conflict between recommendations", null);
+ result.add(new Status(IStatus.INFO, MetadataActivator.PI_METADATA, "can't merge " + otherRecommendation + " with " + matchInThis));
+ }
+ }
+ if (result == null)
+ return Status.OK_STATUS;
+ return result;
+
+ }
+
+ public static RecommendationDescriptor parse(String descriptor) {
+ StringTokenizer entries = new StringTokenizer(descriptor, "\n");
+ Set recommendations = new HashSet(entries.countTokens());
+ while (entries.hasMoreElements()) {
+ StringTokenizer oneRec = new StringTokenizer((String) entries.nextElement(), "/");
+ if (oneRec.countTokens() != 4) {
+ //format error, ignore and continue
+
+ continue;
+ }
+ String ns = oneRec.nextToken().trim();
+ String name = oneRec.nextToken().trim();
+ String oldRange = oneRec.nextToken().trim();
+ String newRange = oneRec.nextToken().trim();
+ recommendations.add(new Recommendation(new RequiredCapability(ns, name, new VersionRange(oldRange)), new RequiredCapability(ns, name, new VersionRange(newRange))));
+ }
+ return new RecommendationDescriptor(recommendations);
+ }
+
+ public static String serialize(RecommendationDescriptor toSerialize) {
+ StringBuffer result = new StringBuffer();
+ for (Iterator iterator = toSerialize.recommendations.iterator(); iterator.hasNext();) {
+ Recommendation entry = (Recommendation) iterator.next();
+ result.append(entry.applyOn().getNamespace() + '/' + entry.applyOn().getName() + '/' + entry.applyOn().getRange().toString() + '/' + entry.newValue().getRange().toString() + '\n');
+ }
+ return result.toString();
+ }
+
+ public boolean isCompatible(RecommendationDescriptor other) {
+ for (Iterator it = other.recommendations.iterator(); it.hasNext();) {
+ Recommendation otherRecommendation = (Recommendation) it.next();
+ Recommendation matchInThis = findRecommendation(otherRecommendation);
+ if (matchInThis == null) {
+ continue;
+ }
+ if (!otherRecommendation.isCompatible(matchInThis))
+ return false;
+ }
+ return true;
+
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/RequiredCapability.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/RequiredCapability.java
new file mode 100644
index 000000000..3ad8a8ee8
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/RequiredCapability.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+/**
+ * A required capability represents some external constraint on an {@link InstallableUnit}.
+ * Each capability represents something an {@link InstallableUnit} needs that
+ * it expects to be provided by another {@link InstallableUnit}. Capabilities are
+ * entirely generic, and are intended to be capable of representing anything that
+ * an {@link InstallableUnit} may need either at install time, or at runtime.
+ * <p>
+ * Capabilities are segmented into namespaces. Anyone can introduce new
+ * capability namespaces. Some well-known namespaces are introduced directly
+ * by the provisioning framework.
+ *
+ * @see InstallableUnit#IU_KIND_NAMESPACE
+ * @see InstallableUnit#IU_NAMESPACE
+ */
+public class RequiredCapability {
+ private String filter;
+
+ private boolean multiple;
+ private String name;
+ private String namespace;
+ boolean optional;
+ private String range;
+ private String[] selectors;
+ private transient VersionRange rangeObject;
+
+ /**
+ * Returns a {@link RequiredCapability} on the installable unit with the given name
+ * and version range.
+ */
+ public static RequiredCapability createRequiredCapabilityForName(String name, VersionRange versionRange, boolean optional) {
+ return new RequiredCapability(IInstallableUnit.IU_NAMESPACE, name, versionRange, null, optional, false);
+ }
+
+ public RequiredCapability(String namespace, String name, VersionRange range) {
+ this(namespace, name, range, null, false, false);
+ }
+
+ public RequiredCapability(String namespace, String name, VersionRange range, String filter, boolean optional, boolean multiple) {
+ this(namespace, name, range, null, filter, optional, multiple);
+ }
+
+ public RequiredCapability(String namespace, String name, VersionRange range, String[] selectors, String filter, boolean optional, boolean multiple) {
+ Assert.isNotNull(namespace);
+ Assert.isNotNull(name);
+ this.namespace = namespace;
+ this.name = name;
+ this.rangeObject = range;
+ this.range = rangeObject == null ? null : rangeObject.toString();
+ this.selectors = selectors == null ? new String[0] : selectors;
+ this.optional = optional;
+ this.filter = filter;
+ this.multiple = multiple;
+ }
+
+ public void accept(IMetadataVisitor visitor) {
+ visitor.visitRequiredCapability(this);
+ }
+
+ public String getFilter() {
+ return filter;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public VersionRange getRange() {
+ if (rangeObject == null)
+ rangeObject = range == null ? VersionRange.emptyRange : new VersionRange(range);
+ return rangeObject;
+ }
+
+ public boolean isMultiple() {
+ return multiple;
+ }
+
+ public boolean isOptional() {
+ return optional;
+ }
+
+ public String toString() {
+ return "requiredCapability: " + namespace + '/' + name + '/' + range;
+ }
+
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((filter == null) ? 0 : filter.hashCode());
+ result = prime * result + (multiple ? 1231 : 1237);
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + ((namespace == null) ? 0 : namespace.hashCode());
+ result = prime * result + (optional ? 1231 : 1237);
+ result = prime * result + ((rangeObject == null) ? 0 : rangeObject.hashCode());
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final RequiredCapability other = (RequiredCapability) obj;
+ if (filter == null) {
+ if (other.filter != null)
+ return false;
+ } else if (!filter.equals(other.filter))
+ return false;
+ if (multiple != other.multiple)
+ return false;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (namespace == null) {
+ if (other.namespace != null)
+ return false;
+ } else if (!namespace.equals(other.namespace))
+ return false;
+ if (optional != other.optional)
+ return false;
+ if (rangeObject == null) {
+ if (other.rangeObject != null)
+ return false;
+ } else if (!rangeObject.equals(other.rangeObject))
+ return false;
+ return true;
+ }
+
+ /**
+ * Returns the properties to use for evaluating required capability filters
+ * downstream from this capability. For example, if the selector "doc"
+ * is provided, then a downstream InstallableUnit with a required capability
+ * filtered with "doc=true" will be included.
+ */
+ public String[] getSelectors() {
+ return selectors;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ResolvedInstallableUnit.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ResolvedInstallableUnit.java
new file mode 100644
index 000000000..f6f5bc034
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ResolvedInstallableUnit.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import org.eclipse.equinox.internal.prov.metadata.InternalInstallableUnit;
+import org.osgi.framework.Version;
+
+public class ResolvedInstallableUnit implements IResolvedInstallableUnit, InternalInstallableUnit {
+ private static IInstallableUnit[] NO_IU = new IInstallableUnit[0];
+
+ private IInstallableUnit[] fragments = NO_IU;
+ protected InstallableUnit resolved;
+
+ public ResolvedInstallableUnit(InstallableUnit resolved) {
+ this.resolved = resolved;
+ }
+
+ public void setFragments(IResolvedInstallableUnit[] fragments) {
+ this.fragments = fragments;
+ }
+
+ public IInstallableUnitFragment[] getFragments() {
+ ArrayList result = new ArrayList();
+ if (fragments != null)
+ result.addAll(Arrays.asList(fragments));
+ for (int i = 0; i < result.size(); i++) {
+ result.addAll(Arrays.asList(((IResolvedInstallableUnit) result.get(i)).getFragments()));
+ }
+ return (IInstallableUnitFragment[]) result.toArray(new IInstallableUnitFragment[result.size()]);
+ }
+
+ public String getApplicabilityFilter() {
+ return resolved.getApplicabilityFilter();
+ }
+
+ public IArtifactKey[] getArtifacts() {
+ return resolved.getArtifacts();
+ }
+
+ public String getFilter() {
+ return resolved.getFilter();
+ }
+
+ public String getId() {
+ return resolved.getId();
+ }
+
+ public String getProperty(String key) {
+ return resolved.getProperty(key);
+ }
+
+ public ProvidedCapability[] getProvidedCapabilities() {
+ ArrayList result = new ArrayList();
+ result.addAll(Arrays.asList(resolved.getProvidedCapabilities()));
+ for (int i = 0; i < fragments.length; i++) {
+ result.addAll(Arrays.asList(fragments[i].getProvidedCapabilities()));
+ }
+ return resolved.getProvidedCapabilities();
+ }
+
+ public RequiredCapability[] getRequiredCapabilities() {
+ ArrayList result = new ArrayList();
+ result.addAll(Arrays.asList(resolved.getRequiredCapabilities()));
+ for (int i = 0; i < fragments.length; i++) {
+ result.addAll(Arrays.asList(fragments[i].getRequiredCapabilities()));
+ }
+ return (RequiredCapability[]) result.toArray(new RequiredCapability[result.size()]);
+
+ }
+
+ public TouchpointData[] getTouchpointData() {
+ ArrayList result = new ArrayList();
+ result.addAll(Arrays.asList(resolved.getTouchpointData()));
+ for (int i = 0; i < fragments.length; i++) {
+ TouchpointData[] data = fragments[i].getTouchpointData();
+ for (int j = 0; j < data.length; j++) {
+ result.add(data[j]);
+ }
+ }
+ return (TouchpointData[]) result.toArray(new TouchpointData[result.size()]);
+ }
+
+ public TouchpointType getTouchpointType() {
+ return resolved.getTouchpointType();
+ }
+
+ public Version getVersion() {
+ return resolved.getVersion();
+ }
+
+ public boolean isFragment() {
+ return resolved.isFragment();
+ }
+
+ public boolean isSingleton() {
+ return resolved.isSingleton();
+ }
+
+ public void accept(IMetadataVisitor visitor) {
+ visitor.visitInstallableUnit(this);
+ }
+
+ public boolean equals(Object obj) {
+ //TODO This is pretty ugly....
+ boolean result = resolved.equals(obj);
+ if (result)
+ return true;
+ if (obj instanceof ResolvedInstallableUnit)
+ return resolved.equals(((ResolvedInstallableUnit) obj).resolved);
+ return false;
+ }
+
+ public int hashCode() {
+ // TODO Auto-generated method stub
+ return resolved.hashCode();
+ }
+
+ public String toString() {
+ return "[R]" + resolved.toString();
+ }
+
+ public IInstallableUnit getOriginal() {
+ return resolved;
+ }
+
+ public int compareTo(Object toCompareTo) {
+ if (!(toCompareTo instanceof IInstallableUnit)) {
+ return -1;
+ }
+ IInstallableUnit other = (IInstallableUnit) toCompareTo;
+ if (getId().compareTo(other.getId()) == 0)
+ return (getVersion().compareTo(other.getVersion()));
+ return getId().compareTo(other.getId());
+ }
+
+ public IResolvedInstallableUnit getResolved() {
+ return this;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ResolvedInstallableUnitFragment.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ResolvedInstallableUnitFragment.java
new file mode 100644
index 000000000..f7532d2a9
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ResolvedInstallableUnitFragment.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+public class ResolvedInstallableUnitFragment extends ResolvedInstallableUnit implements IResolvedInstallableUnitFragment {
+
+ public ResolvedInstallableUnitFragment(InstallableUnitFragment resolved) {
+ super(resolved);
+ }
+
+ public String getHostId() {
+ return ((InstallableUnitFragment) resolved).getHostId();
+ }
+
+ public VersionRange getHostVersionRange() {
+ return ((InstallableUnitFragment) resolved).getHostVersionRange();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Selector.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Selector.java
new file mode 100644
index 000000000..a63f39bc3
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Selector.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+import java.util.Dictionary;
+import org.eclipse.equinox.internal.prov.metadata.MetadataActivator;
+import org.osgi.framework.InvalidSyntaxException;
+
+public class Selector {
+ private String id;
+ private String filter;
+ private boolean internal;
+
+ public Selector(String id, String filter, boolean internal) {
+ this.id = id;
+ this.filter = filter;
+ this.internal = internal;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public boolean eval(Dictionary context) {
+ try {
+ return MetadataActivator.context.createFilter(filter).match(context);
+ } catch (InvalidSyntaxException e) {
+ //TODO log something. though that should not happen
+ return false;
+ }
+ }
+
+ public boolean isInternal() {
+ return internal;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/TouchpointData.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/TouchpointData.java
new file mode 100644
index 000000000..67b56c6de
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/TouchpointData.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+import java.util.Map;
+
+public class TouchpointData {
+ public static TouchpointData[] NO_TOUCHPOINT_DATA = new TouchpointData[0];
+
+ /**
+ * Map of (String->String). The values represent the instructions. The set
+ * of keys supported is up to the touchpoint that will process these
+ * instructions
+ */
+ private Map instructions;
+
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((instructions == null) ? 0 : instructions.hashCode());
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final TouchpointData other = (TouchpointData) obj;
+ if (instructions == null) {
+ if (other.instructions != null)
+ return false;
+ } else if (!instructions.equals(other.instructions))
+ return false;
+ return true;
+ }
+
+ public TouchpointData(Map instructions) {
+ this.instructions = instructions;
+ }
+
+ public String getInstructions(String instructionKey) {
+ return (String) instructions.get(instructionKey);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/TouchpointType.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/TouchpointType.java
new file mode 100644
index 000000000..1a99d8a2a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/TouchpointType.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+import org.osgi.framework.Version;
+
+/**
+ * Identifies a particular touchpoint. A touchpoint is identified by an id
+ * and a version.
+ */
+public class TouchpointType {
+ /**
+ * A touchpoint type indicating that the "null" touchpoint should be used.
+ * The null touchpoint does not participate in any install phase.
+ */
+ public static final TouchpointType NONE = new TouchpointType("null", new Version("0")); //$NON-NLS-1$//$NON-NLS-2$
+ private String id;
+ private Version versionObject;
+ private String version;
+
+ public TouchpointType(String id, Version aVersion) {
+ this.id = id;
+ this.versionObject = aVersion;
+ this.version = aVersion == null ? null : aVersion.toString();
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public Version getVersion() {
+ if (versionObject == null)
+ versionObject = version == null ? Version.emptyVersion : new Version(version);
+ return versionObject;
+ }
+
+ public String toString() {
+ return "Touchpoint: " + id + ' ' + getVersion();
+ }
+
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
+ result = prime * result + ((getVersion() == null) ? 0 : getVersion().hashCode());
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (super.equals(obj))
+ return true;
+ if (getClass() != obj.getClass())
+ return false;
+ final TouchpointType other = (TouchpointType) obj;
+ if (id == null) {
+ if (other.id != null)
+ return false;
+ } else if (!id.equals(other.id))
+ return false;
+ if (getVersion() == null) {
+ if (other.getVersion() != null)
+ return false;
+ } else if (!getVersion().equals(other.getVersion()))
+ return false;
+ return true;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/CompoundIterator.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/CompoundIterator.java
new file mode 100644
index 000000000..73dfaa3dd
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/CompoundIterator.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.prov.query;
+
+import java.util.*;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.equinox.internal.prov.metadata.Messages;
+import org.eclipse.equinox.prov.metadata.IInstallableUnit;
+import org.eclipse.equinox.prov.metadata.RequiredCapability;
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+public class CompoundIterator implements Iterator {
+ private Iterator[] iterators;
+ private String id;
+ private VersionRange range;
+ private RequiredCapability[] requirements;
+ private boolean and;
+ private int index = 0;
+ private boolean filtered = false;
+ private IInstallableUnit lookahead = null;
+
+ public static IInstallableUnit[] asArray(Iterator i, IProgressMonitor progress) {
+ if (progress == null)
+ progress = new NullProgressMonitor();
+ progress.beginTask(Messages.QUERY_PROGRESS, IProgressMonitor.UNKNOWN);
+ HashSet result = new HashSet();
+ while (i.hasNext()) {
+ result.add(i.next());
+ progress.worked(IProgressMonitor.UNKNOWN);
+ }
+ progress.done();
+ return (IInstallableUnit[]) result.toArray(new IInstallableUnit[result.size()]);
+ }
+
+ public CompoundIterator(Iterator[] iterators) {
+ this.iterators = iterators;
+ }
+
+ public CompoundIterator(Iterator[] iterators, String id, VersionRange range, RequiredCapability[] requirements, boolean and) {
+ this(iterators);
+ this.id = id;
+ this.range = range;
+ this.requirements = requirements;
+ this.and = and;
+ filtered = true;
+ }
+
+ public boolean hasNext() {
+ if (lookahead != null)
+ return true;
+ if (index >= iterators.length)
+ return false;
+ if (filtered) {
+ while (iterators[index].hasNext()) {
+ IInstallableUnit next = (IInstallableUnit) iterators[index].next();
+ if (Query.match(next, id, range, requirements, and)) {
+ lookahead = next;
+ return true;
+ }
+ }
+ } else {
+ if (iterators[index].hasNext())
+ return true;
+ }
+ index++;
+ return hasNext();
+ }
+
+ public Object next() {
+ if (lookahead != null) {
+ IInstallableUnit result = lookahead;
+ lookahead = null;
+ return result;
+ }
+ if (index >= iterators.length)
+ throw new NoSuchElementException();
+ while (iterators[index].hasNext()) {
+ IInstallableUnit next = (IInstallableUnit) iterators[index].next();
+ if (!filtered)
+ return next;
+ if (Query.match(next, id, range, requirements, and))
+ return next;
+ }
+ index++;
+ return next();
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/IQueryable.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/IQueryable.java
new file mode 100644
index 000000000..7811a750a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/IQueryable.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.query;
+
+import java.util.Iterator;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.equinox.prov.metadata.IInstallableUnit;
+import org.eclipse.equinox.prov.metadata.RequiredCapability;
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+public interface IQueryable {
+
+ IInstallableUnit[] query(String id, VersionRange range, RequiredCapability[] requirements, boolean and, IProgressMonitor progress);
+
+ Iterator getIterator(String id, VersionRange range, RequiredCapability[] requirements, boolean and);
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/Query.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/Query.java
new file mode 100644
index 000000000..ac91489ed
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/Query.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.prov.query;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.equinox.internal.prov.metadata.Messages;
+import org.eclipse.equinox.prov.metadata.*;
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+public class Query {
+
+ public static boolean match(IInstallableUnit source, String id, VersionRange range, RequiredCapability[] requirements, boolean and) {
+ if (id != null && !source.getId().equals(id))
+ return false;
+ if (range != null && !range.isIncluded(source.getVersion()))
+ return false;
+ if (requirements == null)
+ return true;
+ // if any of the requirements are met by any of the capabilities of the source...
+ for (int k = 0; k < requirements.length; k++) {
+ boolean valid = false;
+ ProvidedCapability[] capabilities = source.getProvidedCapabilities();
+ for (int j = 0; j < capabilities.length; j++)
+ //TODO Need to deal with option and multiplicity flag
+ if ((requirements[k].getName().equals(capabilities[j].getName()) && requirements[k].getNamespace().equals(capabilities[j].getNamespace()) && (requirements[k].getRange() == null ? true : requirements[k].getRange().isIncluded(capabilities[j].getVersion())))) {
+ valid = true;
+ }
+ // if we are OR'ing then the first time we find a requirement that is met, return success
+ if (valid && !and)
+ return true;
+ // if we are AND'ing then the first time we find a requirement that is NOT met, return failure
+ if (!valid && and)
+ return false;
+ }
+ // if we get past the requirements check and we are AND'ing then return true
+ // since all requirements must have been met. If we are OR'ing then return false
+ // since none of the requirements were met.
+ return and;
+ }
+
+ public static IInstallableUnit[] query(IQueryable[] sources, String id, VersionRange range, RequiredCapability[] requirements, boolean and, IProgressMonitor progress) {
+ if (progress == null)
+ progress = new NullProgressMonitor();
+
+ progress.beginTask(Messages.QUERY_PROGRESS, sources.length);
+ ArrayList result = new ArrayList();
+ for (int i = 0; i < sources.length; i++) {
+ IQueryable source = sources[i];
+ IInstallableUnit[] list = source.query(id, range, requirements, and, progress);
+ for (int j = 0; j < list.length; j++)
+ result.add(list[j]);
+ progress.worked(1);
+ }
+ progress.done();
+ return (IInstallableUnit[]) result.toArray(new IInstallableUnit[result.size()]);
+ }
+
+ public static Iterator getIterator(IQueryable[] sources, String id, VersionRange range, RequiredCapability[] requirements, boolean and) {
+ Iterator[] result = new Iterator[sources.length];
+ for (int i = 0; i < sources.length; i++)
+ result[i] = sources[i].getIterator(id, range, requirements, and);
+ return new CompoundIterator(result);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/QueryableArray.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/QueryableArray.java
new file mode 100644
index 000000000..01177285e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/QueryableArray.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.query;
+
+import java.util.*;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.equinox.internal.prov.metadata.Messages;
+import org.eclipse.equinox.prov.metadata.IInstallableUnit;
+import org.eclipse.equinox.prov.metadata.RequiredCapability;
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+public class QueryableArray implements IQueryable {
+ private IInstallableUnit[] source;
+
+ public QueryableArray(IInstallableUnit[] source) {
+ this.source = source;
+ }
+
+ public Iterator getIterator(String id, VersionRange range, RequiredCapability[] requirements, boolean and) {
+ Iterator i = Arrays.asList(source).iterator();
+ return new CompoundIterator(new Iterator[] {i}, id, range, requirements, and);
+ }
+
+ public IInstallableUnit[] query(String id, VersionRange range, RequiredCapability[] requirements, boolean and, IProgressMonitor progress) {
+ if (progress == null)
+ progress = new NullProgressMonitor();
+ progress.beginTask(Messages.QUERY_PROGRESS, source.length);
+ Set result = new HashSet();
+ for (int i = 0; i < source.length; i++) {
+ if (Query.match(source[i], id, range, requirements, and))
+ result.add(source[i]);
+ progress.worked(1);
+ }
+ progress.done();
+ return (IInstallableUnit[]) result.toArray(new IInstallableUnit[result.size()]);
+
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/ResolutionHelper.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/ResolutionHelper.java
new file mode 100644
index 000000000..5eceae0d1
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/ResolutionHelper.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.resolution;
+
+import java.util.*;
+import org.eclipse.equinox.internal.prov.metadata.InternalInstallableUnit;
+import org.eclipse.equinox.internal.prov.metadata.MetadataActivator;
+import org.eclipse.equinox.prov.metadata.*;
+import org.eclipse.osgi.service.resolver.*;
+import org.osgi.framework.ServiceReference;
+
+public class ResolutionHelper {
+ private static boolean DEBUG = false;
+
+ private Transformer transformer;
+ private State state;
+ private Dictionary selectionContext;
+ private RecommendationDescriptor recommendations;
+
+ public ResolutionHelper(Dictionary selectionContext, RecommendationDescriptor recommendations) {
+ this.selectionContext = selectionContext;
+ this.recommendations = recommendations;
+ }
+
+ private void initialize() {
+ ServiceReference sr = MetadataActivator.context.getServiceReference(PlatformAdmin.class.getName());
+ PlatformAdmin pa = (PlatformAdmin) MetadataActivator.context.getService(sr);
+ transformer = new Transformer(pa.getFactory(), selectionContext, recommendations);
+ state = pa.getFactory().createState(true);
+ if (selectionContext != null)
+ state.setPlatformProperties(selectionContext);
+ }
+
+ private void addToState(BundleDescription bd) {
+ state.addBundle(bd);
+ }
+
+ private BundleDescription addInResolution(IInstallableUnit toAdd) {
+ toAdd.accept(transformer);
+ // transformer.visitInstallableUnit(toAdd);
+ BundleDescription descriptionToAdd = transformer.getResult();
+ // bundleDescriptionToIU.put(descriptionToAdd, toAdd);
+ addToState(descriptionToAdd);
+ return descriptionToAdd;
+ }
+
+ /**
+ * Indicates if the installable unit to install will have all their constraints satisfied when installed with other installable units.
+ * @param toInstall the installable units to install
+ * @param existingState the other installable units to resolve against
+ * @return true if the installable unit to install resolves, return false otherwise.
+ */
+ public UnsatisfiedCapability[] install(Set toInstall, Set existingState) {
+ initialize();
+ BundleDescription[] addedBundle = new BundleDescription[toInstall.size()];
+ int j = 0;
+ for (Iterator iterator = toInstall.iterator(); iterator.hasNext();) {
+ addedBundle[j++] = addInResolution((IInstallableUnit) iterator.next());
+ }
+
+ for (Iterator iterator = existingState.iterator(); iterator.hasNext();) {
+ addInResolution((IInstallableUnit) iterator.next());
+ }
+
+ state.resolve(); //We may want to resolve in two times. first the existing state, then add the toInstall. This would allow to see what changes when dropping the new iu.
+ //Also it could allow us to do an incremental resolution. however the results may differ
+
+ ArrayList results = new ArrayList();
+ for (int i = 0; i < addedBundle.length; i++) {
+ results.addAll(createUnsatisfiedCapabilities(state.getStateHelper().getUnsatisfiedConstraints(addedBundle[i]), addedBundle[i]));
+ }
+ return (UnsatisfiedCapability[]) results.toArray(new UnsatisfiedCapability[results.size()]);
+
+ }
+
+ private ArrayList createUnsatisfiedCapabilities(VersionConstraint[] unsatisfied, BundleDescription description) {
+ ArrayList results = new ArrayList();
+ for (int i = 0; i < unsatisfied.length; i++) {
+ RequiredCapability originalDependency = (RequiredCapability) ((StateMetadataMap) description.getUserObject()).getGenericSpecifications().get(unsatisfied[i]);
+ results.add(new UnsatisfiedCapability(originalDependency, ((StateMetadataMap) description.getUserObject()).getUnit()));
+ }
+ return results;
+ }
+
+ /**
+ * Associates installable unit fragments to each IU being installed.
+ *
+ * TODO: This method should probably be renamed to attachFragments
+ */
+ public Collection attachCUs(Collection toAttach) {
+ initialize();
+ Collection result = new HashSet(toAttach.size());
+ for (Iterator iterator = toAttach.iterator(); iterator.hasNext();) {
+ IResolvedInstallableUnit tmp = ((InternalInstallableUnit) iterator.next()).getResolved();
+ result.add(tmp);
+ addInResolution(tmp);
+ }
+ state.resolve();
+ BundleDescription[] bds = state.getBundles();
+ for (int i = 0; i < bds.length; i++) {
+ if (DEBUG) {
+ ResolverError[] re = state.getResolverErrors(bds[i]);
+ for (int j = 0; j < re.length; j++) {
+ System.out.println(re[j]);
+ }
+ }
+ BundleDescription[] potentialIUFragments = state.getStateHelper().getDependentBundles(new BundleDescription[] {bds[i]});
+ // TODO: We need to define a way to allow IUFragments to work together to do configuration work.
+ // For now we will select just one fragment by preferring a fragment that matches the host
+
+ IInstallableUnit hostIU = ((StateMetadataMap) bds[i].getUserObject()).getUnit();
+ IResolvedInstallableUnitFragment selectedFragment = null;
+ for (int k = 0; k < potentialIUFragments.length; k++) {
+ IInstallableUnit dependentIU = ((StateMetadataMap) potentialIUFragments[k].getUserObject()).getUnit();
+ if (hostIU.equals(dependentIU))
+ continue;
+
+ if (dependentIU.isFragment()) {
+ IResolvedInstallableUnitFragment potentialFragment = (IResolvedInstallableUnitFragment) dependentIU;
+
+ if (potentialFragment.getHostId() == null) {
+ // default fragment - we'll mark it selected but keep looking for a fragment that matches the host
+ selectedFragment = potentialFragment;
+ } else if (potentialFragment.getHostId().equals(hostIU.getId()) && potentialFragment.getHostVersionRange().isIncluded(hostIU.getVersion())) {
+ // matches host - we're done
+ selectedFragment = potentialFragment;
+ break;
+ } // otherwise keep looking
+ }
+ }
+ if (selectedFragment != null)
+ ((ResolvedInstallableUnit) hostIU).setFragments(new IResolvedInstallableUnit[] {selectedFragment});
+ }
+ return result;
+ }
+
+ public boolean isResolved(IInstallableUnit iu) {
+ return state.getBundle(iu.getId(), iu.getVersion()).isResolved();
+ }
+
+ public ArrayList getAllResolved() {
+ BundleDescription[] bd = state.getResolvedBundles();
+ ArrayList result = new ArrayList(bd.length);
+ for (int i = 0; i < bd.length; i++) {
+ result.add(extractIU(bd[i]));
+ }
+ return result;
+ }
+
+ private IInstallableUnit extractIU(BundleDescription bd) {
+ return ((StateMetadataMap) bd.getUserObject()).getUnit();
+ }
+
+ public List getSorted() {
+ BundleDescription[] toSort = state.getResolvedBundles();
+ state.getStateHelper().sortBundles(toSort);
+ List result = new ArrayList(toSort.length);
+ for (int i = 0; i < toSort.length; i++) {
+ result.add(extractIU(toSort[i]));
+ }
+ return result;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/StateMetadataMap.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/StateMetadataMap.java
new file mode 100644
index 000000000..1fc262c5e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/StateMetadataMap.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.resolution;
+
+import java.util.Map;
+import org.eclipse.equinox.prov.metadata.IInstallableUnit;
+
+//Instances of this class are stored in the user object slot of bundlescriptions to ease navigation between the two models.
+public class StateMetadataMap {
+ private IInstallableUnit unit;
+ private Map correspondingSpecifications; //indexes in this array maps to the ones in the dependencies array. This is gross. TODO
+
+ public StateMetadataMap(IInstallableUnit unit, Map correspondingSpecifications) {
+ super();
+ this.unit = unit;
+ this.correspondingSpecifications = correspondingSpecifications;
+ }
+
+ public IInstallableUnit getUnit() {
+ return unit;
+ }
+
+ public Map getGenericSpecifications() {
+ return correspondingSpecifications;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/Transformer.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/Transformer.java
new file mode 100644
index 000000000..d9afe1cfa
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/Transformer.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.prov.resolution;
+
+import java.util.*;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.equinox.internal.prov.metadata.MetadataActivator;
+import org.eclipse.equinox.prov.core.helpers.LogHelper;
+import org.eclipse.equinox.prov.metadata.*;
+import org.eclipse.osgi.service.resolver.*;
+import org.osgi.framework.InvalidSyntaxException;
+
+public class Transformer implements IMetadataVisitor {
+ private static final byte IU_KIND = 0;
+ private static final String IU_NAMESPACE = "iu.namespace";
+ static long iuInternalId = 0;
+
+ private Dictionary context = null;
+ private StateObjectFactory factory = null;
+ private ArrayList iuCapabilities;
+ private Map iuDependencies;
+ private byte kind = IU_KIND;
+
+ private BundleDescription result = null;
+
+ private RecommendationDescriptor recommendations = null;
+
+ public Transformer(StateObjectFactory factory) {
+ this(factory, null, null);
+ }
+
+ public Transformer(StateObjectFactory factory, Dictionary context, RecommendationDescriptor recommendations) {
+ this.factory = factory;
+ this.context = context;
+ this.recommendations = recommendations;
+ }
+
+ private String getNamespace() {
+ switch (kind) {
+ case IU_KIND :
+ return IU_NAMESPACE;
+ default :
+ throw new IllegalStateException("unknown kind"); //This should not happen
+ }
+ }
+
+ public BundleDescription getResult() {
+ return result;
+ }
+
+ private boolean isEnabled(RequiredCapability capability) {
+ // If there is no context then be optimistic
+ if (context == null)
+ return true;
+ String filter = capability.getFilter();
+ if (filter == null)
+ return true;
+ try {
+ return MetadataActivator.getContext().createFilter(filter).match(context);
+ } catch (InvalidSyntaxException e) {
+ // If we fail to parse the filter treat it as invalid and be optimistic
+ return true;
+ }
+ }
+
+ private String toFilter(VersionRange range) {
+ if (range == null)
+ return null;
+ StringBuffer buf = new StringBuffer();
+ buf.append("(&"); //$NON-NLS-1$
+ buf.append("(version>=").append(range.getMinimum().toString()).append(')'); //$NON-NLS-1$
+ if (!range.getIncludeMinimum())
+ buf.append("(!(version=").append(range.getMinimum().toString()).append("))");
+ buf.append("(version<=").append(range.getMaximum().toString()).append(')'); //$NON-NLS-1$
+ if (!range.getIncludeMaximum())
+ buf.append("(!(version=").append(range.getMaximum().toString()).append("))");
+ buf.append(')');
+ return buf.toString();
+ }
+
+ public void visitCapability(ProvidedCapability capability) {
+ iuCapabilities.add(factory.createGenericDescription(capability.getName(), capability.getNamespace(), capability.getVersion(), null));
+ }
+
+ public void visitInstallableUnit(IInstallableUnit toTransform) {
+ kind = IU_KIND;
+
+ //Start with the dependencies
+ RequiredCapability[] requires = toTransform.getRequiredCapabilities();
+ iuDependencies = new HashMap(requires.length);
+ for (int i = 0; i < requires.length; i++) {
+ requires[i].accept(this);
+ }
+
+ //Do the capabilities
+ ProvidedCapability[] capabilities = toTransform.getProvidedCapabilities();
+ iuCapabilities = new ArrayList(requires.length + 1);
+ for (int i = 0; i < capabilities.length; i++) {
+ capabilities[i].accept(this);
+ }
+
+ //Add a capability representing the IU itself
+ iuCapabilities.add(factory.createGenericDescription(toTransform.getId(), getNamespace(), toTransform.getVersion(), null));
+
+ GenericSpecification[] genericSpecifications = new GenericSpecification[iuDependencies.size()];
+ iuDependencies.keySet().toArray(genericSpecifications);
+
+ GenericDescription[] genericDescriptions = new GenericDescription[iuCapabilities.size()];
+ iuCapabilities.toArray(genericDescriptions);
+
+ //Finally create the bundle description
+ //TODO Need to create the filter for the IU itself
+ result = factory.createBundleDescription(iuInternalId++, toTransform.getId(), toTransform.getVersion(), (String) null, (BundleSpecification[]) null, (HostSpecification) null, (ImportPackageSpecification[]) null, (ExportPackageDescription[]) null, toTransform.isSingleton(), true, true, toTransform.getFilter(), (String[]) null, genericSpecifications, genericDescriptions);
+ result.setUserObject(new StateMetadataMap(toTransform, iuDependencies));
+ }
+
+ public void visitRequiredCapability(RequiredCapability capability) {
+ try {
+ if (isEnabled(capability)) {
+ capability = rewrite(capability);
+ iuDependencies.put(factory.createGenericSpecification(capability.getName(), capability.getNamespace(), toFilter(capability.getRange()), capability.isOptional(), capability.isMultiple()), capability);
+ }
+ } catch (InvalidSyntaxException e) {
+ LogHelper.log(new Status(IStatus.ERROR, MetadataActivator.PI_METADATA, "Invalid filter: " + e.getFilter(), e)); //$NON-NLS-1$
+ }
+ }
+
+ private RequiredCapability rewrite(RequiredCapability match) {
+ if (recommendations == null)
+ return match;
+ Recommendation foundRecommendation = recommendations.findRecommendation(match);
+ return foundRecommendation != null ? foundRecommendation.newValue() : match;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/UnsatisfiedCapability.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/UnsatisfiedCapability.java
new file mode 100644
index 000000000..29d6c244d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/UnsatisfiedCapability.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.prov.resolution;
+
+import org.eclipse.equinox.prov.metadata.IInstallableUnit;
+import org.eclipse.equinox.prov.metadata.RequiredCapability;
+
+/**
+ * Represents a provisioning dependency that was not satisfied during
+ * resolution.
+ */
+public class UnsatisfiedCapability {
+ private IInstallableUnit owner;
+ private RequiredCapability require;
+
+ /**
+ * Creates a new unresolved dependency
+ * @param required The dependency that was not satisfied.
+ * @param owner The installable unit whose dependency was not satisfied.
+ */
+ public UnsatisfiedCapability(RequiredCapability required, IInstallableUnit owner) {
+ this.require = required;
+ this.owner = owner;
+ }
+
+ public IInstallableUnit getOwner() {
+ return owner;
+ }
+
+ /**
+ * Returns the specific dependency that was not satisfied.
+ */
+ public RequiredCapability getRequiredCapability() {
+ return require;
+ }
+
+ /**
+ * Returns the installable unit whose dependency was not satisfied.
+ */
+ public IInstallableUnit getUnsatisfiedUnit() {
+ return owner;
+ }
+
+ /**
+ * For debugging purposes only.
+ */
+ public String toString() {
+ return "[" + owner + "] " + require.toString(); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+}

Back to the top