Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2011-08-29 21:25:51 +0000
committerThomas Watson2011-09-08 18:57:21 +0000
commita4439d90f4dd7d1033f3dca6e92c3b7064b6f47f (patch)
tree43630c2205abc59ca64dab2de6d419c09d15d8a9
parent9a365c23db3abf8409d7c09a8973e514ab11437d (diff)
downloadrt.equinox.framework-a4439d90f4dd7d1033f3dca6e92c3b7064b6f47f.tar.gz
rt.equinox.framework-a4439d90f4dd7d1033f3dca6e92c3b7064b6f47f.tar.xz
rt.equinox.framework-a4439d90f4dd7d1033f3dca6e92c3b7064b6f47f.zip
Bug 357137 - Changes to equinox resolver to support RFC 112 resolverv20110908-1857
-rw-r--r--bundles/org.eclipse.osgi/META-INF/MANIFEST.MF3
-rw-r--r--bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BaseDescription.java23
-rw-r--r--bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BundleDescription.java20
-rw-r--r--bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/StateObjectFactory.java80
-rw-r--r--bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/VersionConstraint.java22
-rw-r--r--bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/extras/DescriptionReference.java28
-rw-r--r--bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/extras/Sortable.java27
-rw-r--r--bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/extras/SpecificationReference.java28
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/ArrayMap.java16
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java152
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BaseDescriptionImpl.java17
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java9
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateBuilder.java32
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java2
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateObjectFactoryImpl.java130
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/VersionConstraintImpl.java21
16 files changed, 490 insertions, 120 deletions
diff --git a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
index 5cc0727b8..142a91e4b 100644
--- a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
@@ -10,7 +10,8 @@ Export-Package: org.eclipse.osgi.event;version="1.0",
org.eclipse.osgi.service.environment;version="1.3",
org.eclipse.osgi.service.localization;version="1.1",
org.eclipse.osgi.service.pluginconversion;version="1.0",
- org.eclipse.osgi.service.resolver;version="1.5",
+ org.eclipse.osgi.service.resolver;version="1.6",
+ org.eclipse.osgi.service.resolver.extras;version="1.0"; x-friends:="org.eclipse.equinox.resolver",
org.eclipse.osgi.service.runnable;version="1.1",
org.eclipse.osgi.service.security; version="1.0",
org.eclipse.osgi.service.urlconversion;version="1.0",
diff --git a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BaseDescription.java b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BaseDescription.java
index c9b02b724..3c70068a9 100644
--- a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BaseDescription.java
+++ b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BaseDescription.java
@@ -71,4 +71,27 @@ public interface BaseDescription {
* @since 3.7
*/
public BundleCapability getCapability();
+
+ /**
+ * Returns the user object associated to this description, or
+ * <code>null</code> if none exists.
+ *
+ * @return the user object associated to this description,
+ * or <code>null</code>
+ * @since 3.8
+ */
+ public Object getUserObject();
+
+ /**
+ * Associates a user-provided object to this description, or
+ * removes an existing association, if <code>null</code> is provided. The
+ * provided object is not interpreted in any ways by this
+ * description.
+ *
+ * @param userObject an arbitrary object provided by the user, or
+ * <code>null</code>
+ * @since 3.8
+ */
+ public void setUserObject(Object userObject);
+
}
diff --git a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BundleDescription.java b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BundleDescription.java
index 38f02beb7..b7acfcc21 100644
--- a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BundleDescription.java
+++ b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BundleDescription.java
@@ -223,26 +223,6 @@ public interface BundleDescription extends BaseDescription, BundleRevision {
public BundleDescription[] getDependents();
/**
- * Returns the user object associated to this bundle description, or
- * <code>null</code> if none exists.
- *
- * @return the user object associated to this bundle description,
- * or <code>null</code>
- */
- public Object getUserObject();
-
- /**
- * Associates a user-provided object to this bundle description, or
- * removes an existing association, if <code>null</code> is provided. The
- * provided object is not interpreted in any ways by this bundle
- * description.
- *
- * @param userObject an arbitrary object provided by the user, or
- * <code>null</code>
- */
- public void setUserObject(Object userObject);
-
- /**
* Returns the platform filter in the form of an LDAP filter
* @return the platfomr filter in the form of an LDAP filter
*/
diff --git a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/StateObjectFactory.java b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/StateObjectFactory.java
index 3367b0da6..c0f6701bc 100644
--- a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/StateObjectFactory.java
+++ b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/StateObjectFactory.java
@@ -11,8 +11,7 @@
package org.eclipse.osgi.service.resolver;
import java.io.*;
-import java.util.Dictionary;
-import java.util.Map;
+import java.util.*;
import org.eclipse.osgi.internal.resolver.StateObjectFactoryImpl;
import org.osgi.framework.*;
@@ -162,6 +161,27 @@ public interface StateObjectFactory {
public BundleDescription createBundleDescription(long id, String symbolicName, Version version, String location, BundleSpecification[] required, HostSpecification host, ImportPackageSpecification[] imports, ExportPackageDescription[] exports, boolean singleton, boolean attachFragments, boolean dynamicFragments, String platformFilter, String[] executionEnvironments, GenericSpecification[] genericRequires, GenericDescription[] genericCapabilities, NativeCodeSpecification nativeCode);
/**
+ * Creates a bundle description from the given parameters.
+ *
+ * @param id id for the bundle
+ * @param symbolicName the symbolic name of the bundle. This may include directives and/or attributes encoded using the Bundle-SymbolicName header.
+ * @param version version for the bundle (may be <code>null</code>)
+ * @param location location for the bundle (may be <code>null</code>)
+ * @param required version constraints for all required bundles (may be <code>null</code>)
+ * @param host version constraint specifying the host for the bundle to be created. Should be <code>null</code> if the bundle is not a fragment
+ * @param imports version constraints for all packages imported (may be <code>null</code>)
+ * @param exports package descriptions of all the exported packages (may be <code>null</code>)
+ * @param platformFilter the platform filter (may be <code>null</code>)
+ * @param executionEnvironments the execution environment (may be <code>null</code>)
+ * @param genericRequires the version constraints for all required capabilities (may be <code>null</code>)
+ * @param genericCapabilities the specifications of all the capabilities of the bundle (may be <code>null</code>)
+ * @param nativeCode the native code specification of the bundle (may be <code>null</code>)
+ * @return the created bundle description
+ * @since 3.8
+ */
+ public BundleDescription createBundleDescription(long id, String symbolicName, Version version, String location, BundleSpecification[] required, HostSpecification host, ImportPackageSpecification[] imports, ExportPackageDescription[] exports, String platformFilter, String[] executionEnvironments, GenericSpecification[] genericRequires, GenericDescription[] genericCapabilities, NativeCodeSpecification nativeCode);
+
+ /**
* Returns a bundle description based on the information in the supplied manifest dictionary.
* The manifest should contain String keys and String values which correspond to
* proper OSGi manifest headers and values.
@@ -219,6 +239,15 @@ public interface StateObjectFactory {
public BundleSpecification createBundleSpecification(BundleSpecification original);
/**
+ * Creates bundle specifications from the given declaration. The declaration uses
+ * the bundle manifest syntax for the Require-Bundle header.
+ * @param declaration a string declaring bundle specifications
+ * @return the bundle specifications
+ * @since 3.8
+ */
+ public List<BundleSpecification> createBundleSpecifications(String declaration);
+
+ /**
* Creates a host specification from the given parameters.
*
* @param hostSymbolicName the symbolic name for the host bundle
@@ -229,6 +258,15 @@ public interface StateObjectFactory {
public HostSpecification createHostSpecification(String hostSymbolicName, VersionRange hostVersionRange);
/**
+ * Creates host specifications from the given declaration. The declaration uses
+ * the bundle manifest syntax for the Fragment-Host header.
+ * @param declaration a string declaring host specifications
+ * @return the host specifications
+ * @since 3.8
+ */
+ public List<HostSpecification> createHostSpecifications(String declaration);
+
+ /**
* Creates a host specification that is a copy of the given constraint.
*
* @param original the constraint to be copied
@@ -258,6 +296,15 @@ public interface StateObjectFactory {
public ImportPackageSpecification createImportPackageSpecification(ImportPackageSpecification original);
/**
+ * Creates an import package specifications from the given declaration. The declaration uses
+ * the bundle manifest syntax for the Import-Package header.
+ * @param declaration a string declaring import package specifications
+ * @return the import package specifications
+ * @since 3.8
+ */
+ public List<ImportPackageSpecification> createImportPackageSpecifications(String declaration);
+
+ /**
* Used by the Resolver to dynamically create ExportPackageDescription objects during the resolution process.
* The Resolver needs to create ExportPackageDescriptions dynamically for a host when a fragment.
* exports a package<p>
@@ -295,6 +342,15 @@ public interface StateObjectFactory {
public GenericDescription createGenericDescription(String type, Map<String, ?> attributes, Map<String, String> directives, BundleDescription supplier);
/**
+ * Creates generic descriptions from the given declaration. The declaration uses
+ * the bundle manifest syntax for the Provide-Capability header.
+ * @param declaration a string declaring generic descriptions
+ * @return the generic descriptions
+ * @since 3.8
+ */
+ public List<GenericDescription> createGenericDescriptions(String declaration);
+
+ /**
* Creates a generic specification from the given parameters
* @param name the name of the generic specification
* @param type the type of the generic specification (may be <code>null</code>)
@@ -307,6 +363,15 @@ public interface StateObjectFactory {
public GenericSpecification createGenericSpecification(String name, String type, String matchingFilter, boolean optional, boolean multiple) throws InvalidSyntaxException;
/**
+ * Creates generic specifications from the given declaration. The declaration uses
+ * the bundle manifest syntax for the Require-Capability header.
+ * @param declaration a string declaring generic specifications
+ * @return the generic specifications
+ * @since 3.8
+ */
+ public List<GenericSpecification> createGenericSpecifications(String declaration);
+
+ /**
* Creates a native code specification from the given parameters
* @param nativeCodeDescriptions the native code descriptors
* @param optional whether the specification is optional
@@ -330,13 +395,22 @@ public interface StateObjectFactory {
public NativeCodeDescription createNativeCodeDescription(String[] nativePaths, String[] processors, String[] osNames, VersionRange[] osVersions, String[] languages, String filter) throws InvalidSyntaxException;
/**
- * Creates an import package specification that is a copy of the given constraint
+ * Creates an export package specification that is a copy of the given constraint
* @param original the export package to be copied
* @return the created package
*/
public ExportPackageDescription createExportPackageDescription(ExportPackageDescription original);
/**
+ * Creates export package descriptions from the given declaration. The declaration uses
+ * the bundle manifest syntax for the Export-Package header.
+ * @param declaration a string declaring export package descriptions
+ * @return the export package descriptions
+ * @since 3.8
+ */
+ public List<ExportPackageDescription> createExportPackageDescriptions(String declaration);
+
+ /**
* Persists the given state in the given output stream. Closes the stream.
*
* @param state the state to be written
diff --git a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/VersionConstraint.java b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/VersionConstraint.java
index 3b3be74e2..2f15515f8 100644
--- a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/VersionConstraint.java
+++ b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/VersionConstraint.java
@@ -82,4 +82,26 @@ public interface VersionConstraint extends Cloneable {
* @since 3.7
*/
public BundleRequirement getRequirement();
+
+ /**
+ * Returns the user object associated to this constraint, or
+ * <code>null</code> if none exists.
+ *
+ * @return the user object associated to this constraint,
+ * or <code>null</code>
+ * @since 3.8
+ */
+ public Object getUserObject();
+
+ /**
+ * Associates a user-provided object to this constraint, or
+ * removes an existing association, if <code>null</code> is provided. The
+ * provided object is not interpreted in any ways by this
+ * constrain.
+ *
+ * @param userObject an arbitrary object provided by the user, or
+ * <code>null</code>
+ * @since 3.8
+ */
+ public void setUserObject(Object userObject);
}
diff --git a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/extras/DescriptionReference.java b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/extras/DescriptionReference.java
new file mode 100644
index 000000000..d7d32cbf4
--- /dev/null
+++ b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/extras/DescriptionReference.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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.osgi.service.resolver.extras;
+
+import org.eclipse.osgi.service.resolver.BaseDescription;
+
+/**
+ * A reference to a {@link BaseDescription}.
+ * @since 3.8
+ */
+public interface DescriptionReference {
+ /**
+ * Returns the {@code BaseDescription} object associated with this
+ * reference.
+ *
+ * @return The {@code BaseDescription} object associated with this
+ * reference.
+ */
+ public BaseDescription getDescription();
+}
diff --git a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/extras/Sortable.java b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/extras/Sortable.java
new file mode 100644
index 000000000..2442c5e2f
--- /dev/null
+++ b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/extras/Sortable.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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.osgi.service.resolver.extras;
+
+import java.util.Comparator;
+
+/**
+ * Represents a collection of elements which can be sorted.
+ * @since 3.8
+ */
+public interface Sortable<E> {
+ /**
+ * Sorts collection of elements represented by this sortable according
+ * to the specified comparator.
+ * @param comparator the comparator used to sort the collection
+ * of elements represented by this sortable.
+ */
+ void sort(Comparator<E> comparator);
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/extras/SpecificationReference.java b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/extras/SpecificationReference.java
new file mode 100644
index 000000000..c63e2c181
--- /dev/null
+++ b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/extras/SpecificationReference.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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.osgi.service.resolver.extras;
+
+import org.eclipse.osgi.service.resolver.VersionConstraint;
+
+/**
+ * A reference to a {@link VersionConstraint} specification.
+ * @since 3.8
+ */
+public interface SpecificationReference {
+ /**
+ * Returns the {@code VersionConstraint} object associated with this
+ * reference.
+ *
+ * @return The {@code VersionConstraint} object associated with this
+ * reference.
+ */
+ public VersionConstraint getSpecification();
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/ArrayMap.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/ArrayMap.java
index 14512dd09..0eb15e7fa 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/ArrayMap.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/ArrayMap.java
@@ -11,6 +11,7 @@
package org.eclipse.osgi.internal.baseadaptor;
import java.util.*;
+import org.eclipse.osgi.service.resolver.extras.Sortable;
/**
* Simple map when dealing with small amounts of entries.
@@ -19,7 +20,7 @@ import java.util.*;
* @param <K> The key type
* @param <V> the value type
*/
-public class ArrayMap<K, V> implements Collection<K> {
+public class ArrayMap<K, V> implements Collection<K>, Sortable<K> {
final List<K> keys;
final List<V> values;
@@ -157,4 +158,17 @@ public class ArrayMap<K, V> implements Collection<K> {
public V getValue(int index) {
return values.get(index);
}
+
+ public void sort(Comparator<K> comparator) {
+ List<K> sortedKeys = new ArrayList<K>(keys);
+ Collections.sort(sortedKeys, comparator);
+ List<V> sortedValues = new ArrayList<V>(sortedKeys.size());
+ for (K key : sortedKeys) {
+ sortedValues.add(get(key));
+ }
+ clear();
+ for (int i = 0; i < sortedKeys.size(); i++) {
+ put(sortedKeys.get(i), sortedValues.get(i));
+ }
+ }
}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java
index f750efb63..8493bd23c 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java
@@ -11,8 +11,6 @@
******************************************************************************/
package org.eclipse.osgi.internal.module;
-import org.osgi.framework.resource.ResourceConstants;
-
import java.security.AccessController;
import java.util.*;
import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
@@ -29,7 +27,9 @@ import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.hooks.resolver.ResolverHook;
-import org.osgi.framework.wiring.*;
+import org.osgi.framework.resource.ResourceConstants;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRevision;
public class ResolverImpl implements Resolver {
// Debug fields
@@ -348,23 +348,28 @@ public class ResolverImpl implements Resolver {
// find all available hosts to attach to.
boolean foundMatch = false;
BundleConstraint hostConstraint = bundle.getHost();
- List<ResolverBundle> hosts = resolverBundles.get(hostConstraint.getVersionConstraint().getName());
- List<ResolverBundle> candidates = new ArrayList<ResolverBundle>(hosts);
- List<BundleCapability> hostCapabilities = new ArrayList<BundleCapability>(hosts.size());
- // Must remove candidates that do not match before calling hooks.
- for (Iterator<ResolverBundle> iCandidates = candidates.iterator(); iCandidates.hasNext();) {
- ResolverBundle host = iCandidates.next();
- if (!host.isResolvable() || !host.getBundleDescription().attachFragments() || !hostConstraint.isSatisfiedBy(host)) {
- iCandidates.remove();
- } else {
- List<BundleCapability> h = host.getBundleDescription().getDeclaredCapabilities(BundleRevision.HOST_NAMESPACE);
- // the bundle must have 1 host capability.
- hostCapabilities.add(h.get(0));
+ long timestamp;
+ List<ResolverBundle> candidates;
+ do {
+ timestamp = state.getTimeStamp();
+ List<ResolverBundle> hosts = resolverBundles.get(hostConstraint.getVersionConstraint().getName());
+ candidates = new ArrayList<ResolverBundle>(hosts);
+ List<BundleCapability> hostCapabilities = new ArrayList<BundleCapability>(hosts.size());
+ // Must remove candidates that do not match before calling hooks.
+ for (Iterator<ResolverBundle> iCandidates = candidates.iterator(); iCandidates.hasNext();) {
+ ResolverBundle host = iCandidates.next();
+ if (!host.isResolvable() || !host.getBundleDescription().attachFragments() || !hostConstraint.isSatisfiedBy(host)) {
+ iCandidates.remove();
+ } else {
+ List<BundleCapability> h = host.getBundleDescription().getDeclaredCapabilities(BundleRevision.HOST_NAMESPACE);
+ // the bundle must have 1 host capability.
+ hostCapabilities.add(h.get(0));
+ }
}
- }
- if (hook != null)
- hook.filterMatches(hostConstraint.getRequirement(), asCapabilities(new ArrayMap<BundleCapability, ResolverBundle>(hostCapabilities, candidates)));
+ if (hook != null)
+ hook.filterMatches(hostConstraint.getRequirement(), asCapabilities(new ArrayMap<BundleCapability, ResolverBundle>(hostCapabilities, candidates)));
+ } while (timestamp != state.getTimeStamp());
// we are left with only candidates that satisfy the host constraint
for (ResolverBundle host : candidates) {
foundMatch = true;
@@ -372,6 +377,7 @@ public class ResolverImpl implements Resolver {
}
if (!foundMatch)
state.addResolverError(bundle.getBundleDescription(), ResolverError.MISSING_FRAGMENT_HOST, bundle.getHost().getVersionConstraint().toString(), bundle.getHost().getVersionConstraint());
+
}
public synchronized void resolve(BundleDescription[] reRefresh, Dictionary<Object, Object>[] platformProperties) {
@@ -564,7 +570,7 @@ public class ResolverImpl implements Resolver {
if (DEBUG_WIRING)
printWirings();
// set the resolved status of the bundles in the State
- stateResolveBundles(bundles);
+ stateResolveBundles(bundleMapping.values().toArray(new ResolverBundle[bundleMapping.size()]));
}
private void selectSingletons(ResolverBundle[] bundles) {
@@ -1340,26 +1346,31 @@ public class ResolverImpl implements Resolver {
ResolverImpl.log(" - already wired"); //$NON-NLS-1$
return true; // Already wired (due to grouping dependencies) so just return
}
- VersionHashMap<GenericCapability> namespace = resolverGenerics.get(constraint.getNameSpace());
- String name = constraint.getName();
- List<GenericCapability> capabilities;
- if (namespace == null)
- capabilities = Collections.EMPTY_LIST;
- else
- capabilities = name == null || name.indexOf('*') >= 0 ? namespace.getAllValues() : namespace.get(name);
- List<GenericCapability> candidates = new ArrayList<GenericCapability>(capabilities);
- List<BundleCapability> genCapabilities = new ArrayList<BundleCapability>(candidates.size());
- // Must remove candidates that do not match before calling hooks.
- for (Iterator<GenericCapability> iCandidates = candidates.iterator(); iCandidates.hasNext();) {
- GenericCapability capability = iCandidates.next();
- if (!constraint.isSatisfiedBy(capability)) {
- iCandidates.remove();
- } else {
- genCapabilities.add(capability.getCapability());
+ List<GenericCapability> candidates;
+ long timestamp;
+ do {
+ timestamp = state.getTimeStamp();
+ VersionHashMap<GenericCapability> namespace = resolverGenerics.get(constraint.getNameSpace());
+ String name = constraint.getName();
+ List<GenericCapability> capabilities;
+ if (namespace == null)
+ capabilities = Collections.EMPTY_LIST;
+ else
+ capabilities = name == null || name.indexOf('*') >= 0 ? namespace.getAllValues() : namespace.get(name);
+ candidates = new ArrayList<GenericCapability>(capabilities);
+ List<BundleCapability> genCapabilities = new ArrayList<BundleCapability>(candidates.size());
+ // Must remove candidates that do not match before calling hooks.
+ for (Iterator<GenericCapability> iCandidates = candidates.iterator(); iCandidates.hasNext();) {
+ GenericCapability capability = iCandidates.next();
+ if (!constraint.isSatisfiedBy(capability)) {
+ iCandidates.remove();
+ } else {
+ genCapabilities.add(capability.getCapability());
+ }
}
- }
- if (hook != null)
- hook.filterMatches(constraint.getRequirement(), asCapabilities(new ArrayMap<BundleCapability, GenericCapability>(genCapabilities, candidates)));
+ if (hook != null)
+ hook.filterMatches(constraint.getRequirement(), asCapabilities(new ArrayMap<BundleCapability, GenericCapability>(genCapabilities, candidates)));
+ } while (timestamp != state.getTimeStamp());
boolean result = false;
// We are left with only capabilities that satisfy the constraint.
for (GenericCapability capability : candidates) {
@@ -1416,20 +1427,25 @@ public class ResolverImpl implements Resolver {
ResolverImpl.log(" - already wired"); //$NON-NLS-1$
return true; // Already wired (due to grouping dependencies) so just return
}
- List<ResolverBundle> bundles = resolverBundles.get(req.getVersionConstraint().getName());
- List<ResolverBundle> candidates = new ArrayList<ResolverBundle>(bundles);
- List<BundleCapability> capabilities = new ArrayList<BundleCapability>(candidates.size());
- // Must remove candidates that do not match before calling hooks.
- for (Iterator<ResolverBundle> iCandidates = candidates.iterator(); iCandidates.hasNext();) {
- ResolverBundle bundle = iCandidates.next();
- if (!req.isSatisfiedBy(bundle)) {
- iCandidates.remove();
- } else {
- capabilities.add(bundle.getCapability());
+ List<ResolverBundle> candidates;
+ long timestamp;
+ do {
+ timestamp = state.getTimeStamp();
+ List<ResolverBundle> bundles = resolverBundles.get(req.getVersionConstraint().getName());
+ candidates = new ArrayList<ResolverBundle>(bundles);
+ List<BundleCapability> capabilities = new ArrayList<BundleCapability>(candidates.size());
+ // Must remove candidates that do not match before calling hooks.
+ for (Iterator<ResolverBundle> iCandidates = candidates.iterator(); iCandidates.hasNext();) {
+ ResolverBundle bundle = iCandidates.next();
+ if (!req.isSatisfiedBy(bundle)) {
+ iCandidates.remove();
+ } else {
+ capabilities.add(bundle.getCapability());
+ }
}
- }
- if (hook != null)
- hook.filterMatches(req.getRequirement(), asCapabilities(new ArrayMap<BundleCapability, ResolverBundle>(capabilities, candidates)));
+ if (hook != null)
+ hook.filterMatches(req.getRequirement(), asCapabilities(new ArrayMap<BundleCapability, ResolverBundle>(capabilities, candidates)));
+ } while (timestamp != state.getTimeStamp());
// We are left with only capabilities that satisfy the require bundle.
boolean result = false;
for (ResolverBundle bundle : candidates) {
@@ -1483,20 +1499,25 @@ public class ResolverImpl implements Resolver {
}
boolean result = false;
ResolverExport[] substitutableExps = imp.getBundle().getExports(imp.getName());
- List<ResolverExport> exports = resolverExports.get(imp.getName());
- List<ResolverExport> candidates = new ArrayList<ResolverExport>(exports);
- List<BundleCapability> capabilities = new ArrayList<BundleCapability>(candidates.size());
- // Must remove candidates that do not match before calling hooks.
- for (Iterator<ResolverExport> iCandidates = candidates.iterator(); iCandidates.hasNext();) {
- ResolverExport export = iCandidates.next();
- if (!imp.isSatisfiedBy(export)) {
- iCandidates.remove();
- } else {
- capabilities.add(export.getCapability());
+ long timestamp;
+ List<ResolverExport> candidates;
+ do {
+ timestamp = state.getTimeStamp();
+ List<ResolverExport> exports = resolverExports.get(imp.getName());
+ candidates = new ArrayList<ResolverExport>(exports);
+ List<BundleCapability> capabilities = new ArrayList<BundleCapability>(candidates.size());
+ // Must remove candidates that do not match before calling hooks.
+ for (Iterator<ResolverExport> iCandidates = candidates.iterator(); iCandidates.hasNext();) {
+ ResolverExport export = iCandidates.next();
+ if (!imp.isSatisfiedBy(export)) {
+ iCandidates.remove();
+ } else {
+ capabilities.add(export.getCapability());
+ }
}
- }
- if (hook != null)
- hook.filterMatches(imp.getRequirement(), asCapabilities(new ArrayMap<BundleCapability, ResolverExport>(capabilities, candidates)));
+ if (hook != null)
+ hook.filterMatches(imp.getRequirement(), asCapabilities(new ArrayMap<BundleCapability, ResolverExport>(capabilities, candidates)));
+ } while (timestamp != state.getTimeStamp());
// We are left with only capabilities that satisfy the import.
for (ResolverExport export : candidates) {
if (DEBUG_IMPORTS)
@@ -1892,6 +1913,9 @@ public class ResolverImpl implements Resolver {
resolverExports.put(rb.getExportPackages());
resolverBundles.put(rb.getName(), rb);
addGenerics(rb.getGenericCapabilities());
+ if (hook != null && rb.isFragment()) {
+ attachFragment0(rb);
+ }
}
public void bundleRemoved(BundleDescription bundle, boolean pending) {
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BaseDescriptionImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BaseDescriptionImpl.java
index 471631850..a24cf9b0b 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BaseDescriptionImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BaseDescriptionImpl.java
@@ -14,6 +14,7 @@ package org.eclipse.osgi.internal.resolver;
import java.util.*;
import java.util.Map.Entry;
import org.eclipse.osgi.service.resolver.BaseDescription;
+import org.eclipse.osgi.service.resolver.extras.DescriptionReference;
import org.osgi.framework.Version;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRevision;
@@ -26,6 +27,8 @@ public abstract class BaseDescriptionImpl implements BaseDescription {
private volatile Version version;
+ private volatile Object userObject;
+
public String getName() {
return name;
}
@@ -104,7 +107,15 @@ public abstract class BaseDescriptionImpl implements BaseDescription {
return new BaseCapability(namespace);
}
- class BaseCapability implements BundleCapability {
+ public Object getUserObject() {
+ return userObject;
+ }
+
+ public void setUserObject(Object userObject) {
+ this.userObject = userObject;
+ }
+
+ class BaseCapability implements BundleCapability, DescriptionReference {
private final String namespace;
public BaseCapability(String namespace) {
@@ -160,5 +171,9 @@ public abstract class BaseDescriptionImpl implements BaseDescription {
public BundleRevision getResource() {
return getRevision();
}
+
+ public BaseDescription getDescription() {
+ return BaseDescriptionImpl.this;
+ }
}
}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java
index 22c38d221..e88293c9b 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java
@@ -53,7 +53,6 @@ public final class BundleDescriptionImpl extends BaseDescriptionImpl implements
volatile HostSpecification host; //null if the bundle is not a fragment. volatile to allow unsynchronized checks for null
private volatile StateImpl containingState;
- private volatile Object userObject;
private volatile int lazyDataOffset = -1;
private volatile int lazyDataSize = -1;
@@ -581,14 +580,6 @@ public final class BundleDescriptionImpl extends BaseDescriptionImpl implements
}
}
- public Object getUserObject() {
- return userObject;
- }
-
- public void setUserObject(Object userObject) {
- this.userObject = userObject;
- }
-
protected void addDependent(BundleDescription dependent) {
synchronized (this.monitor) {
if (dependents == null)
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateBuilder.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateBuilder.java
index 114b86c65..a93479068 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateBuilder.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateBuilder.java
@@ -31,8 +31,8 @@ public class StateBuilder {
private static final String[] DEFINED_PACKAGE_MATCHING_ATTRS = {Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, Constants.BUNDLE_VERSION_ATTRIBUTE, Constants.PACKAGE_SPECIFICATION_VERSION, Constants.VERSION_ATTRIBUTE};
private static final String[] DEFINED_REQUIRE_BUNDLE_DIRECTIVES = {Constants.RESOLUTION_DIRECTIVE, Constants.VISIBILITY_DIRECTIVE};
private static final String[] DEFINED_FRAGMENT_HOST_DIRECTIVES = {Constants.EXTENSION_DIRECTIVE};
- private static final String[] DEFINED_BSN_DIRECTIVES = {Constants.SINGLETON_DIRECTIVE, Constants.FRAGMENT_ATTACHMENT_DIRECTIVE, Constants.MANDATORY_DIRECTIVE};
- private static final String[] DEFINED_BSN_MATCHING_ATTRS = {Constants.BUNDLE_VERSION_ATTRIBUTE, Constants.OPTIONAL_ATTRIBUTE, Constants.REPROVIDE_ATTRIBUTE};
+ static final String[] DEFINED_BSN_DIRECTIVES = {Constants.SINGLETON_DIRECTIVE, Constants.FRAGMENT_ATTACHMENT_DIRECTIVE, Constants.MANDATORY_DIRECTIVE};
+ static final String[] DEFINED_BSN_MATCHING_ATTRS = {Constants.BUNDLE_VERSION_ATTRIBUTE, Constants.OPTIONAL_ATTRIBUTE, Constants.REPROVIDE_ATTRIBUTE};
private static final String[] DEFINED_REQUIRE_CAPABILITY_DIRECTIVES = {Constants.RESOLUTION_DIRECTIVE, Constants.FILTER_DIRECTIVE};
private static final String[] DEFINED_REQUIRE_CAPABILITY_ATTRS = {};
private static final String[] DEFINED_OSGI_VALIDATE_HEADERS = {Constants.IMPORT_PACKAGE, Constants.DYNAMICIMPORT_PACKAGE, Constants.EXPORT_PACKAGE, Constants.FRAGMENT_HOST, Constants.BUNDLE_SYMBOLICNAME, Constants.REQUIRE_BUNDLE};
@@ -108,7 +108,7 @@ public class StateBuilder {
ManifestElement[] provides = ManifestElement.parseHeader(Constants.PROVIDE_PACKAGE, manifest.get(Constants.PROVIDE_PACKAGE));
boolean strict = state != null && state.inStrictMode();
List<String> providedExports = new ArrayList<String>(provides == null ? 0 : provides.length);
- result.setExportPackages(createExportPackages(exports, provides, providedExports, manifestVersion, strict));
+ result.setExportPackages(createExportPackages(exports, provides, providedExports, strict));
ManifestElement[] imports = ManifestElement.parseHeader(Constants.IMPORT_PACKAGE, manifest.get(Constants.IMPORT_PACKAGE));
ManifestElement[] dynamicImports = ManifestElement.parseHeader(Constants.DYNAMICIMPORT_PACKAGE, manifest.get(Constants.DYNAMICIMPORT_PACKAGE));
result.setImportPackages(createImportPackages(result.getExportPackages(), providedExports, imports, dynamicImports, manifestVersion));
@@ -194,7 +194,7 @@ public class StateBuilder {
return result;
}
- private static String getPlatformProperty(StateImpl state, String key) {
+ private static String getPlatformProperty(State state, String key) {
Dictionary<Object, Object>[] platformProps = state == null ? null : state.getPlatformProperties();
return platformProps == null || platformProps.length == 0 ? null : (String) platformProps[0].get(key);
}
@@ -228,7 +228,7 @@ public class StateBuilder {
return result;
}
- private static BundleSpecification createRequiredBundle(ManifestElement spec) {
+ static BundleSpecification createRequiredBundle(ManifestElement spec) {
BundleSpecificationImpl result = new BundleSpecificationImpl();
result.setName(spec.getValue());
result.setVersionRange(getVersionRange(spec.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE)));
@@ -306,25 +306,25 @@ public class StateBuilder {
private static String getResolution(String resolution) {
String result = ImportPackageSpecification.RESOLUTION_STATIC;
- if (Constants.RESOLUTION_OPTIONAL.equals(resolution))
- result = ImportPackageSpecification.RESOLUTION_OPTIONAL;
+ if (Constants.RESOLUTION_OPTIONAL.equals(resolution) || ImportPackageSpecification.RESOLUTION_DYNAMIC.equals(resolution))
+ result = resolution;
return result;
}
- static ExportPackageDescription[] createExportPackages(ManifestElement[] exported, ManifestElement[] provides, List<String> providedExports, int manifestVersion, boolean strict) {
+ static ExportPackageDescription[] createExportPackages(ManifestElement[] exported, ManifestElement[] provides, List<String> providedExports, boolean strict) {
int numExports = (exported == null ? 0 : exported.length) + (provides == null ? 0 : provides.length);
if (numExports == 0)
return null;
List<ExportPackageDescription> allExports = new ArrayList<ExportPackageDescription>(numExports);
if (exported != null)
for (int i = 0; i < exported.length; i++)
- addExportPackages(exported[i], allExports, manifestVersion, strict);
+ addExportPackages(exported[i], allExports, strict);
if (provides != null)
addProvidePackages(provides, allExports, providedExports);
return allExports.toArray(new ExportPackageDescription[allExports.size()]);
}
- private static void addExportPackages(ManifestElement exportPackage, List<ExportPackageDescription> allExports, int manifestVersion, boolean strict) {
+ static void addExportPackages(ManifestElement exportPackage, List<ExportPackageDescription> allExports, boolean strict) {
String[] exportNames = exportPackage.getValueComponents();
for (int i = 0; i < exportNames.length; i++) {
// if we are in strict mode and the package is marked as internal, skip it.
@@ -367,7 +367,7 @@ public class StateBuilder {
}
}
- private static Map<String, String> getDirectives(ManifestElement element, String[] definedDirectives) {
+ static Map<String, String> getDirectives(ManifestElement element, String[] definedDirectives) {
Enumeration<String> keys = element.getDirectiveKeys();
if (keys == null)
return null;
@@ -385,7 +385,7 @@ public class StateBuilder {
return arbitraryDirectives;
}
- private static Map<String, Object> getAttributes(ManifestElement element, String[] definedAttrs) {
+ static Map<String, Object> getAttributes(ManifestElement element, String[] definedAttrs) {
Enumeration<String> keys = element.getKeys();
Map<String, Object> arbitraryAttrs = null;
if (keys == null)
@@ -463,7 +463,7 @@ public class StateBuilder {
return components;
}
- private static HostSpecification createHostSpecification(ManifestElement spec, StateImpl state) {
+ static HostSpecification createHostSpecification(ManifestElement spec, State state) {
if (spec == null)
return null;
HostSpecificationImpl result = new HostSpecificationImpl();
@@ -484,7 +484,7 @@ public class StateBuilder {
return result == null ? null : result.toArray(new GenericSpecification[result.size()]);
}
- private static List<GenericSpecification> createOSGiRequires(ManifestElement[] osgiRequires, List<GenericSpecification> result) throws BundleException {
+ static List<GenericSpecification> createOSGiRequires(ManifestElement[] osgiRequires, List<GenericSpecification> result) throws BundleException {
if (osgiRequires == null)
return result;
if (result == null)
@@ -562,7 +562,7 @@ public class StateBuilder {
return result == null ? null : result.toArray(new GenericDescription[result.size()]);
}
- private static List<GenericDescription> createOSGiCapabilities(ManifestElement[] osgiCapabilities, List<GenericDescription> result, BundleDescription description) throws BundleException {
+ static List<GenericDescription> createOSGiCapabilities(ManifestElement[] osgiCapabilities, List<GenericDescription> result, BundleDescription description) throws BundleException {
if (result == null)
result = new ArrayList<GenericDescription>(osgiCapabilities == null ? 1 : osgiCapabilities.length + 1);
// Always have an osgi.identity capability if there is a symbolic name.
@@ -770,7 +770,7 @@ public class StateBuilder {
}
}
- private static GenericDescription createOsgiIdentityCapability(BundleDescription description) {
+ static GenericDescription createOsgiIdentityCapability(BundleDescription description) {
if (description.getSymbolicName() == null)
return null;
GenericDescriptionImpl result = new GenericDescriptionImpl();
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java
index 68f61b241..383b33a78 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java
@@ -836,7 +836,7 @@ public abstract class StateImpl implements State {
private void addSystemExports(List<ExportPackageDescription> exports, ManifestElement[] elements, int index) {
if (elements == null)
return;
- ExportPackageDescription[] systemExports = StateBuilder.createExportPackages(elements, null, null, 2, false);
+ ExportPackageDescription[] systemExports = StateBuilder.createExportPackages(elements, null, null, false);
Integer profInx = new Integer(index);
for (int j = 0; j < systemExports.length; j++) {
((ExportPackageDescriptionImpl) systemExports[j]).setDirective(ExportPackageDescriptionImpl.EQUINOX_EE, profInx);
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateObjectFactoryImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateObjectFactoryImpl.java
index df97bf13a..264ead854 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateObjectFactoryImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateObjectFactoryImpl.java
@@ -74,6 +74,52 @@ public class StateObjectFactoryImpl implements StateObjectFactory {
return bundle;
}
+ public BundleDescription createBundleDescription(long id, String symbolicName, Version version, String location, BundleSpecification[] required, HostSpecification host, ImportPackageSpecification[] imports, ExportPackageDescription[] exports, String platformFilter, String[] executionEnvironments, GenericSpecification[] genericRequires, GenericDescription[] genericCapabilities, NativeCodeSpecification nativeCode) {
+ BundleDescriptionImpl bundle = new BundleDescriptionImpl();
+ bundle.setBundleId(id);
+
+ try {
+ ManifestElement[] symbolicNameElements = ManifestElement.parseHeader(Constants.BUNDLE_SYMBOLICNAME, symbolicName);
+ if (symbolicNameElements.length > 0) {
+ ManifestElement bsnElement = symbolicNameElements[0];
+ bundle.setSymbolicName(bsnElement.getValue());
+ bundle.setStateBit(BundleDescriptionImpl.SINGLETON, "true".equals(bsnElement.getDirective(Constants.SINGLETON_DIRECTIVE))); //$NON-NLS-1$
+ String fragmentAttachment = bsnElement.getDirective(Constants.FRAGMENT_ATTACHMENT_DIRECTIVE);
+ if (fragmentAttachment != null) {
+ if (fragmentAttachment.equals(Constants.FRAGMENT_ATTACHMENT_RESOLVETIME)) {
+ bundle.setStateBit(BundleDescriptionImpl.ATTACH_FRAGMENTS, true);
+ bundle.setStateBit(BundleDescriptionImpl.DYNAMIC_FRAGMENTS, false);
+ } else if (fragmentAttachment.equals(Constants.FRAGMENT_ATTACHMENT_NEVER)) {
+ bundle.setStateBit(BundleDescriptionImpl.ATTACH_FRAGMENTS, false);
+ bundle.setStateBit(BundleDescriptionImpl.DYNAMIC_FRAGMENTS, false);
+ }
+ }
+ bundle.setDirective(Constants.MANDATORY_DIRECTIVE, ManifestElement.getArrayFromList(bsnElement.getDirective(Constants.MANDATORY_DIRECTIVE)));
+ bundle.setAttributes(StateBuilder.getAttributes(bsnElement, StateBuilder.DEFINED_BSN_MATCHING_ATTRS));
+ bundle.setArbitraryDirectives(StateBuilder.getDirectives(bsnElement, StateBuilder.DEFINED_BSN_DIRECTIVES));
+ }
+ } catch (BundleException e) {
+ throw (IllegalArgumentException) new IllegalArgumentException("Illegal symbolic name: " + symbolicName).initCause(e); //$NON-NLS-1$
+ }
+
+ bundle.setVersion(version);
+ bundle.setLocation(location);
+ bundle.setRequiredBundles(required);
+ bundle.setHost(host);
+ bundle.setImportPackages(imports);
+ bundle.setExportPackages(exports);
+ bundle.setPlatformFilter(platformFilter);
+ bundle.setExecutionEnvironments(executionEnvironments);
+ bundle.setGenericRequires(genericRequires);
+ GenericDescription[] includeIdentity = new GenericDescription[genericCapabilities == null ? 1 : genericCapabilities.length + 1];
+ if (genericCapabilities != null)
+ System.arraycopy(genericCapabilities, 0, includeIdentity, 1, genericCapabilities.length);
+ includeIdentity[0] = StateBuilder.createOsgiIdentityCapability(bundle);
+ bundle.setGenericCapabilities(includeIdentity);
+ bundle.setNativeCodeSpecification(nativeCode);
+ return bundle;
+ }
+
public BundleDescription createBundleDescription(BundleDescription original) {
BundleDescriptionImpl bundle = new BundleDescriptionImpl();
bundle.setBundleId(original.getBundleId());
@@ -464,4 +510,88 @@ public class StateObjectFactoryImpl implements StateObjectFactory {
StateWriter writer = new StateWriter();
writer.saveStateDeprecated((StateImpl) state, stream);
}
+
+ @SuppressWarnings("unchecked")
+ public List<BundleSpecification> createBundleSpecifications(String declaration) {
+ try {
+ ManifestElement[] elements = ManifestElement.parseHeader(Constants.REQUIRE_BUNDLE, declaration);
+ if (elements == null)
+ return Collections.EMPTY_LIST;
+ List<BundleSpecification> result = new ArrayList<BundleSpecification>(elements.length);
+ for (ManifestElement element : elements)
+ result.add(StateBuilder.createRequiredBundle(element));
+ return result;
+ } catch (BundleException e) {
+ throw (IllegalArgumentException) new IllegalArgumentException("Declaration is invalid: " + declaration).initCause(e); //$NON-NLS-1$
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<HostSpecification> createHostSpecifications(String declaration) {
+ try {
+ ManifestElement[] elements = ManifestElement.parseHeader(Constants.FRAGMENT_HOST, declaration);
+ if (elements == null)
+ return Collections.EMPTY_LIST;
+ List<HostSpecification> result = new ArrayList<HostSpecification>(elements.length);
+ for (ManifestElement element : elements)
+ result.add(StateBuilder.createHostSpecification(element, null));
+ return result;
+ } catch (BundleException e) {
+ throw (IllegalArgumentException) new IllegalArgumentException("Declaration is invalid: " + declaration).initCause(e); //$NON-NLS-1$
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<ImportPackageSpecification> createImportPackageSpecifications(String declaration) {
+ try {
+ ManifestElement[] elements = ManifestElement.parseHeader(Constants.IMPORT_PACKAGE, declaration);
+ if (elements == null)
+ return Collections.EMPTY_LIST;
+ List<ImportPackageSpecification> result = new ArrayList<ImportPackageSpecification>(elements.length);
+ for (ManifestElement element : elements)
+ StateBuilder.addImportPackages(element, result, 2, false);
+ return result;
+ } catch (BundleException e) {
+ throw (IllegalArgumentException) new IllegalArgumentException("Declaration is invalid: " + declaration).initCause(e); //$NON-NLS-1$
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<GenericDescription> createGenericDescriptions(String declaration) {
+ try {
+ ManifestElement[] elements = ManifestElement.parseHeader(Constants.PROVIDE_CAPABILITY, declaration);
+ if (elements == null)
+ return Collections.EMPTY_LIST;
+ return StateBuilder.createOSGiCapabilities(elements, new ArrayList<GenericDescription>(elements.length), (Integer) null);
+ } catch (BundleException e) {
+ throw (IllegalArgumentException) new IllegalArgumentException("Declaration is invalid: " + declaration).initCause(e); //$NON-NLS-1$
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<GenericSpecification> createGenericSpecifications(String declaration) {
+ try {
+ ManifestElement[] elements = ManifestElement.parseHeader(Constants.REQUIRE_CAPABILITY, declaration);
+ if (elements == null)
+ return Collections.EMPTY_LIST;
+ return StateBuilder.createOSGiRequires(elements, new ArrayList<GenericSpecification>(elements.length));
+ } catch (BundleException e) {
+ throw (IllegalArgumentException) new IllegalArgumentException("Declaration is invalid: " + declaration).initCause(e); //$NON-NLS-1$
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<ExportPackageDescription> createExportPackageDescriptions(String declaration) {
+ try {
+ ManifestElement[] elements = ManifestElement.parseHeader(Constants.IMPORT_PACKAGE, declaration);
+ if (elements == null)
+ return Collections.EMPTY_LIST;
+ List<ExportPackageDescription> result = new ArrayList<ExportPackageDescription>(elements.length);
+ for (ManifestElement element : elements)
+ StateBuilder.addExportPackages(element, result, false);
+ return result;
+ } catch (BundleException e) {
+ throw (IllegalArgumentException) new IllegalArgumentException("Declaration is invalid: " + declaration).initCause(e); //$NON-NLS-1$
+ }
+ }
}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/VersionConstraintImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/VersionConstraintImpl.java
index a88af773a..45359bf6e 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/VersionConstraintImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/VersionConstraintImpl.java
@@ -12,16 +12,16 @@
*******************************************************************************/
package org.eclipse.osgi.internal.resolver;
-import org.osgi.framework.resource.Capability;
-import org.osgi.framework.resource.ResourceConstants;
-
import java.util.Collections;
import java.util.Map;
import org.eclipse.osgi.framework.internal.core.Constants;
import org.eclipse.osgi.internal.resolver.BaseDescriptionImpl.BaseCapability;
import org.eclipse.osgi.service.resolver.*;
+import org.eclipse.osgi.service.resolver.extras.SpecificationReference;
import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.*;
+import org.osgi.framework.resource.Capability;
+import org.osgi.framework.resource.ResourceConstants;
import org.osgi.framework.wiring.*;
abstract class VersionConstraintImpl implements VersionConstraint {
@@ -32,6 +32,7 @@ abstract class VersionConstraintImpl implements VersionConstraint {
private VersionRange versionRange;
private BundleDescription bundle;
private BaseDescription supplier;
+ private volatile Object userObject;
public String getName() {
synchronized (this.monitor) {
@@ -114,7 +115,15 @@ abstract class VersionConstraintImpl implements VersionConstraint {
return new BundleRequirementImpl(namespace);
}
- class BundleRequirementImpl implements BundleRequirement {
+ public Object getUserObject() {
+ return userObject;
+ }
+
+ public void setUserObject(Object userObject) {
+ this.userObject = userObject;
+ }
+
+ class BundleRequirementImpl implements BundleRequirement, SpecificationReference {
private final String namespace;
public BundleRequirementImpl(String namespace) {
@@ -182,6 +191,10 @@ abstract class VersionConstraintImpl implements VersionConstraint {
public BundleRevision getResource() {
return getRevision();
}
+
+ public VersionConstraint getSpecification() {
+ return VersionConstraintImpl.this;
+ }
}
static StringBuffer addFilterAttributes(StringBuffer filter, Map<String, ?> attributes) {

Back to the top