Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles/org.eclipse.osgi/.settings/.api_filters45
-rw-r--r--bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BaseDescription.java4
-rw-r--r--bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BundleDescription.java13
-rw-r--r--bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/State.java8
-rw-r--r--bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/StateWire.java81
-rw-r--r--bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/VersionConstraint.java12
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java46
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleFragment.java48
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleHost.java35
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/CoreResolverHookFactory.java15
-rw-r--r--bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/InternalSystemBundle.java6
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WeavingHookConfigurator.java9
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WovenClassImpl.java9
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/AdaptPermission.java635
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/Bundle.java42
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/CapabilityPermission.java12
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/Constants.java4
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkEvent.java22
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/ServiceFactory.java28
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/resolver/ResolverHook.java218
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/service/ListenerHook.java3
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/weaving/WovenClass.java14
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/Framework.java30
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleCapability.java61
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleRequirement.java73
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleRevision.java191
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleRevisions.java67
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleWire.java72
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleWiring.java215
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleWirings.java69
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/Capability.java157
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/WiredCapability.java54
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverBundle.java16
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverConstraint.java10
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java111
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/VersionHashMap.java4
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/VersionSupplier.java8
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BaseDescriptionImpl.java89
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java274
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleSpecificationImpl.java40
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ExportPackageDescriptionImpl.java38
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/GenericDescriptionImpl.java36
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/GenericSpecificationImpl.java27
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/HostSpecificationImpl.java29
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ImportPackageSpecificationImpl.java31
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/NativeCodeSpecificationImpl.java17
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ReadOnlyState.java5
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateHelperImpl.java16
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java33
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateReader.java77
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateWriter.java58
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/VersionConstraintImpl.java69
52 files changed, 2349 insertions, 937 deletions
diff --git a/bundles/org.eclipse.osgi/.settings/.api_filters b/bundles/org.eclipse.osgi/.settings/.api_filters
index a5b74e196..29273de31 100644
--- a/bundles/org.eclipse.osgi/.settings/.api_filters
+++ b/bundles/org.eclipse.osgi/.settings/.api_filters
@@ -419,6 +419,13 @@
</message_arguments>
</filter>
</resource>
+<resource path="osgi/src/org/osgi/framework/AdaptPermission.java" type="org.osgi.framework.AdaptPermission">
+<filter comment="Ignore OSGi API" id="1110441988">
+<message_arguments>
+<message_argument value="org.osgi.framework.AdaptPermission"/>
+</message_arguments>
+</filter>
+</resource>
<resource path="osgi/src/org/osgi/framework/AdminPermission.java" type="org.osgi.framework.AdminPermission">
<filter comment="Ignore OSGi API" id="1141899266">
<message_arguments>
@@ -920,6 +927,13 @@
</message_arguments>
</filter>
</resource>
+<resource path="osgi/src/org/osgi/framework/hooks/service/ListenerHook.java" type="org.osgi.framework.hooks.service.ListenerHook$ListenerInfo">
+<filter comment="Ignore OSGi APIs" id="403853384">
+<message_arguments>
+<message_argument value="org.osgi.framework.hooks.service.ListenerHook.ListenerInfo"/>
+</message_arguments>
+</filter>
+</resource>
<resource path="osgi/src/org/osgi/framework/hooks/weaving/WeavingException.java" type="org.osgi.framework.hooks.weaving.WeavingException">
<filter comment="Ignore OSGi API" id="1110441988">
<message_arguments>
@@ -969,45 +983,52 @@
</message_arguments>
</filter>
</resource>
-<resource path="osgi/src/org/osgi/framework/wiring/BundleRevision.java" type="org.osgi.framework.wiring.BundleRevision">
+<resource path="osgi/src/org/osgi/framework/wiring/BundleCapability.java" type="org.osgi.framework.wiring.BundleCapability">
<filter comment="Ignore OSGi API" id="1110441988">
<message_arguments>
-<message_argument value="org.osgi.framework.wiring.BundleRevision"/>
+<message_argument value="org.osgi.framework.wiring.BundleCapability"/>
</message_arguments>
</filter>
</resource>
-<resource path="osgi/src/org/osgi/framework/wiring/BundleWiring.java" type="org.osgi.framework.wiring.BundleWiring">
+<resource path="osgi/src/org/osgi/framework/wiring/BundleRequirement.java" type="org.osgi.framework.wiring.BundleRequirement">
<filter comment="Ignore OSGi API" id="1110441988">
<message_arguments>
-<message_argument value="org.osgi.framework.wiring.BundleWiring"/>
+<message_argument value="org.osgi.framework.wiring.BundleRequirement"/>
</message_arguments>
</filter>
</resource>
-<resource path="osgi/src/org/osgi/framework/wiring/BundleWirings.java" type="org.osgi.framework.wiring.BundleWirings">
+<resource path="osgi/src/org/osgi/framework/wiring/BundleRevision.java" type="org.osgi.framework.wiring.BundleRevision">
<filter comment="Ignore OSGi API" id="1110441988">
<message_arguments>
-<message_argument value="org.osgi.framework.wiring.BundleWirings"/>
+<message_argument value="org.osgi.framework.wiring.BundleRevision"/>
</message_arguments>
</filter>
</resource>
-<resource path="osgi/src/org/osgi/framework/wiring/Capability.java" type="org.osgi.framework.wiring.Capability">
+<resource path="osgi/src/org/osgi/framework/wiring/BundleRevisions.java" type="org.osgi.framework.wiring.BundleRevisions">
<filter comment="Ignore OSGi API" id="1110441988">
<message_arguments>
-<message_argument value="org.osgi.framework.wiring.Capability"/>
+<message_argument value="org.osgi.framework.wiring.BundleRevisions"/>
</message_arguments>
</filter>
</resource>
-<resource path="osgi/src/org/osgi/framework/wiring/FrameworkWiring.java" type="org.osgi.framework.wiring.FrameworkWiring">
+<resource path="osgi/src/org/osgi/framework/wiring/BundleWire.java" type="org.osgi.framework.wiring.BundleWire">
<filter comment="Ignore OSGi API" id="1110441988">
<message_arguments>
-<message_argument value="org.osgi.framework.wiring.FrameworkWiring"/>
+<message_argument value="org.osgi.framework.wiring.BundleWire"/>
</message_arguments>
</filter>
</resource>
-<resource path="osgi/src/org/osgi/framework/wiring/WiredCapability.java" type="org.osgi.framework.wiring.WiredCapability">
+<resource path="osgi/src/org/osgi/framework/wiring/BundleWiring.java" type="org.osgi.framework.wiring.BundleWiring">
<filter comment="Ignore OSGi API" id="1110441988">
<message_arguments>
-<message_argument value="org.osgi.framework.wiring.WiredCapability"/>
+<message_argument value="org.osgi.framework.wiring.BundleWiring"/>
+</message_arguments>
+</filter>
+</resource>
+<resource path="osgi/src/org/osgi/framework/wiring/FrameworkWiring.java" type="org.osgi.framework.wiring.FrameworkWiring">
+<filter comment="Ignore OSGi API" id="1110441988">
+<message_arguments>
+<message_argument value="org.osgi.framework.wiring.FrameworkWiring"/>
</message_arguments>
</filter>
</resource>
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 024eb8995..9d3b02b38 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
@@ -12,7 +12,7 @@ package org.eclipse.osgi.service.resolver;
import java.util.Map;
import org.osgi.framework.Version;
-import org.osgi.framework.wiring.Capability;
+import org.osgi.framework.wiring.BundleCapability;
/**
* This class represents a base description object for a state. All description
@@ -70,5 +70,5 @@ public interface BaseDescription {
* @return the capability represented by this base description
* @since 3.7
*/
- public Capability getCapability();
+ public BundleCapability getCapability();
}
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 89d525c19..38f02beb7 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2010 IBM Corporation and others.
+ * Copyright (c) 2003, 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
@@ -12,7 +12,6 @@ package org.eclipse.osgi.service.resolver;
import java.util.Map;
import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWiring;
/**
* This class represents a specific version of a bundle in the system.
@@ -289,14 +288,4 @@ public interface BundleDescription extends BaseDescription, BundleRevision {
* @since 3.4
*/
public ExportPackageDescription[] getSubstitutedExports();
-
- /**
- * Returns the bundle wiring object associated with this bundle description.
- * A bundle description can only have one bundle wiring object associated with
- * it which is in use. A bundle description must be resolved in order
- * to have a bundle wiring object associated with it.
- * @return the bundle wiring object associated with this bundle description.
- * @since 3.7
- */
- public BundleWiring getBundleWiring();
}
diff --git a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/State.java b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/State.java
index 1996cf1ed..63b9f70ac 100644
--- a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/State.java
+++ b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/State.java
@@ -10,8 +10,7 @@
*******************************************************************************/
package org.eclipse.osgi.service.resolver;
-import java.util.Collection;
-import java.util.Dictionary;
+import java.util.*;
import org.osgi.framework.BundleException;
import org.osgi.framework.Version;
import org.osgi.framework.hooks.resolver.ResolverHookFactory;
@@ -229,11 +228,12 @@ public interface State {
* @param selectedCapabilities the selected capabilities for this resolved bundle, can be <code>null</code>
* @param resolvedRequires the {@link BundleDescription}s that resolve the required bundles for this bundle, can be <code>null</code>
* @param resolvedImports the exported packages that resolve the imports for this bundle, can be <code>null</code>
- * @param resolveCapabilities the capabilities that resolve the required capabilities for this bundle, can be <code>null</code>
+ * @param resolvedCapabilities the capabilities that resolve the required capabilities for this bundle, can be <code>null</code>
+ * @param resolvedWires the map of state wires for the resolved requirements of the given bundle. The key is the name space of the requirement.
* @throws IllegalStateException if this is not done during a call to <code>resolve</code>
* @since 3.7
*/
- public void resolveBundle(BundleDescription bundle, boolean status, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, ExportPackageDescription[] substitutedExports, GenericDescription[] selectedCapabilities, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports, GenericDescription[] resolveCapabilities);
+ public void resolveBundle(BundleDescription bundle, boolean status, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, ExportPackageDescription[] substitutedExports, GenericDescription[] selectedCapabilities, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports, GenericDescription[] resolvedCapabilities, Map<String, List<StateWire>> resolvedWires);
/**
* Sets the given removal pending bundle to removal complete for this state.
diff --git a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/StateWire.java b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/StateWire.java
new file mode 100644
index 000000000..2b2afdf4b
--- /dev/null
+++ b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/StateWire.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * 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;
+
+/**
+ * A state wire represents a decision made by a resolver to wire a requirement to a capability.
+ * There are 4 parts to a state wire.
+ * <ul>
+ * <li>The requirement which may have been specified by a host bundle or one of its attached fragments.</li>
+ * <li>The host bundle which is associated with the requirement. There are cases where the host
+ * bundle may not be the same as the bundle which declared the requirement. For example, if a fragment
+ * specifies additional requirements.</li>
+ * <li>The capability which may have been specified by a host bundle or one of its attached fragments.</li>
+ * <li>The host bundle which is associated with the capability. There are cases where the host
+ * bundle may not be the same as the bundle which declared the capability. For example, if a fragment
+ * specifies additional capabilities.</li>
+ * </ul>
+ * @since 3.7
+ */
+public class StateWire {
+ private final BundleDescription requirementHost;
+ private final VersionConstraint declaredRequirement;
+ private final BundleDescription capabilityHost;
+ private final BaseDescription declaredCapability;
+
+ /**
+ * Constructs a new state wire.
+ * @param requirementHost the bundle hosting the requirement.
+ * @param declaredRequirement the declared requirement. The bundle declaring the requirement may be different from the requirement host.
+ * @param capabilityHost the bundle hosting the capability.
+ * @param declaredCapability the declared capability. The bundle declaring the capability may be different from the capability host.
+ */
+ public StateWire(BundleDescription requirementHost, VersionConstraint declaredRequirement, BundleDescription capabilityHost, BaseDescription declaredCapability) {
+ super();
+ this.requirementHost = requirementHost;
+ this.declaredRequirement = declaredRequirement;
+ this.capabilityHost = capabilityHost;
+ this.declaredCapability = declaredCapability;
+
+ }
+
+ /**
+ * Gets the requirement host.
+ * @return the requirement host.
+ */
+ public BundleDescription getRequirementHost() {
+ return requirementHost;
+ }
+
+ /**
+ * Gets the declared requirement.
+ * @return the declared requirement.
+ */
+ public VersionConstraint getDeclaredRequirement() {
+ return declaredRequirement;
+ }
+
+ /**
+ * gets the capability host.
+ * @return the capability host.
+ */
+ public BundleDescription getCapabilityHost() {
+ return capabilityHost;
+ }
+
+ /**
+ * gets the declared capability.
+ * @return the declared capability.
+ */
+ public BaseDescription getDeclaredCapability() {
+ return declaredCapability;
+ }
+}
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 b61ad42b1..10119e154 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
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.osgi.service.resolver;
+import org.osgi.framework.wiring.BundleRequirement;
+
/**
* VersionConstraints represent the relationship between two bundles (in the
* case of bundle requires) or a bundle and a package (in the case of import/export).
@@ -70,4 +72,14 @@ public interface VersionConstraint extends Cloneable {
* @see #isResolved()
*/
public BaseDescription getSupplier();
+
+ /**
+ * Returns the requirement represented by this constraint.
+ * Some constraint types may not be able to represent
+ * a requirement. In such cases <code>null</code> is
+ * returned.
+ * @return the requirement represented by this constraint
+ * @since 3.7
+ */
+ public BundleRequirement getRequirement();
}
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java
index d2a784926..36d52ab9a 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java
@@ -30,15 +30,14 @@ import org.eclipse.osgi.signedcontent.*;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.*;
import org.osgi.framework.startlevel.BundleStartLevel;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.framework.wiring.*;
/**
* This object is given out to bundles and wraps the internal Bundle object. It
* is destroyed when a bundle is uninstalled and reused if a bundle is updated.
* This class is abstract and is extended by BundleHost and BundleFragment.
*/
-public abstract class AbstractBundle implements Bundle, Comparable<Bundle>, KeyedElement, BundleStartLevel, BundleReference {
+public abstract class AbstractBundle implements Bundle, Comparable<Bundle>, KeyedElement, BundleStartLevel, BundleReference, BundleRevisions {
private final static long STATE_CHANGE_TIMEOUT;
static {
long stateChangeWait = 5000;
@@ -1453,8 +1452,27 @@ public abstract class AbstractBundle implements Bundle, Comparable<Bundle>, Keye
}
}
+ public final <A> A adapt(Class<A> adapterType) {
+ checkAdaptPermission(adapterType);
+ return adapt0(adapterType);
+ }
+
+ public List<BundleRevision> getRevisions() {
+ List<BundleRevision> revisions = new ArrayList<BundleRevision>();
+ BundleDescription current = getBundleDescription();
+ if (current != null)
+ revisions.add(current);
+ BundleDescription[] removals = framework.adaptor.getState().getRemovalPending();
+ for (BundleDescription removed : removals) {
+ if (removed.getBundleId() == getBundleId() && removed != current) {
+ revisions.add(removed);
+ }
+ }
+ return revisions;
+ }
+
@SuppressWarnings("unchecked")
- public <A> A adapt(Class<A> adapterType) {
+ protected <A> A adapt0(Class<A> adapterType) {
if (adapterType.isInstance(this))
return (A) this;
if (BundleContext.class.equals(adapterType)) {
@@ -1464,22 +1482,32 @@ public abstract class AbstractBundle implements Bundle, Comparable<Bundle>, Keye
return null;
}
}
- if (BundleStartLevel.class.equals(adapterType))
- return (A) this;
-
if (BundleWiring.class.equals(adapterType)) {
- if (state == UNINSTALLED || isFragment())
+ if (state == UNINSTALLED)
return null;
BundleDescription description = getBundleDescription();
- return (A) description.getBundleWiring();
+ return (A) description.getWiring();
}
if (BundleRevision.class.equals(adapterType)) {
+ if (state == UNINSTALLED)
+ return null;
return (A) getBundleDescription();
}
return null;
}
+ /**
+ * Check for permission to get a service.
+ */
+ private <A> void checkAdaptPermission(Class<A> adapterType) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm == null) {
+ return;
+ }
+ sm.checkPermission(new AdaptPermission(adapterType.getName(), this, AdaptPermission.ADAPT));
+ }
+
public File getDataFile(String filename) {
return framework.getDataFile(this, filename);
}
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleFragment.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleFragment.java
index 26fb16328..98ca8ee24 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleFragment.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleFragment.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2010 IBM Corporation and others.
+ * Copyright (c) 2003, 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
@@ -13,16 +13,12 @@ package org.eclipse.osgi.framework.internal.core;
import java.io.IOException;
import java.net.URL;
-import java.util.*;
+import java.util.Enumeration;
import org.eclipse.osgi.framework.adaptor.BundleData;
import org.eclipse.osgi.framework.debug.Debug;
import org.eclipse.osgi.internal.loader.BundleLoader;
-import org.eclipse.osgi.service.resolver.BundleDescription;
-import org.eclipse.osgi.service.resolver.HostSpecification;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.*;
-import org.osgi.framework.wiring.BundleWiring;
-import org.osgi.framework.wiring.BundleWirings;
public class BundleFragment extends AbstractBundle {
@@ -335,44 +331,4 @@ public class BundleFragment extends AbstractBundle {
// Fragments cannot have a BundleContext.
return null;
}
-
- @SuppressWarnings("unchecked")
- public <A> A adapt(Class<A> adapterType) {
- if (BundleWirings.class.equals(adapterType)) {
- return (A) new BundleWirings() {
- public Bundle getBundle() {
- return BundleFragment.this;
- }
-
- public List<BundleWiring> getWirings() {
- List<BundleWiring> wirings = new ArrayList<BundleWiring>();
- BundleDescription current = getBundleDescription();
- BundleDescription[] removed = framework.adaptor.getState().getRemovalPending();
-
- int i = -1;
- do {
- HostSpecification hostSpec = null;
- if (i == -1) {
- if (current != null)
- hostSpec = current.getHost();
- } else if (removed[i] != current && removed[i].getBundleId() == getBundleId()) {
- hostSpec = removed[i].getHost();
- }
- BundleDescription[] hostDescs = hostSpec == null ? null : hostSpec.getHosts();
- if (hostDescs != null) {
- for (BundleDescription host : hostDescs) {
- BundleWiring wiring = host.getBundleWiring();
- if (wiring != null)
- wirings.add(wiring);
- }
- }
- i++;
- } while (i < removed.length);
- return wirings;
- }
-
- };
- }
- return super.adapt(adapterType);
- }
}
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleHost.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleHost.java
index e5ccd70f9..282949a20 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleHost.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleHost.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2010 IBM Corporation and others.
+ * Copyright (c) 2003, 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
@@ -13,7 +13,7 @@ package org.eclipse.osgi.framework.internal.core;
import java.io.IOException;
import java.net.URL;
-import java.util.*;
+import java.util.Enumeration;
import org.eclipse.osgi.framework.adaptor.*;
import org.eclipse.osgi.framework.debug.Debug;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
@@ -23,8 +23,6 @@ import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.osgi.service.resolver.ResolverHookException;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.*;
-import org.osgi.framework.wiring.BundleWiring;
-import org.osgi.framework.wiring.BundleWirings;
public class BundleHost extends AbstractBundle {
public static final int LAZY_TRIGGER = 0x40000000;
@@ -682,33 +680,4 @@ public class BundleHost extends AbstractBundle {
return (bcl instanceof ClassLoader) ? (ClassLoader) bcl : null;
}
- @SuppressWarnings("unchecked")
- public <A> A adapt(Class<A> adapterType) {
- if (BundleWirings.class.equals(adapterType)) {
- return (A) new BundleWirings() {
- public Bundle getBundle() {
- return BundleHost.this;
- }
-
- public List<BundleWiring> getWirings() {
- List<BundleWiring> wirings = new ArrayList<BundleWiring>();
- BundleWiring current = adapt(BundleWiring.class);
- if (current != null)
- wirings.add(current);
- BundleDescription[] removals = framework.adaptor.getState().getRemovalPending();
- for (BundleDescription removed : removals) {
- if (removed.getBundleId() == getBundleId()) {
- BundleWiring removedWiring = removed.getBundleWiring();
- if (removedWiring != null && removedWiring != current)
- wirings.add(removedWiring);
- }
- }
- return wirings;
- }
-
- };
- }
- return super.adapt(adapterType);
- }
-
}
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/CoreResolverHookFactory.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/CoreResolverHookFactory.java
index d5dda8e05..90a580112 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/CoreResolverHookFactory.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/CoreResolverHookFactory.java
@@ -18,8 +18,7 @@ import org.eclipse.osgi.util.NLS;
import org.osgi.framework.*;
import org.osgi.framework.hooks.resolver.ResolverHook;
import org.osgi.framework.hooks.resolver.ResolverHookFactory;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.Capability;
+import org.osgi.framework.wiring.*;
/**
* This class encapsulates the delegation to ResolverHooks that are registered with the service
@@ -133,13 +132,13 @@ public class CoreResolverHookFactory implements ResolverHookFactory {
}
}
- public void filterSingletonCollisions(Capability singleton, Collection<Capability> collisionCandidates) {
+ public void filterSingletonCollisions(BundleCapability singleton, Collection<BundleCapability> collisionCandidates) {
if (Debug.DEBUG_HOOKS) {
Debug.println("ResolverHook.filterSingletonCollisions(" + singleton + ", " + collisionCandidates + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
if (hooks.isEmpty())
return;
- collisionCandidates = new ShrinkableCollection<Capability>(collisionCandidates);
+ collisionCandidates = new ShrinkableCollection<BundleCapability>(collisionCandidates);
for (Iterator<HookReference> iHooks = hooks.iterator(); iHooks.hasNext();) {
HookReference hookRef = iHooks.next();
if (hookRef.reference.getBundle() == null) {
@@ -154,20 +153,20 @@ public class CoreResolverHookFactory implements ResolverHookFactory {
}
}
- public void filterMatches(BundleRevision requirer, Collection<Capability> candidates) {
+ public void filterMatches(BundleRequirement requirement, Collection<BundleCapability> candidates) {
if (Debug.DEBUG_HOOKS) {
- Debug.println("ResolverHook.filterMatches(" + requirer + ", " + candidates + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ Debug.println("ResolverHook.filterMatches(" + requirement + ", " + candidates + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
if (hooks.isEmpty())
return;
- candidates = new ShrinkableCollection<Capability>(candidates);
+ candidates = new ShrinkableCollection<BundleCapability>(candidates);
for (Iterator<HookReference> iHooks = hooks.iterator(); iHooks.hasNext();) {
HookReference hookRef = iHooks.next();
if (hookRef.reference.getBundle() == null) {
handleHookException(null, hookRef.hook, "filterMatches", hookRef.reference.getBundle(), hooks, true); //$NON-NLS-1$
} else {
try {
- hookRef.hook.filterMatches(requirer, candidates);
+ hookRef.hook.filterMatches(requirement, candidates);
} catch (Throwable t) {
handleHookException(t, hookRef.hook, "filterMatches", hookRef.reference.getBundle(), hooks, true); //$NON-NLS-1$
}
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/InternalSystemBundle.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/InternalSystemBundle.java
index ad4da2ac6..f19f7657e 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/InternalSystemBundle.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/InternalSystemBundle.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2010 IBM Corporation and others.
+ * Copyright (c) 2003, 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
@@ -401,12 +401,12 @@ public class InternalSystemBundle extends BundleHost implements org.osgi.framewo
@SuppressWarnings("unchecked")
@Override
- public <A> A adapt(Class<A> adapterType) {
+ protected <A> A adapt0(Class<A> adapterType) {
if (FrameworkStartLevel.class.equals(adapterType))
return (A) fsl;
else if (FrameworkWiring.class.equals(adapterType))
return (A) framework.getPackageAdmin();
- return super.adapt(adapterType);
+ return super.adapt0(adapterType);
}
class EquinoxStartLevel implements FrameworkStartLevel {
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WeavingHookConfigurator.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WeavingHookConfigurator.java
index 5f4b42bbe..78b8f44dc 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WeavingHookConfigurator.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WeavingHookConfigurator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010 IBM Corporation and others.
+ * Copyright (c) 2010, 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
@@ -23,8 +23,7 @@ import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegate;
import org.eclipse.osgi.framework.internal.core.Framework;
import org.eclipse.osgi.internal.loader.BundleLoader;
import org.eclipse.osgi.internal.serviceregistry.ServiceRegistry;
-import org.osgi.framework.FrameworkEvent;
-import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.*;
public class WeavingHookConfigurator implements HookConfigurator, ClassLoadingHook, ClassLoadingStatsHook {
private BaseAdaptor adaptor;
@@ -68,7 +67,9 @@ public class WeavingHookConfigurator implements HookConfigurator, ClassLoadingHo
try {
return wovenClass.callHooks();
} catch (Throwable t) {
- adaptor.getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, manager.getBaseData().getBundle(), t);
+ ServiceRegistration<?> errorHook = wovenClass.getErrorHook();
+ Bundle errorBundle = errorHook != null ? errorHook.getReference().getBundle() : manager.getBaseData().getBundle();
+ adaptor.getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, errorBundle, t);
// fail hard with a class loading error
ClassFormatError error = new ClassFormatError("Unexpected error from weaving hook."); //$NON-NLS-1$
error.initCause(t);
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WovenClassImpl.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WovenClassImpl.java
index 9198e8f29..12f2a4b26 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WovenClassImpl.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WovenClassImpl.java
@@ -34,6 +34,7 @@ public final class WovenClassImpl implements WovenClass, HookContext {
private byte[] bytes;
private byte hookFlags = 0;
private Throwable error;
+ private ServiceRegistration<?> errorHook;
private Class<?> clazz;
public WovenClassImpl(String className, byte[] bytes, ProtectionDomain domain, BundleLoader loader, ServiceRegistry registry, Map<ServiceRegistration<?>, Boolean> blacklist) {
@@ -114,7 +115,7 @@ public final class WovenClassImpl implements WovenClass, HookContext {
}
public BundleWiring getBundleWiring() {
- return loader.getLoaderProxy().getBundleDescription().getBundleWiring();
+ return loader.getLoaderProxy().getBundleDescription().getWiring();
}
public void call(final Object hook, ServiceRegistration<?> hookRegistration) throws Exception {
@@ -128,9 +129,11 @@ public final class WovenClassImpl implements WovenClass, HookContext {
((WeavingHook) hook).weave(this);
} catch (WeavingException e) {
error = e;
+ errorHook = hookRegistration;
// do not blacklist on weaving exceptions
} catch (Throwable t) {
error = t; // save the error to fail later
+ errorHook = hookRegistration;
// put the registration on the black list
blackList.put(hookRegistration, Boolean.TRUE);
}
@@ -188,4 +191,8 @@ public final class WovenClassImpl implements WovenClass, HookContext {
public String toString() {
return className;
}
+
+ public ServiceRegistration<?> getErrorHook() {
+ return errorHook;
+ }
}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/AdaptPermission.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/AdaptPermission.java
new file mode 100644
index 000000000..f95c1fe11
--- /dev/null
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/AdaptPermission.java
@@ -0,0 +1,635 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.framework;
+
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
+import java.security.AccessController;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A bundle's authority to adapt an object to a type.
+ *
+ * <p>
+ * {@code AdaptPermission} has one action: {@code adapt}.
+ *
+ * @ThreadSafe
+ * @version $Id: bc4c5d392d2534a7744f6fc00f4665502f82033c $
+ */
+public class AdaptPermission extends BasicPermission {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The action string {@code initiate}.
+ */
+ public final static String ADAPT = "adapt";
+
+ private final static int ACTION_ADAPT = 0x00000001;
+ private final static int ACTION_ALL = ACTION_ADAPT;
+ final static int ACTION_NONE = 0;
+
+ /**
+ * The actions mask.
+ */
+ transient int action_mask;
+
+ /**
+ * The actions in canonical form.
+ *
+ * @serial
+ */
+ private volatile String actions = null;
+
+ /**
+ * The bundle used by this AdaptPermission.
+ */
+ transient final Bundle bundle;
+
+ /**
+ * This holds a Filter matching object used to evaluate the filter in
+ * implies.
+ */
+ transient Filter filter;
+
+ /**
+ * This map holds the properties of the permission, used to match a filter
+ * in implies. This is not initialized until necessary, and then cached in
+ * this object.
+ */
+ private transient volatile Map<String, Object> properties;
+
+ /**
+ * Creates a new granted {@code AdaptPermission} object.
+ *
+ * This constructor must only be used to create a permission that is going
+ * to be checked.
+ * <p>
+ * Examples:
+ *
+ * <pre>
+ * (adaptClass=com.acme.*)
+ * (&amp;(signer=\*,o=ACME,c=US)(adaptClass=com.acme.*))
+ * (signer=\*,o=ACME,c=US)
+ * </pre>
+ *
+ * <p>
+ * When a signer key is used within the filter expression the signer value
+ * must escape the special filter chars ('*', '(', ')').
+ * <p>
+ * The name is specified as a filter expression. The filter gives access to
+ * the following attributes:
+ * <ul>
+ * <li>signer - A Distinguished Name chain used to sign the exporting
+ * bundle. Wildcards in a DN are not matched according to the filter string
+ * rules, but according to the rules defined for a DN chain.</li>
+ * <li>location - The location of the exporting bundle.</li>
+ * <li>id - The bundle ID of the exporting bundle.</li>
+ * <li>name - The symbolic name of the exporting bundle.</li>
+ * <li>adaptClass - The name of the type to which an object can be adapted.</li>
+ * </ul>
+ * Filter attribute names are processed in a case sensitive manner.
+ *
+ * @param filter A filter expression. Filter attribute names are processed
+ * in a case sensitive manner. A special value of {@code "*"} can be
+ * used to match all adaptations.
+ * @param actions {@code adapt}.
+ * @throws IllegalArgumentException If the filter has an invalid syntax.
+ */
+ public AdaptPermission(String filter, String actions) {
+ this(parseFilter(filter), parseActions(actions));
+ }
+
+ /**
+ * Creates a new requested {@code AdaptPermission} object to be used by the
+ * code that must perform {@code checkPermission}. {@code AdaptPermission}
+ * objects created with this constructor cannot be added to an
+ * {@code AdaptPermission} permission collection.
+ *
+ * @param adaptClass The name of the type to which an object can be adapted.
+ * @param adaptableBundle The bundle associated with the object being
+ * adapted.
+ * @param actions {@code adapt}.
+ */
+ public AdaptPermission(String adaptClass, Bundle adaptableBundle,
+ String actions) {
+ super(adaptClass);
+ setTransients(null, parseActions(actions));
+ this.bundle = adaptableBundle;
+ if (adaptClass == null) {
+ throw new NullPointerException("adaptClass must not be null");
+ }
+ if (adaptableBundle == null) {
+ throw new NullPointerException("adaptableBundle must not be null");
+ }
+ }
+
+ /**
+ * Package private constructor used by AdaptPermissionCollection.
+ *
+ * @param filter name filter
+ * @param mask action mask
+ */
+ AdaptPermission(Filter filter, int mask) {
+ super((filter == null) ? "*" : filter.toString());
+ setTransients(filter, mask);
+ this.bundle = null;
+ }
+
+ /**
+ * Called by constructors and when deserialized.
+ *
+ * @param filter Permission's filter or {@code null} for wildcard.
+ * @param mask action mask
+ */
+ private void setTransients(Filter filter, int mask) {
+ this.filter = filter;
+ if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+ throw new IllegalArgumentException("invalid action string");
+ }
+ this.action_mask = mask;
+ }
+
+ /**
+ * Parse action string into action mask.
+ *
+ * @param actions Action string.
+ * @return action mask.
+ */
+ private static int parseActions(String actions) {
+ boolean seencomma = false;
+
+ int mask = ACTION_NONE;
+
+ if (actions == null) {
+ return mask;
+ }
+
+ char[] a = actions.toCharArray();
+
+ int i = a.length - 1;
+ if (i < 0)
+ return mask;
+
+ while (i != -1) {
+ char c;
+
+ // skip whitespace
+ while ((i != -1)
+ && ((c = a[i]) == ' ' || c == '\r' || c == '\n'
+ || c == '\f' || c == '\t'))
+ i--;
+
+ // check for the known strings
+ int matchlen;
+
+ if (i >= 4 && (a[i - 4] == 'a' || a[i - 4] == 'A')
+ && (a[i - 3] == 'd' || a[i - 3] == 'D')
+ && (a[i - 2] == 'a' || a[i - 2] == 'A')
+ && (a[i - 1] == 'p' || a[i - 1] == 'P')
+ && (a[i] == 't' || a[i] == 'T')) {
+ matchlen = 5;
+ mask |= ACTION_ADAPT;
+
+ }
+ else {
+ // parse error
+ throw new IllegalArgumentException("invalid actions: "
+ + actions);
+ }
+
+ // make sure we didn't just match the tail of a word
+ // like "ackbarfadapt". Also, skip to the comma.
+ seencomma = false;
+ while (i >= matchlen && !seencomma) {
+ switch (a[i - matchlen]) {
+ case ',' :
+ seencomma = true;
+ /* FALLTHROUGH */
+ case ' ' :
+ case '\r' :
+ case '\n' :
+ case '\f' :
+ case '\t' :
+ break;
+ default :
+ throw new IllegalArgumentException(
+ "invalid permission: " + actions);
+ }
+ i--;
+ }
+
+ // point i at the location of the comma minus one (or -1).
+ i -= matchlen;
+ }
+
+ if (seencomma) {
+ throw new IllegalArgumentException("invalid actions: " + actions);
+ }
+
+ return mask;
+ }
+
+ /**
+ * Parse filter string into a Filter object.
+ *
+ * @param filterString The filter string to parse.
+ * @return a Filter for this bundle.
+ * @throws IllegalArgumentException If the filter syntax is invalid.
+ */
+ private static Filter parseFilter(String filterString) {
+ filterString = filterString.trim();
+ if (filterString.equals("*")) {
+ return null;
+ }
+ try {
+ return FrameworkUtil.createFilter(filterString);
+ }
+ catch (InvalidSyntaxException e) {
+ IllegalArgumentException iae = new IllegalArgumentException(
+ "invalid filter");
+ iae.initCause(e);
+ throw iae;
+ }
+ }
+
+ /**
+ * Determines if the specified permission is implied by this object.
+ *
+ * <p>
+ * This method checks that the filter of the target is implied by the adapt
+ * class name of this object. The list of {@code AdaptPermission} actions
+ * must either match or allow for the list of the target object to imply the
+ * target {@code AdaptPermission} action.
+ * <p>
+ *
+ * @param p The requested permission.
+ * @return {@code true} if the specified permission is implied by this
+ * object; {@code false} otherwise.
+ */
+ public boolean implies(Permission p) {
+ if (!(p instanceof AdaptPermission)) {
+ return false;
+ }
+ AdaptPermission requested = (AdaptPermission) p;
+ if (bundle != null) {
+ return false;
+ }
+ // if requested permission has a filter, then it is an invalid argument
+ if (requested.filter != null) {
+ return false;
+ }
+ return implies0(requested, ACTION_NONE);
+ }
+
+ /**
+ * Internal implies method. Used by the implies and the permission
+ * collection implies methods.
+ *
+ * @param requested The requested AdaptPermission which has already be
+ * validated as a proper argument. The requested AdaptPermission must
+ * not have a filter expression.
+ * @param effective The effective actions with which to start.
+ * @return {@code true} if the specified permission is implied by this
+ * object; {@code false} otherwise.
+ */
+ boolean implies0(AdaptPermission requested, int effective) {
+ /* check actions first - much faster */
+ effective |= action_mask;
+ final int desired = requested.action_mask;
+ if ((effective & desired) != desired) {
+ return false;
+ }
+ /* Get filter */
+ Filter f = filter;
+ if (f == null) {
+ // it's "*"
+ return true;
+ }
+ return f.matches(requested.getProperties());
+ }
+
+ /**
+ * Returns the canonical string representation of the
+ * {@code AdaptPermission} actions.
+ *
+ * <p>
+ * Always returns present {@code AdaptPermission} actions in the following
+ * order: {@code adapt}.
+ *
+ * @return Canonical string representation of the {@code AdaptPermission}
+ * actions.
+ */
+ public String getActions() {
+ String result = actions;
+ if (result == null) {
+ actions = result = ADAPT;
+ }
+ return result;
+ }
+
+ /**
+ * Returns a new {@code PermissionCollection} object suitable for storing
+ * {@code AdaptPermission} objects.
+ *
+ * @return A new {@code PermissionCollection} object.
+ */
+ public PermissionCollection newPermissionCollection() {
+ return new AdaptPermissionCollection();
+ }
+
+ /**
+ * Determines the equality of two {@code AdaptPermission} objects.
+ *
+ * This method checks that specified permission has the same name and
+ * {@code AdaptPermission} actions as this {@code AdaptPermission} object.
+ *
+ * @param obj The object to test for equality with this
+ * {@code AdaptPermission} object.
+ * @return {@code true} if {@code obj} is a {@code AdaptPermission}, and has
+ * the same name and actions as this {@code AdaptPermission} object;
+ * {@code false} otherwise.
+ */
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+
+ if (!(obj instanceof AdaptPermission)) {
+ return false;
+ }
+
+ AdaptPermission cp = (AdaptPermission) obj;
+
+ return (action_mask == cp.action_mask)
+ && getName().equals(cp.getName())
+ && ((bundle == cp.bundle) || ((bundle != null) && bundle
+ .equals(cp.bundle)));
+ }
+
+ /**
+ * Returns the hash code value for this object.
+ *
+ * @return A hash code value for this object.
+ */
+ public int hashCode() {
+ int h = 31 * 17 + getName().hashCode();
+ h = 31 * h + getActions().hashCode();
+ if (bundle != null) {
+ h = 31 * h + bundle.hashCode();
+ }
+ return h;
+ }
+
+ /**
+ * WriteObject is called to save the state of this permission object to a
+ * stream. The actions are serialized, and the superclass takes care of the
+ * name.
+ */
+ private synchronized void writeObject(java.io.ObjectOutputStream s)
+ throws IOException {
+ if (bundle != null) {
+ throw new NotSerializableException("cannot serialize");
+ }
+ // Write out the actions. The superclass takes care of the name
+ // call getActions to make sure actions field is initialized
+ if (actions == null)
+ getActions();
+ s.defaultWriteObject();
+ }
+
+ /**
+ * readObject is called to restore the state of this permission from a
+ * stream.
+ */
+ private synchronized void readObject(java.io.ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ // Read in the action, then initialize the rest
+ s.defaultReadObject();
+ setTransients(parseFilter(getName()), parseActions(actions));
+ }
+
+ /**
+ * Called by {@code <@link AdaptPermission#implies(Permission)>}. This
+ * method is only called on a requested permission which cannot have a
+ * filter set.
+ *
+ * @return a map of properties for this permission.
+ */
+ private Map<String, Object> getProperties() {
+ Map<String, Object> result = properties;
+ if (result != null) {
+ return result;
+ }
+ final Map<String, Object> map = new HashMap<String, Object>(5);
+ map.put("adaptClass", getName());
+ if (bundle != null) {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ map.put("id", new Long(bundle.getBundleId()));
+ map.put("location", bundle.getLocation());
+ String name = bundle.getSymbolicName();
+ if (name != null) {
+ map.put("name", name);
+ }
+ SignerProperty signer = new SignerProperty(bundle);
+ if (signer.isBundleSigned()) {
+ map.put("signer", signer);
+ }
+ return null;
+ }
+ });
+ }
+ return properties = map;
+ }
+}
+
+/**
+ * Stores a set of {@code AdaptPermission} permissions.
+ *
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.PermissionCollection
+ */
+
+final class AdaptPermissionCollection extends PermissionCollection {
+ static final long serialVersionUID = -3350758995234427603L;
+ /**
+ * Collection of permissions.
+ *
+ * @serial
+ * @GuardedBy this
+ */
+ private Map<String, AdaptPermission> permissions;
+
+ /**
+ * Boolean saying if "*" is in the collection.
+ *
+ * @serial
+ * @GuardedBy this
+ */
+ private boolean all_allowed;
+
+ /**
+ * Create an empty AdaptPermissions object.
+ */
+ public AdaptPermissionCollection() {
+ permissions = new HashMap<String, AdaptPermission>();
+ all_allowed = false;
+ }
+
+ /**
+ * Adds a permission to this permission collection.
+ *
+ * @param permission The {@code AdaptPermission} object to add.
+ * @throws IllegalArgumentException If the specified permission is not a
+ * {@code AdaptPermission} instance or was constructed with a Bundle
+ * object.
+ * @throws SecurityException If this {@code AdaptPermissionCollection}
+ * object has been marked read-only.
+ */
+ public void add(final Permission permission) {
+ if (!(permission instanceof AdaptPermission)) {
+ throw new IllegalArgumentException("invalid permission: "
+ + permission);
+ }
+ if (isReadOnly()) {
+ throw new SecurityException("attempt to add a Permission to a "
+ + "readonly PermissionCollection");
+ }
+
+ final AdaptPermission ap = (AdaptPermission) permission;
+ if (ap.bundle != null) {
+ throw new IllegalArgumentException("cannot add to collection: "
+ + ap);
+ }
+
+ final String name = ap.getName();
+ synchronized (this) {
+ Map<String, AdaptPermission> pc = permissions;
+ final AdaptPermission existing = pc.get(name);
+ if (existing != null) {
+ final int oldMask = existing.action_mask;
+ final int newMask = ap.action_mask;
+ if (oldMask != newMask) {
+ pc.put(name, new AdaptPermission(existing.filter, oldMask
+ | newMask));
+
+ }
+ }
+ else {
+ pc.put(name, ap);
+ }
+
+ if (!all_allowed) {
+ if (name.equals("*")) {
+ all_allowed = true;
+ }
+ }
+ }
+ }
+
+ /**
+ * Determines if the specified permissions implies the permissions expressed
+ * in {@code permission}.
+ *
+ * @param permission The Permission object to compare with this
+ * {@code AdaptPermission} object.
+ * @return {@code true} if {@code permission} is a proper subset of a
+ * permission in the set; {@code false} otherwise.
+ */
+ public boolean implies(final Permission permission) {
+ if (!(permission instanceof AdaptPermission)) {
+ return false;
+ }
+ final AdaptPermission requested = (AdaptPermission) permission;
+ /* if requested permission has a filter, then it is an invalid argument */
+ if (requested.filter != null) {
+ return false;
+ }
+
+ int effective = AdaptPermission.ACTION_NONE;
+
+ Collection<AdaptPermission> perms;
+ synchronized (this) {
+ Map<String, AdaptPermission> pc = permissions;
+ /* short circuit if the "*" Permission was added */
+ if (all_allowed) {
+ AdaptPermission ap = pc.get("*");
+ if (ap != null) {
+ effective |= ap.action_mask;
+ final int desired = requested.action_mask;
+ if ((effective & desired) == desired) {
+ return true;
+ }
+ }
+ }
+ perms = pc.values();
+ }
+ /* iterate one by one over filteredPermissions */
+ for (AdaptPermission perm : perms) {
+ if (perm.implies0(requested, effective)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns an enumeration of all {@code AdaptPermission} objects in the
+ * container.
+ *
+ * @return Enumeration of all {@code AdaptPermission} objects.
+ */
+ public synchronized Enumeration<Permission> elements() {
+ List<Permission> all = new ArrayList<Permission>(permissions.values());
+ return Collections.enumeration(all);
+ }
+
+ /* serialization logic */
+ private static final ObjectStreamField[] serialPersistentFields = {
+ new ObjectStreamField("permissions", HashMap.class),
+ new ObjectStreamField("all_allowed", Boolean.TYPE) };
+
+ private synchronized void writeObject(ObjectOutputStream out)
+ throws IOException {
+ ObjectOutputStream.PutField pfields = out.putFields();
+ pfields.put("permissions", permissions);
+ pfields.put("all_allowed", all_allowed);
+ out.writeFields();
+ }
+
+ private synchronized void readObject(java.io.ObjectInputStream in)
+ throws IOException, ClassNotFoundException {
+ ObjectInputStream.GetField gfields = in.readFields();
+ permissions = (HashMap<String, AdaptPermission>) gfields.get(
+ "permissions", null);
+ all_allowed = gfields.get("all_allowed", false);
+ }
+}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/Bundle.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/Bundle.java
index 435660545..8f4002c9d 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/Bundle.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/Bundle.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,8 @@ import java.util.Enumeration;
import java.util.List;
import java.util.Map;
+import org.osgi.framework.wiring.FrameworkWiring;
+
/**
* An installed bundle in the Framework.
*
@@ -74,7 +76,7 @@ import java.util.Map;
*
* @ThreadSafe
* @noimplement
- * @version $Id: 2b49f64e7a633cefc70b438ec9e1f966ff4f8130 $
+ * @version $Id: 239108e8d54ff493587b9cdfe1688bdefc5a714c $
*/
public interface Bundle extends Comparable<Bundle> {
/**
@@ -257,8 +259,7 @@ public interface Bundle extends Comparable<Bundle> {
* If this bundle's state is {@code UNINSTALLED} then an
* {@code IllegalStateException} is thrown.
* <p>
- * If the Framework implements the optional Start Level service and the
- * current start level is less than this bundle's start level:
+ * If the current start level is less than this bundle's start level:
* <ul>
* <li>If the {@link #START_TRANSIENT} option is set, then a
* {@code BundleException} is thrown indicating this bundle cannot be
@@ -512,8 +513,9 @@ public interface Bundle extends Comparable<Bundle> {
* <p>
* If this bundle has exported any packages that are imported by another
* bundle, these packages must remain exported until the
- * {@code PackageAdmin.refreshPackages} method has been has been called or
- * the Framework is relaunched.
+ * {@link FrameworkWiring#refreshBundles(java.util.Collection, FrameworkListener...)
+ * FrameworkWiring.refreshBundles} method has been has been called or the
+ * Framework is relaunched.
*
* <p>
* The following steps are required to update a bundle:
@@ -624,8 +626,9 @@ public interface Bundle extends Comparable<Bundle> {
* <p>
* If this bundle has exported any packages, the Framework must continue to
* make these packages available to their importing bundles until the
- * {@code PackageAdmin.refreshPackages} method has been called or the
- * Framework is relaunched.
+ * {@link FrameworkWiring#refreshBundles(java.util.Collection, FrameworkListener...)
+ * FrameworkWiring.refreshBundles} method has been called or the Framework
+ * is relaunched.
*
* <p>
* The following steps are required to uninstall a bundle:
@@ -1075,7 +1078,7 @@ public interface Bundle extends Comparable<Bundle> {
* This method is intended to be used to obtain configuration, setup,
* localization and other information from this bundle. This method takes
* into account that the &quot;contents&quot; of this bundle can be extended
- * with fragments. This &quot;bundle space&quot; is not a namespace with
+ * with fragments. This &quot;bundle space&quot; is not a name space with
* unique members; the same entry name can be present multiple times. This
* method therefore returns an enumeration of URL objects. These URLs can
* come from different JARs but have the same path name. This method can
@@ -1117,15 +1120,15 @@ public interface Bundle extends Comparable<Bundle> {
* files.
* @param recurse If {@code true}, recurse into subdirectories. Otherwise
* only return entries from the specified path.
- * @return An enumeration of URL objects for each matching entry, or {@code
- * null} if no matching entry could not be found or if the caller
- * does not have the appropriate {@code
- * AdminPermission[this,RESOURCE]}, and the Java Runtime Environment
- * supports permissions. The URLs are sorted such that entries from
- * this bundle are returned first followed by the entries from
- * attached fragments in attachment order. If this bundle is a
- * fragment, then only matching entries in this fragment are
- * returned.
+ * @return An enumeration of URL objects for each matching entry, or
+ * {@code null} if no matching entry could not be found or if the
+ * caller does not have the appropriate
+ * {@code AdminPermission[this,RESOURCE]}, and the Java Runtime
+ * Environment supports permissions. The URLs are sorted such that
+ * entries from this bundle are returned first followed by the
+ * entries from attached fragments in attachment order. If this
+ * bundle is a fragment, then only matching entries in this fragment
+ * are returned.
* @throws IllegalStateException If this bundle has been uninstalled.
* @since 1.3
*/
@@ -1204,6 +1207,9 @@ public interface Bundle extends Comparable<Bundle> {
* @return The object, of the specified type, to which this bundle has been
* adapted or {@code null} if this bundle cannot be adapted to the
* specified type.
+ * @throws SecurityException If the caller does not have the appropriate
+ * {@code AdaptPermission[type,this,ADAPT]}, and the Java Runtime
+ * Environment supports permissions.
* @since 1.6
*/
<A> A adapt(Class<A> type);
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/CapabilityPermission.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/CapabilityPermission.java
index f1b5d007c..bcac7906c 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/CapabilityPermission.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/CapabilityPermission.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,7 +47,7 @@ import java.util.Set;
* </ul>
*
* @ThreadSafe
- * @version $Id: ad31023478478ecb577e11eb753875cfff57de1b $
+ * @version $Id: bab1ac06b46613f6cff39b291295d8b3e51d58ce $
* @since 1.6
*/
@@ -133,7 +133,7 @@ public final class CapabilityPermission extends BasicPermission {
* <li>location - The location of the bundle providing the capability.</li>
* <li>id - The bundle ID of the bundle providing the capability.</li>
* <li>name - The symbolic name of the bundle providing the capability.</li>
- * <li>capability.namespace - The namespace of the required capability.</li>
+ * <li>capability.namespace - The name space of the required capability.</li>
* </ul>
* Since the above attribute names may conflict with attribute names of a
* capability, you can prefix an attribute name with '@' in the filter
@@ -146,9 +146,9 @@ public final class CapabilityPermission extends BasicPermission {
* {@code require} permission allows the owner of this permission to require
* a capability matching the attributes. The {@code provide} permission
* allows the bundle to provide a capability in the specified capability
- * namespace.
+ * name space.
*
- * @param name The capability namespace or a filter over the attributes.
+ * @param name The capability name space or a filter over the attributes.
* @param actions {@code require},{@code provide} (canonical order)
* @throws IllegalArgumentException If the specified name is a filter
* expression and either the specified action is not {@code require}
@@ -170,7 +170,7 @@ public final class CapabilityPermission extends BasicPermission {
* constructor cannot be added to a {@code CapabilityPermission} permission
* collection.
*
- * @param namespace The requested capability namespace.
+ * @param namespace The requested capability name space.
* @param attributes The requested capability attributes.
* @param providingBundle The bundle providing the requested capability.
* @param actions The action {@code require}.
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/Constants.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/Constants.java
index c7784683a..b71a12dfd 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/Constants.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/Constants.java
@@ -28,7 +28,7 @@ import org.osgi.framework.launch.Framework;
*
* @since 1.1
* @noimplement
- * @version $Id: dfc898e60b6825d9b1dada682a6aecc858daa7f4 $
+ * @version $Id: 517c954ed7d34d2ee762933466f69fa03db7cd37 $
*/
public interface Constants {
@@ -1276,7 +1276,7 @@ public interface Constants {
* persists across multiple Framework invocations.
*
* <p>
- * By convention, every bundle has its own unique namespace, starting with
+ * By convention, every bundle has its own unique name space, starting with
* the bundle's identifier (see {@link Bundle#getBundleId}) and followed by
* a dot (.). A bundle may use this as the prefix of the persistent
* identifiers for the services it registers.
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkEvent.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkEvent.java
index 2cc72cfe9..d30969978 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkEvent.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/FrameworkEvent.java
@@ -18,6 +18,9 @@ package org.osgi.framework;
import java.util.EventObject;
+import org.osgi.framework.startlevel.FrameworkStartLevel;
+import org.osgi.framework.wiring.FrameworkWiring;
+
/**
* A general event from the Framework.
*
@@ -32,7 +35,7 @@ import java.util.EventObject;
*
* @Immutable
* @see FrameworkListener
- * @version $Id: 897075a0bc075c0bb89e77d113f05ca84406a073 $
+ * @version $Id: e05c6ffd542fa432835961882bf6b15b0620ffb6 $
*/
public class FrameworkEvent extends EventObject {
@@ -61,7 +64,7 @@ public class FrameworkEvent extends EventObject {
* has reached the initial start level. The source of this event is the
* System Bundle.
*
- * @see "The Start Level Service"
+ * @see "The Start Level Specification"
*/
public final static int STARTED = 0x00000001;
@@ -74,20 +77,21 @@ public class FrameworkEvent extends EventObject {
public final static int ERROR = 0x00000002;
/**
- * A PackageAdmin.refreshPackage operation has completed.
+ * A FrameworkWiring.refreshBundles operation has completed.
*
* <p>
- * This event is fired when the Framework has completed the refresh packages
- * operation initiated by a call to the PackageAdmin.refreshPackages method.
- * The source of this event is the System Bundle.
+ * This event is fired when the Framework has completed the refresh bundles
+ * operation initiated by a call to the FrameworkWiring.refreshBundles
+ * method. The source of this event is the System Bundle.
*
* @since 1.2
- * @see "{@code PackageAdmin.refreshPackages}"
+ * @see FrameworkWiring#refreshBundles(java.util.Collection,
+ * FrameworkListener...)
*/
public final static int PACKAGES_REFRESHED = 0x00000004;
/**
- * A StartLevel.setStartLevel operation has completed.
+ * A FrameworkStartLevel.setStartLevel operation has completed.
*
* <p>
* This event is fired when the Framework has completed changing the active
@@ -95,7 +99,7 @@ public class FrameworkEvent extends EventObject {
* The source of this event is the System Bundle.
*
* @since 1.2
- * @see "The Start Level Service"
+ * @see FrameworkStartLevel#setStartLevel(int, FrameworkListener...)
*/
public final static int STARTLEVEL_CHANGED = 0x00000008;
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/ServiceFactory.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/ServiceFactory.java
index df72801b2..6383b22bb 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/ServiceFactory.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/ServiceFactory.java
@@ -45,7 +45,7 @@ package org.osgi.framework;
* @param <S> Type of Service
* @see BundleContext#getService
* @ThreadSafe
- * @version $Id: 8b6ee170eba398d06389cded7d4f154ba2f89098 $
+ * @version $Id: 94cd1a0127aaad9beb484f557342a8fbd0be2322 $
*/
public interface ServiceFactory<S> {
@@ -59,12 +59,20 @@ public interface ServiceFactory<S> {
* factory can then return a specific service object for each bundle.
*
* <p>
- * The Framework must check that the returned service object is valid. It
- * must not be {@code null} and it must be an {@code instanceof} all the
- * classes named when the service was registered. If this method throws an
- * exception or will be recursively called for the specified bundle or if
- * the returned service object is not valid, then {@code null} is returned
- * to the bundle.
+ * The Framework must check that the returned service object is valid. If
+ * the returned service object is {@code null} or is not an
+ * {@code instanceof} all the classes named when the service was registered,
+ * a framework event of type {@link FrameworkEvent#ERROR} is fired
+ * containing a service exception of type
+ * {@link ServiceException#FACTORY_ERROR} and {@code null} is returned to
+ * the bundle. If this method throws an exception, a framework event of type
+ * {@link FrameworkEvent#ERROR} is fired containing a service exception of
+ * type {@link ServiceException#FACTORY_EXCEPTION} with the thrown exception
+ * as the cause and {@code null} is returned to the bundle. If this method
+ * is recursively called for the specified bundle, a framework event of type
+ * {@link FrameworkEvent#ERROR} is fired containing a service exception of
+ * type {@link ServiceException#FACTORY_RECURSION} and {@code null} is
+ * returned to the bundle.
*
* <p>
* The Framework caches the valid service object and will return the same
@@ -88,6 +96,12 @@ public interface ServiceFactory<S> {
* The Framework invokes this method when a service has been released by a
* bundle. The service object may then be destroyed.
*
+ * <p>
+ * If this method throws an exception, a framework event of type
+ * {@link FrameworkEvent#ERROR} is fired containing a service exception of
+ * type {@link ServiceException#FACTORY_EXCEPTION} with the thrown exception
+ * as the cause.
+ *
* @param bundle The bundle releasing the service.
* @param registration The {@code ServiceRegistration} object for the
* service being released.
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/resolver/ResolverHook.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/resolver/ResolverHook.java
index 6e2ecc8ee..bbde7ffb5 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/resolver/ResolverHook.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/resolver/ResolverHook.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,95 +19,113 @@ package org.osgi.framework.hooks.resolver;
import java.util.Collection;
import org.osgi.framework.Bundle;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.Capability;
import org.osgi.framework.wiring.FrameworkWiring;
/**
- * OSGi Framework Resolver Hook instances are obtained from the OSGi {@link ResolverHookFactory
- * Framework Resolver Hook Factory} service.
+ * OSGi Framework Resolver Hook instances are obtained from the OSGi
+ * {@link ResolverHookFactory Framework Resolver Hook Factory} service.
*
* <p>
- * A Resolver Hook instance is called by the framework during a resolve
- * process. A resolver hook may influence the outcome of a resolve process by removing entries
- * from shrinkable collections that are passed to the hook during a resolve process. A shrinkable
- * collection is a {@code Collection} that supports all remove operations. Any other attempts to modify
- * a shrinkable collection will result in an {@code UnsupportedOperationException} being thrown.
+ * A Resolver Hook instance is called by the framework during a resolve process.
+ * A resolver hook may influence the outcome of a resolve process by removing
+ * entries from shrinkable collections that are passed to the hook during a
+ * resolve process. A shrinkable collection is a {@code Collection} that
+ * supports all remove operations. Any other attempts to modify a shrinkable
+ * collection will result in an {@code UnsupportedOperationException} being
+ * thrown.
*
* <p>
- * The following steps outline the way a framework uses the resolver hooks during a resolve
- * process.
+ * The following steps outline the way a framework uses the resolver hooks
+ * during a resolve process.
* <ol>
- * <li> Collect a snapshot of registered resolver hook factories that will be called during the
- * current resolve process. Any hook factories registered after the snapshot is taken must not be called
- * during the current resolve process. A resolver hook factory contained in the snapshot may become
- * unregistered during the resolve process. The framework should handle this and stop calling
- * the resolver hook instance provided by the unregistered hook factory for the remainder of the resolve process.</li>
- * <li> For each registered hook factory call the {@link ResolverHookFactory#begin(Collection)} method to inform the
- * hooks about a resolve process beginning and to obtain a Resolver Hook instance that will be used for the duration
- * of the resolve process.</li>
- * <li> Determine the collection of unresolved bundle revisions that may be considered for resolution during
- * the current resolution process and place each of the bundle revisions in a shrinkable collection
- * <b>{@code R}</b>. For each resolver hook call the {@link #filterResolvable(Collection)} method with the
- * shrinkable collection <b>{@code R}</b>.</li>
- * <li> The shrinkable collection <b>{@code R}</b> now contains all the unresolved bundle revisions that may end up
- * as resolved at the end of the current resolve process. Any other bundle revisions that
- * got removed from the shrinkable collection <b>{@code R}</b> must not end up as resolved at the end
- * of the current resolve process.</li>
- * <li> For each bundle revision {@code B} left in the shrinkable collection <b>{@code R}</b> that represents a
- * singleton bundle do the following:
- * <p>
- * Determine the collection of available capabilities that have a name space of
- * {@link Capability#BUNDLE_CAPABILITY osgi.bundle}, are singletons, and have the same
- * symbolic name as the singleton bundle revision <b>{@code B}</b> and place each of the matching
- * capabilities into a shrinkable collection <b>{@code S}</b>.
-
- * Remove the {@link Capability#BUNDLE_CAPABILITY osgi.bundle} capability provided by
- * bundle revision <b>{@code B}</b> from shrinkable collection <b>{@code S}</b>. A singleton bundle
- * cannot collide with itself.
- *
- * For each resovler hook call the {@link #filterSingletonCollisions(Capability, Collection)}
- * with the {@link Capability#BUNDLE_CAPABILITY osgi.bundle} capability provided by bundle revision
- * <b>{@code B}</b> and the shrinkable collection <b>{@code S}</b>
- *
- * The shrinkable collection <b>{@code S}</b> now contains all singleton {@link Capability#BUNDLE_CAPABILITY
- * osgi.bundle} capabilities that can influence the ability of bundle revision <b>{@code B}</b> to resolve.
- * </p>
- * </li>
- * <li> During a resolve process a framework is free to attempt to resolve any or all bundles contained in
- * shrinkable collection <b>{@code R}</b>. For each bundle revision <b>{@code B}</b> left in the shrinkable collection
- * <b>{@code R}</b> which the framework attempts to resolve the following steps must be followed:
- * <p>
- * For each requirement <b>{@code T}</b> specified by bundle revision <b>{@code B}</b> determine the
- * collection of capabilities that satisfy (or match) the requirement and place each matching capability into
- * a shrinkable collection <b>{@code C}</b>. A capability is considered to match a particular requirement
- * if its attributes satisfy a specified requirement and the requirer bundle has permission to access the
- * capability.
+ * <li>Collect a snapshot of registered resolver hook factories that will be
+ * called during the current resolve process. Any hook factories registered
+ * after the snapshot is taken must not be called during the current resolve
+ * process. A resolver hook factory contained in the snapshot may become
+ * unregistered during the resolve process. The framework should handle this and
+ * stop calling the resolver hook instance provided by the unregistered hook
+ * factory and the current resolve process must fail. If possible, an exception
+ * must be thrown to the caller of the API which triggered the resolve process.
+ * In cases where the the caller is not available a framework event of type
+ * error should be fired.</li>
+ * <li>For each registered hook factory call the
+ * {@link ResolverHookFactory#begin(Collection)} method to inform the hooks
+ * about a resolve process beginning and to obtain a Resolver Hook instance that
+ * will be used for the duration of the resolve process.</li>
+ * <li>Determine the collection of unresolved bundle revisions that may be
+ * considered for resolution during the current resolution process and place
+ * each of the bundle revisions in a shrinkable collection {@code R}. For each
+ * resolver hook call the {@link #filterResolvable(Collection)} method with the
+ * shrinkable collection {@code R}.</li>
+ * <li>The shrinkable collection {@code R} now contains all the unresolved
+ * bundle revisions that may end up as resolved at the end of the current
+ * resolve process. Any other bundle revisions that got removed from the
+ * shrinkable collection {@code R} must not end up as resolved at the end of the
+ * current resolve process.</li>
+ * <li>For each bundle revision {@code B} left in the shrinkable collection
+ * {@code R} that represents a singleton bundle do the following:<br/>
+ * Determine the collection of available capabilities that have a name space of
+ * {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle}, are singletons,
+ * and have the same symbolic name as the singleton bundle revision {@code B}
+ * and place each of the matching capabilities into a shrinkable collection
+ * {@code S}.
*
- * For each resolver hook call the {@link #filterMatches(BundleRevision, Collection)} with the
- * bundle revision <b>{@code B}</b> and the shrinkable collection <b>{@code C}</b>.
- *
- * The shrinkable collection <b>{@code C}</b> now contains all the capabilities that may be used to
- * satisfy the requirement <b>{@code T}</b>. Any other capabilities that got removed from the
- * shrinkable collection <b>{@code C}</b> must not be used to satisfy requirement <b>{@code T}</b>.
- * </p>
- * </li>
- * <li> For each resolver hook call the {@link #end()} method to inform the hooks about a resolve
- * process ending.</li>
+ * Remove the {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle}
+ * capability provided by bundle revision {@code B} from shrinkable collection
+ * {@code S}. A singleton bundle cannot collide with itself.
+ *
+ * For each resolver hook call the
+ * {@link #filterSingletonCollisions(BundleCapability, Collection)} with the
+ * {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle} capability
+ * provided by bundle revision {@code B} and the shrinkable collection {@code S}
+ *
+ * The shrinkable collection {@code S} now contains all singleton
+ * {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle} capabilities that
+ * can influence the ability of bundle revision {@code B} to resolve.</li>
+ * <li>During a resolve process a framework is free to attempt to resolve any or
+ * all bundles contained in shrinkable collection {@code R}. For each bundle
+ * revision {@code B} left in the shrinkable collection {@code R} which the
+ * framework attempts to resolve the following steps must be followed:
+ * <p/>
+ * For each requirement {@code T} specified by bundle revision {@code B}
+ * determine the collection of capabilities that satisfy (or match) the
+ * requirement and place each matching capability into a shrinkable collection
+ * {@code C}. A capability is considered to match a particular requirement if
+ * its attributes satisfy a specified requirement and the requirer bundle has
+ * permission to access the capability.
+ *
+ * <p/>
+ * For each resolver hook call the
+ * {@link #filterMatches(BundleRequirement, Collection)} with the requirement
+ * {@code T} and the shrinkable collection {@code C}.
+ *
+ * <p/>
+ * The shrinkable collection {@code C} now contains all the capabilities that
+ * may be used to satisfy the requirement {@code T}. Any other capabilities that
+ * got removed from the shrinkable collection {@code C} must not be used to
+ * satisfy requirement {@code T}.</li>
+ * <li>For each resolver hook call the {@link #end()} method to inform the hooks
+ * about a resolve process ending.</li>
* </ol>
- * In all cases, the order in which the resolver hooks are called is the reverse compareTo ordering of
- * their Service References. That is, the service with the highest ranking number must be called first.
- * In cases where a shrinkable collection becomes empty the framework is required to call the
- * remaining registered hooks.
+ * In all cases, the order in which the resolver hooks are called is the reverse
+ * compareTo ordering of their Service References. That is, the service with the
+ * highest ranking number must be called first. In cases where a shrinkable
+ * collection becomes empty the framework is required to call the remaining
+ * registered hooks.
* <p>
- * Resolver hooks are low level. Implementations of the resolver hook must be careful not to create an unresolvable state which
- * is very hard for a developer or a provisioner to diagnose. Resolver hooks also must not be allowed to start another synchronous
- * resolve process (e.g. by calling {@link Bundle#start()} or {@link FrameworkWiring#resolveBundles(Collection)}).
- * The framework must detect this and throw an {@link IllegalStateException}.
+ * Resolver hooks are low level. Implementations of the resolver hook must be
+ * careful not to create an unresolvable state which is very hard for a
+ * developer or a provisioner to diagnose. Resolver hooks also must not be
+ * allowed to start another synchronous resolve process (e.g. by calling
+ * {@link Bundle#start()} or {@link FrameworkWiring#resolveBundles(Collection)}
+ * ). The framework must detect this and throw an {@link IllegalStateException}.
*
* @see ResolverHookFactory
- * @ThreadSafe
- * @version $Id: abc1f4bb4fd57b8bb41855b1282fe22cb13a9654 $
+ * @NotThreadSafe
+ * @version $Id: ea23400257d780706250f8825ec886aaebb0e5d8 $
*/
public interface ResolverHook {
/**
@@ -123,48 +141,52 @@ public interface ResolverHook {
void filterResolvable(Collection<BundleRevision> candidates);
/**
- * Filter singleton collisions hook method. This method is called during the resolve process
- * for the specified singleton. The specified singleton represents a singleton capability
- * and the specified collection represent a collection of singleton capabilities which are
- * considered collision candidates. The singleton capability and the collection of collision
+ * Filter singleton collisions hook method. This method is called during the
+ * resolve process for the specified singleton. The specified singleton
+ * represents a singleton capability and the specified collection represent
+ * a collection of singleton capabilities which are considered collision
+ * candidates. The singleton capability and the collection of collision
* candidates must all use the same name space.
* <p>
- * Currently only capabilities with the name space of {@link Capability#BUNDLE_CAPABILITY
- * osgi.bundle} can be singletons. In that case all the collision candidates
- * have the name space of {@link Capability#BUNDLE_CAPABILITY osgi.bundle}, are singletons,
- * and have the same symbolic name as the specified singleton capability.
+ * Currently only capabilities with the name space of
+ * {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle} can be
+ * singletons. In that case all the collision candidates have the name space
+ * of {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle}, are
+ * singletons, and have the same symbolic name as the specified singleton
+ * capability.
* <p>
- * In the future, capabilities in other name spaces may support the singleton concept.
- * Hook implementations should be prepared to receive calls to this method for
- * capabilities in name spaces other than {@link Capability#BUNDLE_CAPABILITY
- * osgi.bundle}.
+ * In the future, capabilities in other name spaces may support the
+ * singleton concept. Hook implementations should be prepared to receive
+ * calls to this method for capabilities in name spaces other than
+ * {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle}.
* <p>
- * This method can filter the list of collision candidates by removing potential collisions.
- * Removing a collision candidate will allow the specified singleton to resolve regardless of
- * the resolution state of the removed collision candidate.
+ * This method can filter the list of collision candidates by removing
+ * potential collisions. Removing a collision candidate will allow the
+ * specified singleton to resolve regardless of the resolution state of the
+ * removed collision candidate.
*
* @param singleton the singleton involved in a resolve process
* @param collisionCandidates a collection of singleton collision candidates
*/
- void filterSingletonCollisions(Capability singleton, Collection<Capability> collisionCandidates);
+ void filterSingletonCollisions(BundleCapability singleton, Collection<BundleCapability> collisionCandidates);
/**
* Filter matches hook method. This method is called during the resolve process for the
- * specified requirer. The collection of candidates match a requirement for the requirer.
+ * specified requirement. The collection of candidates match the specified requirement.
* This method can filter the collection of matching candidates by removing candidates from
* the collection. Removing a candidate will prevent the resolve process from choosing the
- * removed candidate to satisfy a requirement for the requirer.
+ * removed candidate to satisfy the requirement.
* <p>
* All of the candidates will have the same name space and will
- * match a requirement of the requirer.
+ * match the specified requirement.
* <p>
* If the Java Runtime Environment supports permissions then the collection of
* candidates will only contain candidates for which the requirer has permission to
* access.
- * @param requirer the bundle revision which contains a requirement
- * @param candidates a collection of candidates that match a requirement of the requirer
+ * @param requirement the requirement to filter candidates for
+ * @param candidates a collection of candidates that match the requirement
*/
- void filterMatches(BundleRevision requirer, Collection<Capability> candidates);
+ void filterMatches(BundleRequirement requirement, Collection<BundleCapability> candidates);
/**
* This method is called once at the end of the resolve process.
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/service/ListenerHook.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/service/ListenerHook.java
index 48538686f..bdac7b590 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/service/ListenerHook.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/service/ListenerHook.java
@@ -28,7 +28,7 @@ import org.osgi.framework.BundleContext;
* addition and removal.
*
* @ThreadSafe
- * @version $Id: c64053251939f402bb35b6a69fc3009888420872 $
+ * @version $Id: c1687e95e568589cf3e6d927b7d372c9f88c5d16 $
*/
public interface ListenerHook {
@@ -67,6 +67,7 @@ public interface ListenerHook {
* which added the Service Listener and the filter with which it was added.
*
* @ThreadSafe
+ * @noimplement
*/
public interface ListenerInfo {
/**
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/weaving/WovenClass.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/weaving/WovenClass.java
index 58cf64f2e..34aa6d2f4 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/weaving/WovenClass.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/hooks/weaving/WovenClass.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@ import org.osgi.framework.wiring.BundleWiring;
*
* @NotThreadSafe
* @noimplement
- * @version $Id: f54547066bd0632e85242cac434a6bb8a759dff6 $
+ * @version $Id: c689a4c27dc39af1bf5f51338f1a8eaca1dddc1a $
*/
public interface WovenClass {
@@ -52,6 +52,9 @@ public interface WovenClass {
*
* @return The bytes to be used to define the
* {@link WovenClass#getClassName() named} class.
+ * @throws SecurityException If the caller does not have
+ * {@code AdminPermission[bundle,WEAVE]} and the Java runtime
+ * environment supports permissions.
*/
public byte[] getBytes();
@@ -75,6 +78,9 @@ public interface WovenClass {
* @throws NullPointerException If newBytes is {@code null}.
* @throws IllegalStateException If weaving is {@link #isWeavingComplete()
* complete}.
+ * @throws SecurityException If the caller does not have
+ * {@code AdminPermission[bundle,WEAVE]} and the Java runtime
+ * environment supports permissions.
*/
public void setBytes(byte[] newBytes);
@@ -90,6 +96,10 @@ public interface WovenClass {
* After weaving is {@link #isWeavingComplete() complete}, this object
* becomes effectively immutable and the returned list will be unmodifiable.
*
+ * <p>
+ * If the Java runtime environment supports permissions, the caller must
+ * have {@code AdminPermission[bundle,WEAVE]} to modify the returned list.
+ *
* @return A list containing zero or more dynamic import package
* descriptions to add to the bundle wiring for this woven class.
* This list must throw {@code IllegalArgumentException} if a
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/Framework.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/Framework.java
index 2e9083bb1..672db449b 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/Framework.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/launch/Framework.java
@@ -35,7 +35,7 @@ import org.osgi.framework.FrameworkEvent;
*
* @ThreadSafe
* @noimplement
- * @version $Id: e403b10bdb5ae9b9e42651ce04003923beacc3d9 $
+ * @version $Id: 2be857d06f3605a04f701b59f11e127c0f8940dc $
*/
public interface Framework extends Bundle {
@@ -51,8 +51,7 @@ public interface Framework extends Bundle {
* <li>Have event handling enabled.</li>
* <li>Have reified Bundle objects for all installed bundles.</li>
* <li>Have registered any framework services. For example,
- * {@code PackageAdmin}, {@code ConditionalPermissionAdmin},
- * {@code StartLevel}.</li>
+ * {@code ConditionalPermissionAdmin}.</li>
* <li>Be {@link #adapt(Class) adaptable} to the OSGi defined types to which
* a system bundle can be adapted.</li>
* </ul>
@@ -134,12 +133,10 @@ public interface Framework extends Bundle {
* <li>All installed bundles must be started in accordance with each
* bundle's persistent <i>autostart setting</i>. This means some bundles
* will not be started, some will be started with <i>eager activation</i>
- * and some will be started with their <i>declared activation</i> policy. If
- * this Framework implements the optional <i>Start Level Service
- * Specification</i>, then the start level of this Framework is moved to the
- * start level specified by the
- * {@link Constants#FRAMEWORK_BEGINNING_STARTLEVEL beginning start level}
- * framework property, as described in the <i>Start Level Service
+ * and some will be started with their <i>declared activation</i> policy.
+ * The start level of this Framework is moved to the start level specified
+ * by the {@link Constants#FRAMEWORK_BEGINNING_STARTLEVEL beginning start
+ * level} framework property, as described in the <i>Start Level
* Specification</i>. If this framework property is not specified, then the
* start level of this Framework is moved to start level one (1). Any
* exceptions that occur during bundle starting must be wrapped in a
@@ -153,7 +150,7 @@ public interface Framework extends Bundle {
* @throws SecurityException If the caller does not have the appropriate
* {@code AdminPermission[this,EXECUTE]}, and the Java Runtime
* Environment supports permissions.
- * @see "Start Level Service Specification"
+ * @see "Start Level Specification"
*/
void start() throws BundleException;
@@ -182,12 +179,11 @@ public interface Framework extends Bundle {
* <ol>
* <li>This Framework's state is set to {@link #STOPPING}.</li>
* <li>All installed bundles must be stopped without changing each bundle's
- * persistent <i>autostart setting</i>. If this Framework implements the
- * optional <i>Start Level Service Specification</i>, then the start level
- * of this Framework is moved to start level zero (0), as described in the
- * <i>Start Level Service Specification</i>. Any exceptions that occur
- * during bundle stopping must be wrapped in a {@link BundleException} and
- * then published as a framework event of type {@link FrameworkEvent#ERROR}</li>
+ * persistent <i>autostart setting</i>. The start level of this Framework is
+ * moved to start level zero (0), as described in the <i>Start Level
+ * Specification</i>. Any exceptions that occur during bundle stopping must
+ * be wrapped in a {@link BundleException} and then published as a framework
+ * event of type {@link FrameworkEvent#ERROR}</li>
* <li>Unregister all services registered by this Framework.</li>
* <li>Event handling is disabled.</li>
* <li>This Framework's state is set to {@link #RESOLVED}.</li>
@@ -205,7 +201,7 @@ public interface Framework extends Bundle {
* @throws SecurityException If the caller does not have the appropriate
* {@code AdminPermission[this,EXECUTE]}, and the Java Runtime
* Environment supports permissions.
- * @see "Start Level Service Specification"
+ * @see "Start Level Specification"
*/
void stop() throws BundleException;
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleCapability.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleCapability.java
new file mode 100644
index 000000000..3114bab5c
--- /dev/null
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleCapability.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.wiring;
+
+import java.util.Map;
+
+/**
+ * A capability that has been declared from a {@link BundleRevision bundle
+ * revision}.
+ *
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: BundleCapability.java,v 1.1.2.1 2011/02/14 22:18:14 twatson Exp $
+ */
+public interface BundleCapability {
+ /**
+ * Returns the name space of this capability.
+ *
+ * @return The name space of this capability.
+ */
+ String getNamespace();
+
+ /**
+ * Returns the directives of this capability.
+ *
+ * @return An unmodifiable map of directive names to directive values for
+ * this capability, or an empty map if this capability has no
+ * directives.
+ */
+ Map<String, String> getDirectives();
+
+ /**
+ * Returns the attributes of this capability.
+ *
+ * @return An unmodifiable map of attribute names to attribute values for
+ * this capability, or an empty map if this capability has no
+ * attributes.
+ */
+ Map<String, Object> getAttributes();
+
+ /**
+ * Returns the bundle revision declaring this capability.
+ *
+ * @return The bundle revision declaring this capability.
+ */
+ BundleRevision getRevision();
+}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleRequirement.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleRequirement.java
new file mode 100644
index 000000000..4ec2b12b4
--- /dev/null
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleRequirement.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.wiring;
+
+import java.util.Map;
+
+/**
+ * A requirement that has been declared from a {@link BundleRevision bundle
+ * revision}.
+ *
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: BundleRequirement.java,v 1.1.2.1 2011/02/14 22:18:14 twatson Exp $
+ */
+public interface BundleRequirement {
+ /**
+ * Returns the name space of this requirement.
+ *
+ * @return The name space of this requirement.
+ */
+ String getNamespace();
+
+ /**
+ * Returns the directives of this requirement.
+ *
+ * @return An unmodifiable map of directive names to directive values for
+ * this requirement, or an empty map if this requirement has no
+ * directives.
+ */
+ Map<String, String> getDirectives();
+
+ /**
+ * Returns the attributes of this requirement.
+ *
+ * @return An unmodifiable map of attribute names to attribute values for
+ * this requirement, or an empty map if this requirement has no
+ * attributes.
+ */
+ Map<String, Object> getAttributes();
+
+ /**
+ * Returns the bundle revision declaring this requirement.
+ *
+ * @return The bundle revision declaring this requirement.
+ */
+ BundleRevision getRevision();
+
+ /**
+ * Returns whether the specified capability matches this requirement.
+ *
+ * @param capability The capability to match to this requirement.
+ * @return {@code true} if the specified capability has the same
+ * {@link #getNamespace() name space} as this requirement and the
+ * filter for this requirement matches the
+ * {@link BundleCapability#getAttributes() attributes of the
+ * specified capability}; {@code false} otherwise.
+ */
+ boolean matches(BundleCapability capability);
+}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleRevision.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleRevision.java
index e9f71d91e..4f8ccca94 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleRevision.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleRevision.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,27 +14,40 @@
* limitations under the License.
*/
-
package org.osgi.framework.wiring;
import java.util.List;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleReference;
+import org.osgi.framework.Constants;
import org.osgi.framework.Version;
/**
- * Bundle Revision. Since a bundle update can change the entries in a bundle,
- * different bundle wirings for the same bundle can be associated with different
- * bundle revisions.
+ * Bundle Revision. When a bundle is installed and each time a bundle is
+ * updated, a new bundle revision of the bundle is created. Since a bundle
+ * update can change the entries in a bundle, different bundle wirings for the
+ * same bundle can be associated with different bundle revisions.
+ *
+ * <p>
+ * For a bundle that has not been uninstalled, the most recent bundle revision
+ * is defined to be the current bundle revision. A bundle in the UNINSTALLED
+ * state does not have a current revision. The current bundle revision for a
+ * bundle can be obtained by calling {@link Bundle#adapt(Class) bundle.adapt}
+ * (BundleRevision.class). Since a bundle in the UNINSTALLED state does not have
+ * a current revision, adapting such a bundle returns {@code null}.
*
* <p>
- * The current bundle revision for a bundle can be obtained by calling
- * {@link Bundle#adapt(Class) bundle.adapt}(BundleRevision.class).
+ * The framework defines name spaces for {@link #PACKAGE_NAMESPACE package},
+ * {@link #BUNDLE_NAMESPACE bundle} and {@link #HOST_NAMESPACE host}
+ * capabilities and requirements. These name spaces are defined only to express
+ * wiring information by the framework. They must not be used in
+ * {@link Constants#PROVIDE_CAPABILITY Provide-Capability} and
+ * {@link Constants#REQUIRE_CAPABILITY Require-Capability} manifest headers.
*
* @ThreadSafe
* @noimplement
- * @version $Id: 1a15861159e7071a1eb504afbc3f75f8af1aff01 $
+ * @version $Id: 5c029f6074388be25b42893e72012b4bbbc96fce $
*/
public interface BundleRevision extends BundleReference {
/**
@@ -58,15 +71,152 @@ public interface BundleRevision extends BundleReference {
/**
* Returns the capabilities declared by this bundle revision.
*
- * @param namespace The name space of the declared capabilities to
- * return or {@code null} to return the provided capabilities from
- * all name spaces.
- * @return A list containing a snapshot of the declared {@link Capability}s,
- * or an empty list if this bundle revision declares no capabilities
- * in the specified name space. The list contains the provided
- * capabilities in the order they are specified in the manifest.
+ * @param namespace The name space of the declared capabilities to return or
+ * {@code null} to return the declared capabilities from all name
+ * spaces.
+ * @return A list containing a snapshot of the declared
+ * {@link BundleCapability}s, or an empty list if this bundle
+ * revision declares no capabilities in the specified name space.
+ * The list contains the declared capabilities in the order they are
+ * specified in the manifest.
+ */
+ List<BundleCapability> getDeclaredCapabilities(String namespace);
+
+ /**
+ * Returns the requirements declared by this bundle revision.
+ *
+ * @param namespace The name space of the declared requirements to return or
+ * {@code null} to return the declared requirements from all name
+ * spaces.
+ * @return A list containing a snapshot of the declared
+ * {@link BundleRequirement}s, or an empty list if this bundle
+ * revision declares no requirements in the specified name space.
+ * The list contains the declared requirements in the order they are
+ * specified in the manifest.
+ */
+ List<BundleRequirement> getDeclaredRequirements(String namespace);
+
+ /**
+ * Name space for package capabilities and requirements.
+ *
+ * <p>
+ * The name of the package is stored in the capability attribute of the same
+ * name as this name space ({@value #PACKAGE_NAMESPACE}). The other
+ * directives and attributes of the package, from the
+ * {@link Constants#EXPORT_PACKAGE Export-Package} manifest header, can be
+ * found in the cabability's {@link BundleCapability#getDirectives()
+ * directives} and {@link BundleCapability#getAttributes() attributes}. The
+ * {@link Constants#VERSION_ATTRIBUTE version} capability attribute must
+ * contain the {@link Version} of the package if one is specified or
+ * {@link Version#emptyVersion} if not specified. The
+ * {@link Constants#BUNDLE_SYMBOLICNAME_ATTRIBUTE bundle-symbolic-name}
+ * capability attribute must contain the
+ * {@link BundleRevision#getSymbolicName() symbolic name} of the provider if
+ * one is specified. The {@link Constants#BUNDLE_VERSION_ATTRIBUTE
+ * bundle-version} capability attribute must contain the
+ * {@link BundleRevision#getVersion() version} of the provider if one is
+ * specified or {@link Version#emptyVersion} if not specified.
+ *
+ * <p>
+ * The package capabilities provided by the system bundle, that is the
+ * bundle with id zero, must include the package specified by the
+ * {@link Constants#FRAMEWORK_SYSTEMPACKAGES} and
+ * {@link Constants#FRAMEWORK_SYSTEMPACKAGES_EXTRA} framework properties as
+ * well as any other package exported by the framework implementation.
+ *
+ * <p>
+ * A bundle revision {@link BundleRevision#getDeclaredCapabilities(String)
+ * declares} zero or more package capabilities (this is, exported packages)
+ * and {@link BundleRevision#getDeclaredRequirements(String) declares} zero
+ * or more package requirements.
+ * <p>
+ * A bundle wiring {@link BundleWiring#getCapabilities(String) provides}
+ * zero or more resolved package capabilities (that is, exported packages)
+ * and {@link BundleWiring#getRequiredWires(String) requires} zero or more
+ * resolved package requirements (that is, imported packages). The number of
+ * package wires required by a bundle wiring may change as the bundle wiring
+ * may dynamically import additional packages.
*/
- List<Capability> getDeclaredCapabilities(String namespace);
+ String PACKAGE_NAMESPACE = "osgi.wiring.package";
+
+ /**
+ * Name space for bundle capabilities and requirements.
+ *
+ * <p>
+ * The bundle symbolic name of the bundle is stored in the capability
+ * attribute of the same name as this name space ({@value #BUNDLE_NAMESPACE}
+ * ). The other directives and attributes of the bundle, from the
+ * {@link Constants#BUNDLE_SYMBOLICNAME Bundle-SymbolicName} manifest
+ * header, can be found in the cabability's
+ * {@link BundleCapability#getDirectives() directives} and
+ * {@link BundleCapability#getAttributes() attributes}. The
+ * {@link Constants#BUNDLE_VERSION_ATTRIBUTE bundle-version} capability
+ * attribute must contain the {@link Version} of the bundle from the
+ * {@link Constants#BUNDLE_VERSION Bundle-Version} manifest header if one is
+ * specified or {@link Version#emptyVersion} if not specified.
+ *
+ * <p>
+ * A non-fragment revision
+ * {@link BundleRevision#getDeclaredCapabilities(String) declares} exactly
+ * one<sup>&#8224;</sup> bundle capability (that is, the bundle can be
+ * required by another bundle). A fragment revision must not declare a
+ * bundle capability.
+ *
+ * <p>
+ * A bundle wiring for a non-fragment revision
+ * {@link BundleWiring#getCapabilities(String) provides} exactly
+ * one<sup>&#8224;</sup> bundle capability (that is, the bundle can be
+ * required by another bundle) and
+ * {@link BundleWiring#getRequiredWires(String) requires} zero or more
+ * bundle capabilities (that is, requires other bundles).
+ *
+ * <p>
+ * &#8224; A bundle with no bundle symbolic name (that is, a bundle with
+ * {@link Constants#BUNDLE_MANIFESTVERSION Bundle-ManifestVersion}
+ * {@literal <} 2) must not provide a bundle capability.
+ */
+ String BUNDLE_NAMESPACE = "osgi.wiring.bundle";
+
+ /**
+ * Name space for host capabilities and requirements.
+ *
+ * <p>
+ * The bundle symbolic name of the bundle is stored in the capability
+ * attribute of the same name as this name space ({@value #HOST_NAMESPACE}).
+ * The other directives and attributes of the bundle, from the
+ * {@link Constants#BUNDLE_SYMBOLICNAME Bundle-SymbolicName} manifest
+ * header, can be found in the cabability's
+ * {@link BundleCapability#getDirectives() directives} and
+ * {@link BundleCapability#getAttributes() attributes}. The
+ * {@link Constants#BUNDLE_VERSION_ATTRIBUTE bundle-version} capability
+ * attribute must contain the {@link Version} of the bundle from the
+ * {@link Constants#BUNDLE_VERSION Bundle-Version} manifest header if one is
+ * specified or {@link Version#emptyVersion} if not specified.
+ *
+ * <p>
+ * A non-fragment revision
+ * {@link BundleRevision#getDeclaredCapabilities(String) declares} zero or
+ * one<sup>&#8224;</sup> host capability if the bundle
+ * {@link Constants#FRAGMENT_ATTACHMENT_DIRECTIVE allows fragments to be
+ * attached}. A fragment revision must
+ * {@link BundleRevision#getDeclaredRequirements(String) declare} exactly
+ * one host requirement.
+ *
+ * <p>
+ * A bundle wiring for a non-fragment revision
+ * {@link BundleWiring#getCapabilities(String) provides} zero or
+ * one<sup>&#8224;</sup> host capability if the bundle
+ * {@link Constants#FRAGMENT_ATTACHMENT_DIRECTIVE allows fragments to be
+ * attached}. A bundle wiring for a fragment revision
+ * {@link BundleWiring#getRequiredWires(String) requires} a host capability
+ * for each host to which it is attached.
+ *
+ * <p>
+ * &#8224; A bundle with no bundle symbolic name (that is, a bundle with
+ * {@link Constants#BUNDLE_MANIFESTVERSION Bundle-ManifestVersion}
+ * {@literal <} 2) must not provide a host capability.
+ */
+ String HOST_NAMESPACE = "osgi.wiring.host";
/**
* Returns the special types of this bundle revision. The bundle revision
@@ -93,4 +243,13 @@ public interface BundleRevision extends BundleReference {
* @see #getTypes()
*/
int TYPE_FRAGMENT = 0x00000001;
+
+ /**
+ * Returns the bundle wiring which is using this bundle revision.
+ *
+ * @return The bundle wiring which is using this bundle revision or
+ * {@code null} if no bundle wiring is using this bundle revision.
+ * @see BundleWiring#getRevision()
+ */
+ BundleWiring getWiring();
}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleRevisions.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleRevisions.java
new file mode 100644
index 000000000..ba856b3f3
--- /dev/null
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleRevisions.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.wiring;
+
+import java.util.List;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleReference;
+
+/**
+ * The {@link BundleRevision bundle revisions} of a bundle. When a bundle is
+ * installed and each time a bundle is updated, a new bundle revision of the
+ * bundle is created. For a bundle that has not been uninstalled, the most
+ * recent bundle revision is defined to be the current bundle revision. A bundle
+ * in the UNINSTALLED state does not have a current revision. An in use bundle
+ * revision is associated with an {@link BundleWiring#isInUse() in use}
+ * {@link BundleWiring}. The current bundle revision, if there is one, and all
+ * in use bundle revisions are returned.
+ *
+ * <p>
+ * The bundle revisions for a bundle can be obtained by calling
+ * {@link Bundle#adapt(Class) bundle.adapt}({@link BundleRevisions}.class).
+ * {@link #getRevisions()} on the bundle.
+ *
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: BundleRevisions.java,v 1.1.2.2 2011/02/14 22:18:14 twatson Exp $
+ */
+public interface BundleRevisions extends BundleReference {
+ /**
+ * Return the bundle revisions for the {@link BundleReference#getBundle()
+ * referenced} bundle.
+ *
+ * <p>
+ * The result is a list containing the current bundle revision, if there is
+ * one, and all in use bundle revisions. The list may also contain
+ * intermediate bundle revisions which are not in use.
+ *
+ * <p>
+ * The list is ordered in reverse chronological order such that the first
+ * item is the most recent bundle revision and last item is the oldest
+ * bundle revision.
+ *
+ * <p>
+ * Generally the list will have at least one bundle revision for the bundle:
+ * the current bundle revision. However, for an uninstalled bundle with no
+ * in use bundle revisions, the list may be empty.
+ *
+ * @return A list containing a snapshot of the {@link BundleRevision}s for
+ * the referenced bundle.
+ */
+ List<BundleRevision> getRevisions();
+}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleWire.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleWire.java
new file mode 100644
index 000000000..ad420fa60
--- /dev/null
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleWire.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.wiring;
+
+/**
+ * A wire connecting a {@link BundleCapability} to a {@link BundleRequirement}.
+ *
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: BundleWire.java,v 1.1.2.1 2011/02/14 22:18:14 twatson Exp $
+ */
+public interface BundleWire {
+ /**
+ * Returns the {@link BundleCapability} for this wire.
+ *
+ * @return The {@link BundleCapability} for this wire.
+ */
+ BundleCapability getCapability();
+
+ /**
+ * Return the {@link BundleRequirement} for this wire.
+ *
+ * @return The {@link BundleRequirement} for this wire.
+ */
+ BundleRequirement getRequirement();
+
+ /**
+ * Returns the bundle wiring {@link BundleWiring#getProvidedWires(String)
+ * providing} the {@link #getCapability() capability}.
+ *
+ * <p>
+ * The bundle revision referenced by the returned bundle wiring may differ
+ * from the bundle revision reference by the {@link #getCapability()
+ * capability}.
+ *
+ * @return The bundle wiring providing the capability. If the bundle wiring
+ * providing the capability is not {@link BundleWiring#isInUse() in
+ * use}, {@code null} will be returned.
+ */
+ BundleWiring getProviderWiring();
+
+ /**
+ * Returns the bundle wiring who
+ * {@link BundleWiring#getRequiredWires(String) requires} the
+ * {@link #getCapability() capability}.
+ *
+ * <p>
+ * The bundle revision referenced by the returned bundle wiring may differ
+ * from the bundle revision reference by the {@link #getRequirement()
+ * requirement}.
+ *
+ * @return The bundle wiring whose requirement is wired to the capability.
+ * If the bundle wiring requiring the capability is not
+ * {@link BundleWiring#isInUse() in use}, {@code null} will be
+ * returned.
+ */
+ BundleWiring getRequirerWiring();
+}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleWiring.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleWiring.java
index 2c7149564..c8f19a270 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleWiring.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleWiring.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2010). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,43 +25,36 @@ import org.osgi.framework.BundleReference;
/**
* A wiring for a bundle. Each time a bundle is resolved, a new bundle wiring
- * for the bundle is created. A bundle wiring consists of a bundle and it
- * attached fragments and represents the dependencies with other bundle wirings.
+ * for the bundle is created. A bundle wiring is associated with a bundle
+ * revision and represents the dependencies with other bundle wirings.
*
* <p>
* The bundle wiring for a bundle is the {@link #isCurrent() current} bundle
- * wiring if the bundle is resolved and the bundle wiring is the most recent
- * bundle wiring. All bundles with non-current, in use bundle wirings are
- * considered removal pending. A bundle wiring is {@link #isInUse() in use} if
- * it is the current wiring or if some other in use bundle wiring is dependent
- * upon it. For example, wired to a package exported by the bundle wiring or
- * requires the bundle wiring. An in use bundle wiring has a class loader. Once
- * a bundle wiring is no longer in use, it is considered stale and is discarded
- * by the framework.
+ * wiring if it is the most recent bundle wiring for the current bundle
+ * revision. A bundle wiring is {@link #isInUse() in use} if it is the current
+ * bundle wiring or if some other in use bundle wiring is dependent upon it. For
+ * example, another bundle wiring is wired to a capability provided by the
+ * bundle wiring. An in use bundle wiring for a non-fragment bundle has a class
+ * loader. All bundles with non-current, in use bundle wirings are considered
+ * removal pending. Once a bundle wiring is no longer in use, it is considered
+ * stale and is discarded by the framework.
*
* <p>
- * A list of all in use bundle wirings for a bundle can be obtained by calling
- * {@link Bundle#adapt(Class) bundle.adapt}({@link BundleWirings}.class).
- * {@link BundleWirings#getWirings() getWirings()}. For non-fragment bundles,
- * the first item in the returned list is the current bundle wiring.
- *
- * <p>
- * The current bundle wiring for a non-fragment bundle can be obtained by
- * calling {@link Bundle#adapt(Class) bundle.adapt}(BundleWiring.class). A
- * fragment bundle does not itself have bundle wirings. So calling
- * {@link Bundle#adapt(Class) bundle.adapt}(BundleWiring.class) on a fragment
- * must return {@code null}.
+ * The current bundle wiring for a bundle can be obtained by calling
+ * {@link Bundle#adapt(Class) bundle.adapt}(BundleWiring.class). A bundle in the
+ * INSTALLED or UNINSTALLED state does not have a current wiring, adapting such
+ * a bundle returns {@code null}.
*
* @ThreadSafe
* @noimplement
- * @version $Id: 77da60ad2f9fdeea7bd9465b633b35f8a06c6cdf $
+ * @version $Id: 7a7bc5a26838599519fbd1496248136278b9d1e7 $
*/
public interface BundleWiring extends BundleReference {
/**
* Returns {@code true} if this bundle wiring is the current bundle wiring.
- * The bundle wiring for a bundle is the current bundle wiring if the bundle
- * is resolved and the bundle wiring is the most recent bundle wiring. All
- * bundles with non-current, in use bundle wirings are considered
+ * The bundle wiring for a bundle is the current bundle wiring if it is the
+ * most recent bundle wiring for the current bundle revision. All bundles
+ * with non-current, in use bundle wirings are considered
* {@link FrameworkWiring#getRemovalPendingBundles() removal pending}.
*
* @return {@code true} if this bundle wiring is the current bundle wiring;
@@ -83,36 +76,99 @@ public interface BundleWiring extends BundleReference {
/**
* Returns the capabilities provided by this bundle wiring.
*
- * @param capabilityNamespace The name space of the provided capabilities to
- * return or {@code null} to return the provided capabilities from
- * all name spaces.
- * @return A list containing a snapshot of the {@link WiredCapability}s, or
+ * <p>
+ * A capability may not be required by any bundle wiring and thus there may
+ * be no {@link #getProvidedWires(String) wires} for the capability.
+ *
+ * <p>
+ * A bundle wiring for a non-fragment revision provides a subset of the
+ * declared capabilities from the bundle revision and all attached fragment
+ * revisions. Not all declared capabilities may be provided since some may
+ * be discarded. For example, if a package is declared to be exported and
+ * import, only one is selected and the other is discarded.
+ *
+ * @param namespace The name space of the capabilities to return or
+ * {@code null} to return the capabilities from all name spaces.
+ * @return A list containing a snapshot of the {@link BundleCapability}s, or
* an empty list if this bundle wiring provides no capabilities in
* the specified name space. If this bundle wiring is not
- * {@link #isInUse() in use}, {@code null} will be returned. The
- * list contains the provided capabilities in the order they are
- * specified in the manifest.
+ * {@link #isInUse() in use}, {@code null} will be returned. For a
+ * given name space, the list contains the wires in the order the
+ * capabilities were specified in the manifests of the
+ * {@link #getRevision() bundle revision} and the attached fragments
+ * of this bundle wiring. There is no ordering defined between
+ * capabilities in different name spaces.
+ */
+ List<BundleCapability> getCapabilities(String namespace);
+
+ /**
+ * Returns the requirements of this bundle wiring.
+ *
+ * <p>
+ * A bundle wiring for a non-fragment revision has a subset of the declared
+ * requirements from the bundle revision and all attached fragment
+ * revisions. Not all declared requirements may be present since some may be
+ * discarded. For example, if a package is declared to be optionally
+ * imported and is not actually imported, the requirement must be discarded.
+ *
+ * @param namespace The name space of the requirements to return or
+ * {@code null} to return the requirements from all name spaces.
+ * @return A list containing a snapshot of the {@link BundleRequirement}s,
+ * or an empty list if this bundle wiring uses no requirements in
+ * the specified name space. If this bundle wiring is not
+ * {@link #isInUse() in use}, {@code null} will be returned. For a
+ * given name space, the list contains the wires in the order the
+ * requirements were specified in the manifests of the
+ * {@link #getRevision() bundle revision} and the attached fragments
+ * of this bundle wiring. There is no ordering defined between
+ * requirements in different name spaces.
*/
- List<WiredCapability> getProvidedCapabilities(String capabilityNamespace);
+ List<BundleRequirement> getRequirements(String namespace);
/**
- * Returns the required capabilities used by this bundle wiring.
+ * Returns the {@link BundleWire}s to the provided {@link BundleCapability
+ * capabilities} of this bundle wiring.
+ *
+ * @param namespace The name space of the capabilities for which to return
+ * wires or {@code null} to return the wires for the capabilities in
+ * all name spaces.
+ * @return A list containing a snapshot of the {@link BundleWire}s for the
+ * {@link BundleCapability capabilities} of this bundle wiring, or
+ * an empty list if this bundle wiring has no capabilities in the
+ * specified name space. If this bundle wiring is not
+ * {@link #isInUse() in use}, {@code null} will be returned. For a
+ * given name space, the list contains the wires in the order the
+ * capabilities were specified in the manifests of the
+ * {@link #getRevision() bundle revision} and the attached fragments
+ * of this bundle wiring. There is no ordering defined between
+ * capabilities in different name spaces.
+ */
+ List<BundleWire> getProvidedWires(String namespace);
+
+ /**
+ * Returns the {@link BundleWire}s to the {@link BundleRequirement
+ * requirements} in use by this bundle wiring.
*
* <p>
- * The result of this method can change if this bundle wiring requires
- * additional capabilities.
+ * This method may return different results if this bundle wiring adds wires
+ * to more requirements. For example, dynamically importing a package will
+ * establish a new wire to the dynamically imported package.
*
- * @param capabilityNamespace The name space of the required capabilities to
- * return or {@code null} to return the required capabilities from
+ * @param namespace The name space of the requirements for which to return
+ * wires or {@code null} to return the wires for the requirements in
* all name spaces.
- * @return A list containing a snapshot of the {@link WiredCapability}s used
- * by this bundle wiring, or an empty list if this bundle wiring
- * requires no capabilities in the specified name space. If this
- * bundle wiring is not {@link #isInUse() in use}, {@code null} will
- * be returned. The list contains the required capabilities in the
- * order they are specified in the manifest.
+ * @return A list containing a snapshot of the {@link BundleWire}s for the
+ * {@link BundleRequirement requirements} of this bundle wiring, or
+ * an empty list if this bundle wiring has no requirements in the
+ * specified name space. If this bundle wiring is not
+ * {@link #isInUse() in use}, {@code null} will be returned. For a
+ * given name space, the list contains the wires in the order the
+ * requirements were specified in the manifests of the
+ * {@link #getRevision() bundle revision} and the attached fragments
+ * of this bundle wiring. There is no ordering defined between
+ * requirements in different name spaces.
*/
- List<WiredCapability> getRequiredCapabilities(String capabilityNamespace);
+ List<BundleWire> getRequiredWires(String namespace);
/**
* Returns the bundle revision for the bundle in this bundle wiring. Since a
@@ -126,27 +182,9 @@ public interface BundleWiring extends BundleReference {
* may refer to an older revision of the bundle.
*
* @return The bundle revision for this bundle wiring.
+ * @see BundleRevision#getWiring()
*/
- BundleRevision getBundleRevision();
-
- /**
- * Returns the bundle revisions for all attached fragments of this bundle
- * wiring. Since a bundle update can change the entries in a fragment,
- * different bundle wirings for the same bundle can have different bundle
- * revisions.
- *
- * <p>
- * The bundle revisions in the list are ordered in fragment attachment order
- * such that the first revision in the list is the first attached fragment
- * and the last revision in the list is the last attached fragment.
- *
- * @return A list containing a snapshot of the {@link BundleRevision}s for
- * all attached fragments attached of this bundle wiring, or an
- * empty list if this bundle wiring does not have any attached
- * fragments. If this bundle wiring is not {@link #isInUse() in use}
- * , {@code null} will be returned.
- */
- List<BundleRevision> getFragmentRevisions();
+ BundleRevision getRevision();
/**
* Returns the class loader for this bundle wiring. Since a bundle refresh
@@ -154,7 +192,8 @@ public interface BundleWiring extends BundleReference {
* the same bundle will have different class loaders.
*
* @return The class loader for this bundle wiring. If this bundle wiring is
- * not {@link #isInUse() in use}, {@code null} will be returned.
+ * not {@link #isInUse() in use} or this bundle wiring is for a
+ * fragment revision, {@code null} will be returned.
* @throws SecurityException If the caller does not have the appropriate
* {@code RuntimePermission("getClassLoader")}, and the Java Runtime
* Environment supports permissions.
@@ -162,16 +201,16 @@ public interface BundleWiring extends BundleReference {
ClassLoader getClassLoader();
/**
- * Returns entries in this bundle wiring's {@link #getBundleRevision()
- * bundle revision} and its attached {@link #getFragmentRevisions() fragment
- * revisions}. This bundle wiring's class loader is not used to search for
- * entries. Only the contents of this bundle wiring's bundle revision and
- * its attached fragment revisions are searched for the specified entries.
+ * Returns entries in this bundle wiring's {@link #getRevision() bundle
+ * revision} and its attached fragment revisions. This bundle wiring's class
+ * loader is not used to search for entries. Only the contents of this
+ * bundle wiring's bundle revision and its attached fragment revisions are
+ * searched for the specified entries.
*
* <p>
* This method takes into account that the &quot;contents&quot; of this
* bundle wiring can have attached fragments. This &quot;bundle space&quot;
- * is not a namespace with unique members; the same entry name can be
+ * is not a name space with unique members; the same entry name can be
* present multiple times. This method therefore returns a list of URL
* objects. These URLs can come from different JARs but have the same path
* name. This method can either return only entries in the specified path or
@@ -199,15 +238,15 @@ public interface BundleWiring extends BundleReference {
* {@link #FINDENTRIES_RECURSE}. The method must ignore unrecognized
* options.
* @return An unmodifiable list of URL objects for each matching entry, or
- * an empty list if no matching entry could not be found or if the
- * caller does not have the appropriate
- * {@code AdminPermission[bundle,RESOURCE]} and the Java Runtime
- * Environment supports permissions. The list is ordered such that
- * entries from the {@link #getBundleRevision() bundle revision} are
- * returned first followed by the entries from
- * {@link #getFragmentRevisions() attached fragment revisions} in
- * attachment order. If this bundle wiring is not {@link #isInUse()
- * in use}, {@code null} must be returned.
+ * an empty list if no matching entry could not be found, if this
+ * bundle wiring is for a fragment revision or if the caller does
+ * not have the appropriate {@code AdminPermission[bundle,RESOURCE]}
+ * and the Java Runtime Environment supports permissions. The list
+ * is ordered such that entries from the {@link #getRevision()
+ * bundle revision} are returned first followed by the entries from
+ * attached fragment revisions in attachment order. If this bundle
+ * wiring is not {@link #isInUse() in use}, {@code null} must be
+ * returned.
* @see Bundle#findEntries(String, String, boolean)
*/
List<URL> findEntries(String path, String filePattern, int options);
@@ -257,7 +296,8 @@ public interface BundleWiring extends BundleReference {
* This method must ignore unrecognized options.
* @return An unmodifiable collection of resource names for each matching
* resource, or an empty collection if no matching resource could
- * not be found or if the caller does not have the appropriate
+ * not be found, if this bundle wiring is for a fragment revision or
+ * if the caller does not have the appropriate
* {@code AdminPermission[bundle,RESOURCE]} and the Java Runtime
* Environment supports permissions. The collection is unordered and
* must contain no duplicate resource names. If this bundle wiring
@@ -283,11 +323,10 @@ public interface BundleWiring extends BundleReference {
/**
* The list resource names operation must limit the result to the names of
* matching resources contained in this bundle wiring's
- * {@link #getBundleRevision() bundle revision} and its attached
- * {@link #getFragmentRevisions() fragment revisions}. The result must not
- * include resource names for resources in
- * {@link Capability#PACKAGE_CAPABILITY package} names which are
- * {@link #getRequiredCapabilities(String) imported} by this wiring.
+ * {@link #getRevision() bundle revision} and its attached fragment
+ * revisions. The result must not include resource names for resources in
+ * {@link BundleRevision#PACKAGE_NAMESPACE package} names which are
+ * {@link #getRequiredWires(String) imported} by this wiring.
*
* <p>
* This bit may be set when calling
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleWirings.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleWirings.java
deleted file mode 100644
index f1e2d5256..000000000
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/BundleWirings.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) OSGi Alliance (2010). All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.osgi.framework.wiring;
-
-import java.util.List;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleReference;
-
-/**
- * The {@link BundleWiring#isInUse() in use} bundle wirings for a bundle. Each
- * time a bundle is resolved, a new bundle wiring of the bundle is created. A
- * bundle wiring consists of a bundle and its attached fragments and represents
- * the dependencies with other bundle wirings.
- *
- * <p>
- * The in use bundle wirings for a bundle can be obtained by calling
- * {@link Bundle#adapt(Class) bundle.adapt}({@link BundleWirings}.class).
- * {@link BundleWirings#getWirings() getWirings()}.
- *
- * @ThreadSafe
- * @noimplement
- * @version $Id: ecf3e7820319a6710f4dff063577bd052f5dafe2 $
- */
-public interface BundleWirings extends BundleReference {
- /**
- * Return the {@link BundleWiring#isInUse() in use} wirings for the
- * {@link BundleReference#getBundle() referenced} bundle.
- *
- * <p>
- * If the referenced bundle is a non-fragment bundle, then the result is a
- * list of in use bundle wirings. The list is ordered in reverse
- * chronological order such that the first bundle wiring is the
- * {@link BundleWiring#isCurrent() current} bundle wiring and last wiring is
- * the oldest in use bundle wiring.
- *
- * <p>
- * If the referenced bundle is a fragment bundle, then the result is a list
- * of in use bundle wirings to which the referenced fragment bundle is
- * attached. The ordering of the list is unspecified. If the fragment bundle
- * is not attached to any bundle wiring, then the returned list will be
- * empty.
- *
- * <p>
- * The list must only contain in use bundle wirings. Generally the list will
- * have at least one bundle wiring for the bundle: the current bundle
- * wiring. However, for an uninstalled bundle with no in use bundle wirings
- * or a newly installed bundle which has not been resolved, the list will be
- * empty.
- *
- * @return A list containing a snapshot of the {@link BundleWiring}s for the
- * referenced bundle.
- */
- List<BundleWiring> getWirings();
-}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/Capability.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/Capability.java
deleted file mode 100644
index fc9e5b01c..000000000
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/Capability.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (c) OSGi Alliance (2010). All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.osgi.framework.wiring;
-
-import java.util.Map;
-
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-
-/**
- * A capability that has been declared from a {@link BundleRevision bundle
- * revision}.
- *
- * <p>
- * The framework defines capabilities for {@link #PACKAGE_CAPABILITY packages},
- * {@link #BUNDLE_CAPABILITY bundles} and {@link #HOST_CAPABILITY hosts}. These
- * capabilities are defined only to express wiring information by the framework.
- * They must not be used in {@link Constants#PROVIDE_CAPABILITY
- * Provide-Capability} and {@link Constants#REQUIRE_CAPABILITY
- * Require-Capability} manifest headers.
- *
- * @ThreadSafe
- * @noimplement
- * @version $Id: 6b7ced3912cc0570547c06bb4140b78d36d7ee42 $
- */
-public interface Capability {
- /**
- * Capability name space for package capabilities. The name of the package
- * is stored in the capability attribute of the same name as this name
- * space. The other directives and attributes of the package, from the
- * {@link Constants#EXPORT_PACKAGE Export-Package} manifest header, can be
- * found in the cabability's {@link #getDirectives() directives} and
- * {@link #getAttributes() attributes}. The
- * {@link Constants#VERSION_ATTRIBUTE version} capability attribute must
- * contain the {@link Version} of the package if one is specified. The
- * {@link Constants#BUNDLE_SYMBOLICNAME_ATTRIBUTE bundle-symbolic-name}
- * capability attribute must contain the {@link
- * BundleRevision#getSymbolicName() symbolic name} of the provider if one
- * is specified.
- * The {@link Constants#BUNDLE_VERSION_ATTRIBUTE bundle-version} capability
- * attribute must contain the {@link BundleRevision#getVersion() version}
- * of the provider if one is specified.
- *
- * <p>
- * The package capabilities provided by the system bundle, that is the
- * bundle with id zero, must include the package specified by the
- * {@link Constants#FRAMEWORK_SYSTEMPACKAGES} and
- * {@link Constants#FRAMEWORK_SYSTEMPACKAGES_EXTRA} framework properties as
- * well as any other package exported by the framework implementation.
- *
- * <p>
- * A bundle revision {@link BundleRevision#getDeclaredCapabilities(String)
- * declares} zero or more package capabilities (this is, exported packages).
- * <p>
- * A bundle wiring {@link BundleWiring#getProvidedCapabilities(String)
- * provides} zero or more resolved package capabilities (that is, exported packages)
- * and {@link BundleWiring#getRequiredCapabilities(String) requires} zero or
- * more resolved package capabilities (that is, imported packages). The number of
- * package capabilities required by a bundle wiring may change as the bundle
- * wiring may dynamically import additional packages.
- */
- String PACKAGE_CAPABILITY = "osgi.package";
-
- /**
- * Capability name space for bundle capabilities. The bundle symbolic name
- * of the bundle is stored in the capability attribute of the same name as
- * this name space. The other directives and attributes of the bundle, from
- * the {@link Constants#BUNDLE_SYMBOLICNAME Bundle-SymbolicName} manifest
- * header, can be found in the cabability's {@link #getDirectives()
- * directives} and {@link #getAttributes() attributes}. The
- * {@link Constants#BUNDLE_VERSION_ATTRIBUTE bundle-version} capability
- * attribute must contain the {@link Version} of the bundle, from the
- * {@link Constants#BUNDLE_VERSION Bundle-Version} manifest header.
- *
- * <p>
- * A bundle wiring {@link BundleWiring#getProvidedCapabilities(String)
- * provides} exactly one<sup>&#8224;</sup> bundle capability (that is, the
- * bundle can be required by another bundle) and
- * {@link BundleWiring#getRequiredCapabilities(String) requires} zero or
- * more bundle capabilities (that is, requires other bundles).
- *
- * <p>
- * &#8224; A bundle with no bundle symbolic name (that is, a bundle with
- * {@link Constants#BUNDLE_MANIFESTVERSION Bundle-ManifestVersion}
- * {@literal <} 2) must not provide a bundle capability.
- */
- String BUNDLE_CAPABILITY = "osgi.bundle";
-
- /**
- * Capability name space for host capabilities. The bundle symbolic name of
- * the bundle is stored in the capability attribute of the same name as this
- * name space. The other directives and attributes of the bundle, from the
- * {@link Constants#BUNDLE_SYMBOLICNAME Bundle-SymbolicName} manifest
- * header, can be found in the cabability's {@link #getDirectives()
- * directives} and {@link #getAttributes() attributes}. The
- * {@link Constants#BUNDLE_VERSION_ATTRIBUTE bundle-version} capability
- * attribute must contain the {@link Version} of the bundle, from the
- * {@link Constants#BUNDLE_VERSION Bundle-Version} manifest header.
- *
- * <p>
- * A bundle wiring {@link BundleWiring#getProvidedCapabilities(String)
- * provides} zero or one<sup>&#8224;</sup> host capability if the bundle
- * {@link Constants#FRAGMENT_ATTACHMENT_DIRECTIVE allows fragments to be
- * attached} and {@link BundleWiring#getRequiredCapabilities(String)
- * requires} zero or one host capability if their are attached fragments.
- *
- * <p>
- * &#8224; A bundle with no bundle symbolic name (that is, a bundle with
- * {@link Constants#BUNDLE_MANIFESTVERSION Bundle-ManifestVersion}
- * {@literal <} 2) must not provide a host capability.
- */
- String HOST_CAPABILITY = "osgi.host";
-
- /**
- * Returns the name space of this capability.
- *
- * @return The name space of this capability.
- */
- String getNamespace();
-
- /**
- * Returns the directives of this capability.
- *
- * @return An unmodifiable map of directive names to directive values for this
- * capability, or an empty map if this capability has no directives.
- */
- Map<String, String> getDirectives();
-
- /**
- * Returns the attributes of this capability.
- *
- * @return An unmodifiable map of attribute names to attribute values for this
- * capability, or an empty map if this capability has no attributes.
- */
- Map<String, Object> getAttributes();
-
- /**
- * Returns the bundle revision declaring this capability.
- *
- * @return The bundle revision declaring this capability.
- */
- BundleRevision getProviderRevision();
-}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/WiredCapability.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/WiredCapability.java
deleted file mode 100644
index d2e40ec44..000000000
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/framework/wiring/WiredCapability.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) OSGi Alliance (2010). All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.osgi.framework.wiring;
-
-import java.util.Collection;
-
-/**
- * A wired capability that has been provided from a {@link BundleWiring bundle wiring}.
- * This capability may or may not be required by any bundle wiring.
- * <p>
- * A wired capability represents a capability from a resolved bundle wiring.
- * @ThreadSafe
- * @noimplement
- * @version $Id: bdf793be0ba691b543c523ca1b608e356aac9963 $
- */
-public interface WiredCapability extends Capability {
- /**
- * Returns the bundle wiring providing this capability.
- *
- * @return The bundle wiring providing this capability. If the bundle wiring
- * providing this capability is not {@link BundleWiring#isInUse() in
- * use}, {@code null} will be returned.
- */
- BundleWiring getProviderWiring();
-
- /**
- * Returns the bundle wirings that require this capability.
- *
- * <p>
- * The result of this method can change if this capability becomes required
- * by additional bundle wirings.
- *
- * @return A collection containing a snapshot of the bundle wirings
- * currently requiring this capability, or an empty collection if no
- * bundle wirings require this capability. If the bundle wiring
- * providing this capability is not {@link BundleWiring#isInUse() in
- * use}, {@code null} will be returned.
- */
- Collection<BundleWiring> getRequirerWirings();
-}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverBundle.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverBundle.java
index 8aff6b6f4..7eb0e0827 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverBundle.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverBundle.java
@@ -12,6 +12,8 @@ package org.eclipse.osgi.internal.module;
import java.util.*;
import java.util.Map.Entry;
+import org.eclipse.osgi.internal.resolver.ExportPackageDescriptionImpl;
+import org.eclipse.osgi.internal.resolver.GenericDescriptionImpl;
import org.eclipse.osgi.service.resolver.*;
import org.osgi.framework.Constants;
@@ -351,7 +353,6 @@ public class ResolverBundle extends VersionSupplier implements Comparable<Resolv
ArrayList<ResolverExport> hostExports = new ArrayList<ResolverExport>(newExports.length);
if (newExports.length > 0 && dynamicAttach) {
- StateObjectFactory factory = resolver.getState().getFactory();
for (int i = 0; i < newExports.length; i++) {
ResolverExport currentExports[] = getExports(newExports[i].getName());
boolean foundEquivalent = false;
@@ -360,7 +361,7 @@ public class ResolverBundle extends VersionSupplier implements Comparable<Resolv
foundEquivalent = true;
}
if (!foundEquivalent) {
- ExportPackageDescription hostExport = factory.createExportPackageDescription(newExports[i].getName(), newExports[i].getVersion(), newExports[i].getDirectives(), newExports[i].getAttributes(), true, getBundleDescription());
+ ExportPackageDescription hostExport = new ExportPackageDescriptionImpl(getBundleDescription(), newExports[i]);
hostExports.add(new ResolverExport(this, hostExport));
}
}
@@ -369,17 +370,8 @@ public class ResolverBundle extends VersionSupplier implements Comparable<Resolv
List<GenericCapability> hostCapabilities = new ArrayList<GenericCapability>(newGenericCapabilities.length);
if (newGenericCapabilities.length > 0 && dynamicAttach) {
- StateObjectFactory factory = resolver.getState().getFactory();
for (GenericDescription capability : newGenericCapabilities) {
- Dictionary<String, Object> origAttrs = capability.getAttributes();
- Map<String, Object> attrs = new HashMap<String, Object>();
- if (origAttrs != null) {
- for (Enumeration<String> keys = origAttrs.keys(); keys.hasMoreElements();) {
- String key = keys.nextElement();
- attrs.put(key, origAttrs.get(key));
- }
- }
- GenericDescription hostCapabililty = factory.createGenericDescription(capability.getType(), attrs, null, getBundleDescription());
+ GenericDescription hostCapabililty = new GenericDescriptionImpl(getBundleDescription(), capability);
hostCapabilities.add(new GenericCapability(this, hostCapabililty));
}
fragmentGenericCapabilities.put(fragment.bundleID, hostCapabilities);
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverConstraint.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverConstraint.java
index 5d6f46c3a..759898a70 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverConstraint.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverConstraint.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2010 IBM Corporation and others. All rights reserved. This
+ * Copyright (c) 2005, 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
@@ -10,6 +10,7 @@ package org.eclipse.osgi.internal.module;
import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.osgi.service.resolver.VersionConstraint;
+import org.osgi.framework.wiring.BundleRequirement;
/*
* A companion to VersionConstraint from the state used while resolving
@@ -17,12 +18,14 @@ import org.eclipse.osgi.service.resolver.VersionConstraint;
public abstract class ResolverConstraint {
final protected ResolverBundle bundle;
protected VersionConstraint constraint;
+ private BundleRequirement requrement;
private VersionSupplier[] possibleSuppliers;
private int selectedSupplierIndex = 0;
ResolverConstraint(ResolverBundle bundle, VersionConstraint constraint) {
this.bundle = bundle;
this.constraint = constraint;
+ this.requrement = constraint.getRequirement();
}
// returns the Resolver bundle requiring the ResolverConstraint
@@ -139,5 +142,10 @@ public abstract class ResolverConstraint {
void setVersionConstraint(VersionConstraint constraint) {
this.constraint = constraint;
+ this.requrement = constraint.getRequirement();
+ }
+
+ BundleRequirement getRequirement() {
+ return requrement;
}
}
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 7652a122e..d8a800f73 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
@@ -27,8 +27,8 @@ 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.BundleCapability;
import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.Capability;
public class ResolverImpl implements Resolver {
// Debug fields
@@ -349,21 +349,21 @@ public class ResolverImpl implements Resolver {
BundleConstraint hostConstraint = bundle.getHost();
List<ResolverBundle> hosts = resolverBundles.get(hostConstraint.getVersionConstraint().getName());
List<ResolverBundle> candidates = new ArrayList<ResolverBundle>(hosts);
- List<Capability> hostCapabilities = new ArrayList<Capability>(hosts.size());
+ 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<Capability> h = host.getBundleDescription().getDeclaredCapabilities(Capability.HOST_CAPABILITY);
+ 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(bundle.getBundleDescription(), asCapabilities(new ArrayMap<Capability, ResolverBundle>(hostCapabilities, candidates)));
+ hook.filterMatches(hostConstraint.getRequirement(), asCapabilities(new ArrayMap<BundleCapability, ResolverBundle>(hostCapabilities, candidates)));
// we are left with only candidates that satisfy the host constraint
for (ResolverBundle host : candidates) {
foundMatch = true;
@@ -435,6 +435,10 @@ public class ResolverImpl implements Resolver {
usesCalculationTimeout = false;
resolveBundles(bundles, platformProperties, hookDisabled);
+ // reorder exports and bundles after resolving the bundles
+ resolverExports.reorder();
+ resolverBundles.reorder();
+ reorderGenerics();
if (resolveOptional)
resolveOptionalConstraints(currentlyResolved);
if (DEBUG)
@@ -515,7 +519,7 @@ public class ResolverImpl implements Resolver {
resolvedOptional = true;
}
if (resolvedOptional) {
- state.resolveBundle(bundle.getBundleDescription(), false, null, null, null, null, null, null, null);
+ state.resolveBundle(bundle.getBundleDescription(), false, null, null, null, null, null, null, null, null);
stateResolveConstraints(bundle);
stateResolveBundle(bundle);
}
@@ -575,7 +579,7 @@ public class ResolverImpl implements Resolver {
continue;
}
List<ResolverBundle> collisionCandidates = new ArrayList<ResolverBundle>(sameBSN.size() - 1);
- List<Capability> capabilities = new ArrayList<Capability>(sameBSN.size() - 1);
+ List<BundleCapability> capabilities = new ArrayList<BundleCapability>(sameBSN.size() - 1);
for (ResolverBundle collision : sameBSN) {
if (collision == singleton || !collision.getBundleDescription().isSingleton() || !collision.isResolvable())
continue; // Ignore the bundle we are checking and non-singletons and non-resovlable
@@ -583,7 +587,7 @@ public class ResolverImpl implements Resolver {
capabilities.add(collision.getCapability());
}
if (hook != null)
- hook.filterSingletonCollisions(singleton.getCapability(), asCapabilities(new ArrayMap<Capability, ResolverBundle>(capabilities, collisionCandidates)));
+ hook.filterSingletonCollisions(singleton.getCapability(), asCapabilities(new ArrayMap<BundleCapability, ResolverBundle>(capabilities, collisionCandidates)));
if (collisionCandidates.isEmpty()) {
if (!selected.contains(singleton))
selected.add(singleton);
@@ -669,7 +673,7 @@ public class ResolverImpl implements Resolver {
continue;
if (!bundles[i].isResolved())
continue;
- if (!helper.giveExports(getExportsWiredTo(bundles[i]))) {
+ if (!helper.giveExports(getExportsWiredTo(bundles[i], null))) {
state.addResolverError(bundles[i].getBundleDescription(), ResolverError.DISABLED_BUNDLE, null, null);
bundles[i].setResolvable(false);
// We pass false for keepFragmentsAttached because we need to redo the attachments (bug 272561)
@@ -1123,8 +1127,8 @@ public class ResolverImpl implements Resolver {
}
@SuppressWarnings("unchecked")
- static Collection<Capability> asCapabilities(Collection<? extends Capability> capabilities) {
- return (Collection<Capability>) capabilities;
+ static Collection<BundleCapability> asCapabilities(Collection<? extends BundleCapability> capabilities) {
+ return (Collection<BundleCapability>) capabilities;
}
private void resolveFragment(ResolverBundle fragment) {
@@ -1292,7 +1296,7 @@ public class ResolverImpl implements Resolver {
else
capabilities = name == null || "*".equals(name) ? namespace.getAllValues() : namespace.get(name); //$NON-NLS-1$
List<GenericCapability> candidates = new ArrayList<GenericCapability>(capabilities);
- List<Capability> genCapabilities = new ArrayList<Capability>(candidates.size());
+ 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();
@@ -1303,7 +1307,7 @@ public class ResolverImpl implements Resolver {
}
}
if (hook != null)
- hook.filterMatches(constraint.getBundle().getBundleDescription(), asCapabilities(new ArrayMap<Capability, GenericCapability>(genCapabilities, candidates)));
+ hook.filterMatches(constraint.getRequirement(), asCapabilities(new ArrayMap<BundleCapability, GenericCapability>(genCapabilities, candidates)));
boolean result = false;
// We are left with only capabilities that satisfy the constraint.
for (GenericCapability capability : candidates) {
@@ -1351,7 +1355,7 @@ public class ResolverImpl implements Resolver {
}
List<ResolverBundle> bundles = resolverBundles.get(req.getVersionConstraint().getName());
List<ResolverBundle> candidates = new ArrayList<ResolverBundle>(bundles);
- List<Capability> capabilities = new ArrayList<Capability>(candidates.size());
+ 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();
@@ -1362,7 +1366,7 @@ public class ResolverImpl implements Resolver {
}
}
if (hook != null)
- hook.filterMatches(req.getBundle().getBundleDescription(), asCapabilities(new ArrayMap<Capability, ResolverBundle>(capabilities, candidates)));
+ hook.filterMatches(req.getRequirement(), asCapabilities(new ArrayMap<BundleCapability, ResolverBundle>(capabilities, candidates)));
// We are left with only capabilities that satisfy the require bundle.
boolean result = false;
for (ResolverBundle bundle : candidates) {
@@ -1418,7 +1422,7 @@ public class ResolverImpl implements Resolver {
ResolverExport[] substitutableExps = imp.getBundle().getExports(imp.getName());
List<ResolverExport> exports = resolverExports.get(imp.getName());
List<ResolverExport> candidates = new ArrayList<ResolverExport>(exports);
- List<Capability> capabilities = new ArrayList<Capability>(candidates.size());
+ 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();
@@ -1429,7 +1433,7 @@ public class ResolverImpl implements Resolver {
}
}
if (hook != null)
- hook.filterMatches(imp.getBundle().getBundleDescription(), asCapabilities(new ArrayMap<Capability, ResolverExport>(capabilities, candidates)));
+ hook.filterMatches(imp.getRequirement(), asCapabilities(new ArrayMap<BundleCapability, ResolverExport>(capabilities, candidates)));
// We are left with only capabilities that satisfy the import.
for (ResolverExport export : candidates) {
if (DEBUG_IMPORTS)
@@ -1583,6 +1587,10 @@ public class ResolverImpl implements Resolver {
stateResolveFragConstraints(rb);
else
stateResolveConstraints(rb);
+
+ // Build up the state wires
+ Map<String, List<StateWire>> stateWires = new HashMap<String, List<StateWire>>();
+
// Gather selected exports
ResolverExport[] exports = rb.getSelectedExports();
List<ExportPackageDescription> selectedExports = new ArrayList<ExportPackageDescription>(exports.length);
@@ -1601,15 +1609,22 @@ public class ResolverImpl implements Resolver {
ExportPackageDescription[] substitutedExportsArray = substitutedExports.toArray(new ExportPackageDescription[substitutedExports.size()]);
// Gather exports that have been wired to
- ExportPackageDescription[] exportsWiredToArray = getExportsWiredTo(rb);
+ ExportPackageDescription[] exportsWiredToArray = getExportsWiredTo(rb, stateWires);
// Gather bundles that have been wired to
BundleConstraint[] requires = rb.getRequires();
List<BundleDescription> bundlesWiredTo = new ArrayList<BundleDescription>(requires.length);
+ List<StateWire> requireWires = new ArrayList<StateWire>(requires.length);
for (int i = 0; i < requires.length; i++)
- if (requires[i].getSelectedSupplier() != null)
- bundlesWiredTo.add((BundleDescription) requires[i].getSelectedSupplier().getBaseDescription());
+ if (requires[i].getSelectedSupplier() != null) {
+ BundleDescription supplier = (BundleDescription) requires[i].getSelectedSupplier().getBaseDescription();
+ bundlesWiredTo.add(supplier);
+ StateWire requireWire = newStateWire(rb.getBundleDescription(), requires[i].getVersionConstraint(), supplier, supplier);
+ requireWires.add(requireWire);
+ }
BundleDescription[] bundlesWiredToArray = bundlesWiredTo.toArray(new BundleDescription[bundlesWiredTo.size()]);
+ if (!requireWires.isEmpty())
+ stateWires.put(BundleRevision.BUNDLE_NAMESPACE, requireWires);
GenericCapability[] capabilities = rb.getGenericCapabilities();
List<GenericDescription> selectedCapabilities = new ArrayList<GenericDescription>(capabilities.length);
@@ -1623,8 +1638,17 @@ public class ResolverImpl implements Resolver {
for (GenericConstraint genericConstraint : genericRequires) {
VersionSupplier[] matching = genericConstraint.getMatchingCapabilities();
if (matching != null)
- for (VersionSupplier capability : matching)
- resolvedGenericRequires.add(((GenericCapability) capability).getGenericDescription());
+ for (VersionSupplier capability : matching) {
+ GenericDescription supplier = ((GenericCapability) capability).getGenericDescription();
+ resolvedGenericRequires.add(supplier);
+ StateWire genericWire = newStateWire(rb.getBundleDescription(), genericConstraint.getVersionConstraint(), supplier.getSupplier(), supplier);
+ List<StateWire> genericWires = stateWires.get(genericConstraint.getNameSpace());
+ if (genericWires == null) {
+ genericWires = new ArrayList<StateWire>();
+ stateWires.put(genericConstraint.getNameSpace(), genericWires);
+ }
+ genericWires.add(genericWire);
+ }
}
GenericDescription[] capabilitiesWiredToArray = resolvedGenericRequires.toArray(new GenericDescription[resolvedGenericRequires.size()]);
@@ -1633,8 +1657,12 @@ public class ResolverImpl implements Resolver {
VersionSupplier[] matchingBundles = rb.getHost().getPossibleSuppliers();
if (matchingBundles != null && matchingBundles.length > 0) {
hostBundles = new BundleDescription[matchingBundles.length];
+ List<StateWire> hostWires = new ArrayList<StateWire>(matchingBundles.length);
+ stateWires.put(BundleRevision.HOST_NAMESPACE, hostWires);
for (int i = 0; i < matchingBundles.length; i++) {
hostBundles[i] = matchingBundles[i].getBundleDescription();
+ StateWire hostWire = newStateWire(rb.getBundleDescription(), rb.getHost().getVersionConstraint(), hostBundles[i], hostBundles[i]);
+ hostWires.add(hostWire);
if (hostBundles[i].isResolved()) {
ExportPackageDescription[] newSelectedExports = null;
GenericDescription[] newSelectedCapabilities = null;
@@ -1657,7 +1685,7 @@ public class ResolverImpl implements Resolver {
newSelectedCapabilities = hostBundles[i].getSelectedGenericCapabilities();
if (newSelectedExports == null)
newSelectedExports = hostBundles[i].getSelectedExports();
- state.resolveBundle(hostBundles[i], true, null, newSelectedExports, hostBundles[i].getSubstitutedExports(), newSelectedCapabilities, hostBundles[i].getResolvedRequires(), hostBundles[i].getResolvedImports(), hostBundles[i].getResolvedGenericRequires());
+ state.resolveBundle(hostBundles[i], true, null, newSelectedExports, hostBundles[i].getSubstitutedExports(), newSelectedCapabilities, hostBundles[i].getResolvedRequires(), hostBundles[i].getResolvedImports(), hostBundles[i].getResolvedGenericRequires(), ((BundleDescriptionImpl) hostBundles[i]).getWires());
}
}
}
@@ -1665,19 +1693,32 @@ public class ResolverImpl implements Resolver {
}
// Resolve the bundle in the state
- state.resolveBundle(rb.getBundleDescription(), rb.isResolved(), hostBundles, selectedExportsArray, substitutedExportsArray, selectedCapabilitiesArray, bundlesWiredToArray, exportsWiredToArray, capabilitiesWiredToArray);
+ state.resolveBundle(rb.getBundleDescription(), rb.isResolved(), hostBundles, selectedExportsArray, substitutedExportsArray, selectedCapabilitiesArray, bundlesWiredToArray, exportsWiredToArray, capabilitiesWiredToArray, stateWires);
}
- private static ExportPackageDescription[] getExportsWiredTo(ResolverBundle rb) {
+ private static ExportPackageDescription[] getExportsWiredTo(ResolverBundle rb, Map<String, List<StateWire>> stateWires) {
// Gather exports that have been wired to
ResolverImport[] imports = rb.getImportPackages();
List<ExportPackageDescription> exportsWiredTo = new ArrayList<ExportPackageDescription>(imports.length);
+ List<StateWire> importWires = new ArrayList<StateWire>(imports.length);
for (int i = 0; i < imports.length; i++)
- if (imports[i].getSelectedSupplier() != null)
- exportsWiredTo.add((ExportPackageDescription) imports[i].getSelectedSupplier().getBaseDescription());
+ if (imports[i].getSelectedSupplier() != null) {
+ ExportPackageDescription supplier = (ExportPackageDescription) imports[i].getSelectedSupplier().getBaseDescription();
+ exportsWiredTo.add(supplier);
+ StateWire wire = newStateWire(rb.getBundleDescription(), imports[i].getVersionConstraint(), supplier.getExporter(), supplier);
+ importWires.add(wire);
+ }
+ if (stateWires != null && !importWires.isEmpty())
+ stateWires.put(BundleRevision.PACKAGE_NAMESPACE, importWires);
return exportsWiredTo.toArray(new ExportPackageDescription[exportsWiredTo.size()]);
}
+ private static StateWire newStateWire(BundleDescription requirementHost, VersionConstraint declaredRequirement, BundleDescription capabilityHost, BaseDescription declaredCapability) {
+ BaseDescription fragDeclared = ((BaseDescriptionImpl) declaredCapability).getFragmentDeclaration();
+ declaredCapability = fragDeclared != null ? fragDeclared : declaredCapability;
+ return new StateWire(requirementHost, declaredRequirement, capabilityHost, declaredCapability);
+ }
+
// Resolve dynamic import
public synchronized ExportPackageDescription resolveDynamicImport(BundleDescription importingBundle, String requestedPackage) {
if (state == null)
@@ -1720,6 +1761,16 @@ public class ResolverImpl implements Resolver {
}
}
+ private void addStateWire(BundleDescription importingBundle, VersionConstraint requirement, BundleDescription capabilityHost, ExportPackageDescription capability) {
+ Map<String, List<StateWire>> wires = ((BundleDescriptionImpl) importingBundle).getWires();
+ List<StateWire> imports = wires.get(BundleRevision.PACKAGE_NAMESPACE);
+ if (imports == null) {
+ imports = new ArrayList<StateWire>();
+ wires.put(BundleRevision.PACKAGE_NAMESPACE, imports);
+ }
+ imports.add(newStateWire(importingBundle, requirement, capabilityHost, capability));
+ }
+
private ExportPackageDescription resolveDynamicImport(ResolverImport dynamicImport, String requestedPackage) {
String importName = dynamicImport.getName();
// If the import uses a wildcard, then temporarily replace this with the requested package
@@ -1742,7 +1793,11 @@ public class ResolverImpl implements Resolver {
// If the import resolved then return it's matching export
if (DEBUG_IMPORTS)
ResolverImpl.log("Resolved dynamic import: " + dynamicImport.getBundle() + ":" + dynamicImport.getName() + " -> " + ((ResolverExport) dynamicImport.getSelectedSupplier()).getExporter() + ":" + requestedPackage); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
- return ((ResolverExport) dynamicImport.getSelectedSupplier()).getExportPackageDescription();
+
+ ExportPackageDescription supplier = ((ResolverExport) dynamicImport.getSelectedSupplier()).getExportPackageDescription();
+ if (supplier != null)
+ addStateWire(dynamicImport.getBundleDescription(), dynamicImport.getVersionConstraint(), supplier.getExporter(), supplier);
+ return supplier;
}
}
dynamicImport.clearPossibleSuppliers();
@@ -1833,7 +1888,7 @@ public class ResolverImpl implements Resolver {
setBundleUnresolved(bundle, removed, false);
// Get bundles dependent on 'bundle'
BundleDescription[] dependents = bundle.getBundleDescription().getDependents();
- state.resolveBundle(bundle.getBundleDescription(), false, null, null, null, null, null, null, null);
+ state.resolveBundle(bundle.getBundleDescription(), false, null, null, null, null, null, null, null, null);
// Unresolve dependents of 'bundle'
for (int i = 0; i < dependents.length; i++)
unresolveBundle(bundleMapping.get(dependents[i]), false);
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/VersionHashMap.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/VersionHashMap.java
index 6b7be54b6..b27b03876 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/VersionHashMap.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/VersionHashMap.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2010 IBM Corporation and others.
+ * Copyright (c) 2004, 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
@@ -78,7 +78,7 @@ public class VersionHashMap<V extends VersionSupplier> extends MappedList<String
void reorder() {
for (Iterator<List<V>> it = internal.values().iterator(); it.hasNext();) {
List<V> existing = it.next();
- if (existing.size() > 0)
+ if (existing.size() > 1)
Collections.sort(existing, this);
}
}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/VersionSupplier.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/VersionSupplier.java
index 9ffdaeb91..03c94b021 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/VersionSupplier.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/VersionSupplier.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * Copyright (c) 2004, 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
@@ -13,14 +13,14 @@ package org.eclipse.osgi.internal.module;
import org.eclipse.osgi.service.resolver.BaseDescription;
import org.eclipse.osgi.service.resolver.BundleDescription;
import org.osgi.framework.Version;
-import org.osgi.framework.wiring.Capability;
+import org.osgi.framework.wiring.BundleCapability;
/*
* A companion to BaseDescription from the state used while resolving.
*/
public abstract class VersionSupplier {
final protected BaseDescription base;
- final private Capability capability;
+ final private BundleCapability capability;
private VersionSupplier substitute;
VersionSupplier(BaseDescription base) {
@@ -65,7 +65,7 @@ public abstract class VersionSupplier {
return base.toString();
}
- Capability getCapability() {
+ BundleCapability getCapability() {
return capability;
}
}
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 5d890cf3f..c158d325f 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2010 IBM Corporation and others.
+ * Copyright (c) 2004, 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
@@ -13,11 +13,11 @@ package org.eclipse.osgi.internal.resolver;
import java.util.*;
import org.eclipse.osgi.service.resolver.BaseDescription;
-import org.eclipse.osgi.service.resolver.BundleDescription;
import org.osgi.framework.Version;
-import org.osgi.framework.wiring.*;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRevision;
-abstract class BaseDescriptionImpl implements BaseDescription {
+public abstract class BaseDescriptionImpl implements BaseDescription {
protected final Object monitor = new Object();
@@ -84,24 +84,18 @@ abstract class BaseDescriptionImpl implements BaseDescription {
return null;
}
- WiredCapability getWiredCapability(String namespace) {
- if (namespace == null)
- namespace = getInternalNameSpace();
- if (namespace == null)
- return null;
-
- BundleDescription supplier = getSupplier();
- BundleWiring wiring = supplier.getBundleWiring();
- if (wiring == null)
- return null;
- return new BaseWiredCapability(namespace, wiring);
+ public BaseDescription getFragmentDeclaration() {
+ return null;
}
- public Capability getCapability() {
+ public BundleCapability getCapability() {
return getCapability(null);
}
- Capability getCapability(String namespace) {
+ BundleCapability getCapability(String namespace) {
+ BaseDescriptionImpl fragmentDeclaration = (BaseDescriptionImpl) getFragmentDeclaration();
+ if (fragmentDeclaration != null)
+ return fragmentDeclaration.getCapability(namespace);
if (namespace == null)
namespace = getInternalNameSpace();
if (namespace == null)
@@ -109,7 +103,7 @@ abstract class BaseDescriptionImpl implements BaseDescription {
return new BaseCapability(namespace);
}
- class BaseCapability implements Capability {
+ class BaseCapability implements BundleCapability {
private final String namespace;
public BaseCapability(String namespace) {
@@ -117,7 +111,7 @@ abstract class BaseDescriptionImpl implements BaseDescription {
this.namespace = namespace;
}
- public BundleRevision getProviderRevision() {
+ public BundleRevision getRevision() {
return getSupplier();
}
@@ -162,61 +156,4 @@ abstract class BaseDescriptionImpl implements BaseDescription {
return getNamespace() + BaseDescriptionImpl.toString(getAttributes(), false);
}
}
-
- class BaseWiredCapability extends BaseCapability implements WiredCapability {
- private final BundleWiring originalWiring;
-
- public BaseWiredCapability(String namespace, BundleWiring originalWiring) {
- super(namespace);
- this.originalWiring = originalWiring;
- }
-
- public Collection<BundleWiring> getRequirerWirings() {
- BundleWiring wiring = getProviderWiring();
- if (wiring == null)
- return null;
- BundleDescription supplier = getSupplier();
- BundleDescription[] dependents = supplier.getDependents();
- Collection<BundleWiring> requirers = new ArrayList<BundleWiring>();
- if (Capability.HOST_CAPABILITY.equals(getNamespace())) {
- // special casing osgi.host capability.
- // this is needed because the host capability is manufactured only for
- // representation in the wiring API. We need to represent a host wiring
- // as requiring its own osgi.host capability if it has attached fragments
- List<BundleRevision> fragments = wiring.getFragmentRevisions();
- if (fragments != null && fragments.size() > 0)
- // found at least one fragment add the host wiring as a requirer and return
- requirers.add(wiring);
- }
-
- for (BundleDescription dependent : dependents) {
- BundleWiring dependentWiring = dependent.getBundleWiring();
- if (dependentWiring == null) // fragments have no wiring
- continue;
- List<WiredCapability> namespace = dependentWiring.getRequiredCapabilities(getNamespace());
- if (namespace == null)
- continue;
- if (namespace.contains(this))
- requirers.add(dependentWiring);
- }
- return requirers;
- }
-
- public BundleWiring getProviderWiring() {
- return originalWiring.isInUse() ? originalWiring : null;
- }
-
- public int hashCode() {
- return System.identityHashCode(BaseDescriptionImpl.this) ^ System.identityHashCode(originalWiring);
- }
-
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (!(obj instanceof BaseWiredCapability))
- return false;
- BaseWiredCapability other = (BaseWiredCapability) obj;
- return (other.originalWiring == this.originalWiring) && super.equals(obj);
- }
- }
}
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 a3ab615f6..efcc81c76 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2010 IBM Corporation and others.
+ * Copyright (c) 2003, 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
@@ -47,7 +47,7 @@ public final class BundleDescriptionImpl extends BaseDescriptionImpl implements
private volatile int stateBits = FULLY_LOADED | ATTACH_FRAGMENTS | DYNAMIC_FRAGMENTS;
private volatile long bundleId = -1;
- private volatile HostSpecification host; //null if the bundle is not a fragment. volatile to allow unsynchronized checks for null
+ 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;
@@ -257,6 +257,23 @@ public final class BundleDescriptionImpl extends BaseDescriptionImpl implements
}
}
+ public Map<String, List<StateWire>> getWires() {
+ LazyData currentData = loadLazyData();
+ synchronized (this.monitor) {
+ if (currentData.stateWires == null) {
+ currentData.stateWires = new HashMap<String, List<StateWire>>(0);
+ }
+ return currentData.stateWires;
+ }
+ }
+
+ Map<String, List<StateWire>> getWiresInternal() {
+ LazyData currentData = loadLazyData();
+ synchronized (this.monitor) {
+ return currentData.stateWires;
+ }
+ }
+
protected void setBundleId(long bundleId) {
this.bundleId = bundleId;
}
@@ -461,6 +478,13 @@ public final class BundleDescriptionImpl extends BaseDescriptionImpl implements
}
}
+ protected void setStateWires(Map<String, List<StateWire>> stateWires) {
+ synchronized (this.monitor) {
+ checkLazyData();
+ lazyData.stateWires = stateWires;
+ }
+ }
+
void clearAddedDynamicImportPackages() {
synchronized (this.monitor) {
checkLazyData();
@@ -792,6 +816,7 @@ public final class BundleDescriptionImpl extends BaseDescriptionImpl implements
String[] executionEnvironments;
Map<String, Long> dynamicStamps;
+ Map<String, List<StateWire>> stateWires;
// Note that this is not persisted in the state cache
List<ImportPackageSpecification> addedDynamicImports;
}
@@ -856,37 +881,61 @@ public final class BundleDescriptionImpl extends BaseDescriptionImpl implements
if (attributes != null)
result.putAll(attributes);
}
- result.put(Capability.BUNDLE_CAPABILITY, getName());
+ result.put(BundleRevision.BUNDLE_NAMESPACE, getName());
result.put(Constants.BUNDLE_VERSION_ATTRIBUTE, getVersion());
return Collections.unmodifiableMap(result);
}
- public List<Capability> getDeclaredCapabilities(String namespace) {
- List<Capability> result = new ArrayList<Capability>();
+ public List<BundleRequirement> getDeclaredRequirements(String namespace) {
+ List<BundleRequirement> result = new ArrayList<BundleRequirement>();
+ if (namespace == null || BundleRevision.BUNDLE_NAMESPACE.equals(namespace)) {
+ BundleSpecification[] requires = getRequiredBundles();
+ for (BundleSpecification require : requires) {
+ result.add(require.getRequirement());
+ }
+ }
+ if (host != null && (namespace == null || BundleRevision.HOST_NAMESPACE.equals(namespace))) {
+ result.add(host.getRequirement());
+ }
+ if (namespace == null || BundleRevision.PACKAGE_NAMESPACE.equals(namespace)) {
+ ImportPackageSpecification[] imports = getImportPackages();
+ for (ImportPackageSpecification importPkg : imports)
+ result.add(importPkg.getRequirement());
+ }
+ GenericSpecification[] genericSpecifications = getGenericRequires();
+ for (GenericSpecification requirement : genericSpecifications) {
+ if (namespace == null || namespace.equals(requirement.getType()))
+ result.add(requirement.getRequirement());
+ }
+ return Collections.unmodifiableList(result);
+ }
+
+ public List<BundleCapability> getDeclaredCapabilities(String namespace) {
+ List<BundleCapability> result = new ArrayList<BundleCapability>();
if (host == null) {
if (getSymbolicName() != null) {
- if (namespace == null || Capability.BUNDLE_CAPABILITY.equals(namespace)) {
+ if (namespace == null || BundleRevision.BUNDLE_NAMESPACE.equals(namespace)) {
result.add(BundleDescriptionImpl.this.getCapability());
}
- if (attachFragments() && (namespace == null || Capability.HOST_CAPABILITY.equals(namespace))) {
- result.add(BundleDescriptionImpl.this.getCapability(Capability.HOST_CAPABILITY));
+ if (attachFragments() && (namespace == null || BundleRevision.HOST_NAMESPACE.equals(namespace))) {
+ result.add(BundleDescriptionImpl.this.getCapability(BundleRevision.HOST_NAMESPACE));
}
}
} else {
- // may need to have a osgi.fragment capability
+ // may need to have a osgi.wiring.fragment capability
}
- if (namespace == null || Capability.PACKAGE_CAPABILITY.equals(namespace)) {
+ if (namespace == null || BundleRevision.PACKAGE_NAMESPACE.equals(namespace)) {
ExportPackageDescription[] exports = getExportPackages();
- for (ExportPackageDescription importPkg : exports)
- result.add(importPkg.getCapability());
+ for (ExportPackageDescription exportPkg : exports)
+ result.add(exportPkg.getCapability());
}
GenericDescription[] genericCapabilities = getGenericCapabilities();
for (GenericDescription capabilitiy : genericCapabilities) {
if (namespace == null || namespace.equals(capabilitiy.getType()))
result.add(capabilitiy.getCapability());
}
- return result;
+ return Collections.unmodifiableList(result);
}
public int getTypes() {
@@ -901,17 +950,72 @@ public final class BundleDescriptionImpl extends BaseDescriptionImpl implements
}
String getInternalNameSpace() {
- return Capability.BUNDLE_CAPABILITY;
+ return BundleRevision.BUNDLE_NAMESPACE;
}
- public BundleWiring getBundleWiring() {
+ public BundleWiring getWiring() {
synchronized (this.monitor) {
- if (bundleWiring != null || !isResolved() || (getTypes() & BundleRevision.TYPE_FRAGMENT) != 0)
+ if (bundleWiring != null || !isResolved())
return bundleWiring;
return bundleWiring = new DescriptionWiring();
}
}
+ static class BundleWireImpl implements BundleWire {
+ private final BundleCapability capability;
+ private final BundleWiring provider;
+ private final BundleRequirement requirement;
+ private final BundleWiring requirer;
+
+ public BundleWireImpl(StateWire wire) {
+ VersionConstraint declaredRequirement = wire.getDeclaredRequirement();
+ if (declaredRequirement instanceof HostSpecification)
+ this.capability = ((BaseDescriptionImpl) wire.getDeclaredCapability()).getCapability(BundleRevision.HOST_NAMESPACE);
+ else
+ this.capability = wire.getDeclaredCapability().getCapability();
+ this.provider = wire.getCapabilityHost().getWiring();
+ this.requirement = declaredRequirement.getRequirement();
+ this.requirer = wire.getRequirementHost().getWiring();
+ }
+
+ public BundleCapability getCapability() {
+ return capability;
+ }
+
+ public BundleRequirement getRequirement() {
+ return requirement;
+ }
+
+ public BundleWiring getProviderWiring() {
+ return provider;
+ }
+
+ public BundleWiring getRequirerWiring() {
+ return requirer;
+ }
+
+ @Override
+ public int hashCode() {
+ int hashcode = 31 + capability.hashCode();
+ hashcode = hashcode * 31 + requirement.hashCode();
+ hashcode = hashcode * 31 + provider.hashCode();
+ hashcode = hashcode * 31 + requirer.hashCode();
+ return hashcode;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof BundleWireImpl))
+ return false;
+ BundleWireImpl other = (BundleWireImpl) obj;
+ return capability.equals(other.getCapability()) && requirement.equals(other.getRequirement()) && provider.equals(other.getProviderWiring()) && requirer.equals(other.getRequirerWiring());
+ }
+
+ public String toString() {
+ return getRequirement() + " -> " + getCapability(); //$NON-NLS-1$
+ }
+ }
+
// Note that description wiring are identity equality based
class DescriptionWiring implements BundleWiring {
private volatile boolean valid = true;
@@ -932,69 +1036,115 @@ public final class BundleDescriptionImpl extends BaseDescriptionImpl implements
return valid && !BundleDescriptionImpl.this.isRemovalPending();
}
- public List<WiredCapability> getRequiredCapabilities(String capabilityNamespace) {
+ public List<BundleCapability> getCapabilities(String namespace) {
if (!isInUse())
return null;
- List<WiredCapability> result = new ArrayList<WiredCapability>();
- if (capabilityNamespace == null || Capability.BUNDLE_CAPABILITY.equals(capabilityNamespace)) {
- BundleDescription[] requires = getResolvedRequires();
- for (BundleDescription require : requires)
- result.add(((BaseDescriptionImpl) require).getWiredCapability(null));
- }
- if (attachFragments() && (capabilityNamespace == null || Capability.HOST_CAPABILITY.equals(capabilityNamespace))) {
- Collection<BundleRevision> fragments = getFragmentRevisions();
- if (fragments.size() > 0)
- result.add(BundleDescriptionImpl.this.getWiredCapability(Capability.HOST_CAPABILITY));
+ @SuppressWarnings("unchecked")
+ List<BundleCapability> result = Collections.EMPTY_LIST;
+ if (host != null)
+ return result;
+ result = new ArrayList<BundleCapability>();
+ if (getSymbolicName() != null) {
+ if (namespace == null || BundleRevision.BUNDLE_NAMESPACE.equals(namespace)) {
+ result.add(BundleDescriptionImpl.this.getCapability());
+ }
+ if (attachFragments() && (namespace == null || BundleRevision.HOST_NAMESPACE.equals(namespace))) {
+ result.add(BundleDescriptionImpl.this.getCapability(BundleRevision.HOST_NAMESPACE));
+ }
}
- if (capabilityNamespace == null || Capability.PACKAGE_CAPABILITY.equals(capabilityNamespace)) {
- ExportPackageDescription[] imports = getResolvedImports();
- for (ExportPackageDescription importPkg : imports)
- result.add(((BaseDescriptionImpl) importPkg).getWiredCapability(null));
+ if (namespace == null || BundleRevision.PACKAGE_NAMESPACE.equals(namespace)) {
+ ExportPackageDescription[] exports = getSelectedExports();
+ for (ExportPackageDescription exportPkg : exports)
+ result.add(exportPkg.getCapability());
}
- GenericDescription[] genericRequires = getResolvedGenericRequires();
- for (GenericDescription require : genericRequires) {
- if (capabilityNamespace == null || capabilityNamespace.equals(require.getType()))
- result.add(((BaseDescriptionImpl) require).getWiredCapability(null));
+ GenericDescription[] genericCapabilities = getSelectedGenericCapabilities();
+ for (GenericDescription capabilitiy : genericCapabilities) {
+ if (namespace == null || namespace.equals(capabilitiy.getType()))
+ result.add(capabilitiy.getCapability());
}
return result;
}
- public List<WiredCapability> getProvidedCapabilities(String capabilityNamespace) {
- if (!isInUse())
+ public List<BundleRequirement> getRequirements(String namespace) {
+ List<BundleWire> requiredWires = getRequiredWires(namespace);
+ if (requiredWires == null)
+ // happens if not in use
return null;
- List<WiredCapability> result = new ArrayList<WiredCapability>();
- if (getSymbolicName() != null) {
- if ((capabilityNamespace == null || Capability.BUNDLE_CAPABILITY.equals(capabilityNamespace)))
- result.add(BundleDescriptionImpl.this.getWiredCapability(null));
- if (attachFragments() && (capabilityNamespace == null || Capability.HOST_CAPABILITY.endsWith(capabilityNamespace)))
- result.add(BundleDescriptionImpl.this.getWiredCapability(Capability.HOST_CAPABILITY));
+ List<BundleRequirement> requirements = new ArrayList<BundleRequirement>(requiredWires.size());
+ for (BundleWire wire : requiredWires) {
+ if (!requirements.contains(wire.getRequirement()))
+ requirements.add(wire.getRequirement());
+ }
+ // get dynamic imports
+ if (namespace == null || BundleRevision.PACKAGE_NAMESPACE.equals(namespace)) {
+ if (hasDynamicImports()) {
+ ImportPackageSpecification[] imports = getImportPackages();
+ for (ImportPackageSpecification impPackage : imports) {
+ if (ImportPackageSpecification.RESOLUTION_DYNAMIC.equals(impPackage.getDirective(Constants.RESOLUTION_DIRECTIVE))) {
+ BundleRequirement req = impPackage.getRequirement();
+ if (!requirements.contains(req))
+ requirements.add(req);
+ }
+ }
+ }
}
+ return requirements;
+ }
- if (capabilityNamespace == null || Capability.PACKAGE_CAPABILITY.equals(capabilityNamespace)) {
- ExportPackageDescription[] exports = getSelectedExports();
- for (ExportPackageDescription importPkg : exports)
- result.add(((BaseDescriptionImpl) importPkg).getWiredCapability(null));
+ public List<BundleWire> getProvidedWires(String namespace) {
+ if (!isInUse())
+ return null;
+ BundleDescription[] dependentBundles = getDependents();
+ List<BundleWire> unorderedResult = new ArrayList<BundleWire>();
+ for (BundleDescription dependent : dependentBundles) {
+ List<BundleWire> dependentWires = dependent.getWiring().getRequiredWires(namespace);
+ if (dependentWires != null)
+ for (BundleWire bundleWire : dependentWires) {
+ if (bundleWire.getProviderWiring() == this)
+ unorderedResult.add(bundleWire);
+ }
}
- GenericDescription[] genericCapabilities = getSelectedGenericCapabilities();
- for (GenericDescription capabilitiy : genericCapabilities) {
- if (capabilityNamespace == null || capabilityNamespace.equals(capabilitiy.getType()))
- result.add(((BaseDescriptionImpl) capabilitiy).getWiredCapability(null));
+ List<BundleWire> orderedResult = new ArrayList<BundleWire>(unorderedResult.size());
+ List<BundleCapability> capabilities = getCapabilities(namespace);
+ for (BundleCapability capability : capabilities) {
+ for (Iterator<BundleWire> wires = unorderedResult.iterator(); wires.hasNext();) {
+ BundleWire wire = wires.next();
+ if (wire.getCapability().equals(capability)) {
+ wires.remove();
+ orderedResult.add(wire);
+ }
+ }
}
- return result;
+ return orderedResult;
}
- public List<BundleRevision> getFragmentRevisions() {
+ public List<BundleWire> getRequiredWires(String namespace) {
if (!isInUse())
return null;
- List<BundleRevision> results = new ArrayList<BundleRevision>();
- BundleDescription[] deps = getDependents();
- for (BundleDescription dependent : deps) {
- if (dependent.getHost() != null) {
- // found a fragment
- results.add(dependent);
+ @SuppressWarnings("unchecked")
+ List<BundleWire> result = Collections.EMPTY_LIST;
+ Map<String, List<StateWire>> wireMap = getWires();
+ if (namespace == null) {
+ result = new ArrayList<BundleWire>();
+ for (List<StateWire> wires : wireMap.values()) {
+ for (StateWire wire : wires) {
+ result.add(new BundleWireImpl(wire));
+ }
}
+ return result;
+ }
+ List<StateWire> wires = wireMap.get(namespace);
+ if (wires == null)
+ return result;
+ result = new ArrayList<BundleWire>(wires.size());
+ for (StateWire wire : wires) {
+ result.add(new BundleWireImpl(wire));
}
- return results;
+ return result;
+ }
+
+ public BundleRevision getRevision() {
+ return BundleDescriptionImpl.this;
}
public ClassLoader getClassLoader() {
@@ -1019,10 +1169,6 @@ public final class BundleDescriptionImpl extends BaseDescriptionImpl implements
return null;
}
- public BundleRevision getBundleRevision() {
- return BundleDescriptionImpl.this;
- }
-
private boolean hasResourcePermission() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleSpecificationImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleSpecificationImpl.java
index 01e350b36..630313186 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleSpecificationImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleSpecificationImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2008 IBM Corporation and others.
+ * Copyright (c) 2003, 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
@@ -11,10 +11,10 @@
*******************************************************************************/
package org.eclipse.osgi.internal.resolver;
-import java.util.Map;
-import org.eclipse.osgi.service.resolver.BaseDescription;
-import org.eclipse.osgi.service.resolver.BundleSpecification;
+import java.util.*;
+import org.eclipse.osgi.service.resolver.*;
import org.osgi.framework.Constants;
+import org.osgi.framework.wiring.BundleRevision;
public class BundleSpecificationImpl extends VersionConstraintImpl implements BundleSpecification {
private boolean exported;
@@ -93,4 +93,36 @@ public class BundleSpecificationImpl extends VersionConstraintImpl implements Bu
public String toString() {
return "Require-Bundle: " + getName() + "; bundle-version=\"" + getVersionRange() + "\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
+
+ @Override
+ protected Map<String, String> getInternalDirectives() {
+ Map<String, String> result = new HashMap<String, String>(2);
+ synchronized (this.monitor) {
+ if (exported)
+ result.put(Constants.VISIBILITY_DIRECTIVE, Constants.VISIBILITY_REEXPORT);
+ if (optional)
+ result.put(Constants.RESOLUTION_DIRECTIVE, Constants.RESOLUTION_OPTIONAL);
+ return Collections.unmodifiableMap(result);
+ }
+ }
+
+ @Override
+ protected Map<String, Object> getInteralAttributes() {
+ Map<String, Object> result = new HashMap<String, Object>(2);
+ synchronized (this.monitor) {
+ if (attributes != null)
+ result.putAll(attributes);
+ result.put(BundleRevision.BUNDLE_NAMESPACE, getName());
+ VersionRange range = getVersionRange();
+ if (range != null)
+ result.put(Constants.BUNDLE_VERSION_ATTRIBUTE, range.toString());
+ return Collections.unmodifiableMap(result);
+ }
+ }
+
+ @Override
+ protected String getInternalNameSpace() {
+ // TODO Auto-generated method stub
+ return BundleRevision.BUNDLE_NAMESPACE;
+ }
}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ExportPackageDescriptionImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ExportPackageDescriptionImpl.java
index 6863b681a..a76444518 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ExportPackageDescriptionImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ExportPackageDescriptionImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2010 IBM Corporation and others.
+ * Copyright (c) 2004, 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
@@ -14,10 +14,9 @@ package org.eclipse.osgi.internal.resolver;
import java.util.*;
import org.eclipse.osgi.framework.internal.core.Constants;
-import org.eclipse.osgi.service.resolver.BundleDescription;
-import org.eclipse.osgi.service.resolver.ExportPackageDescription;
+import org.eclipse.osgi.service.resolver.*;
import org.osgi.framework.Version;
-import org.osgi.framework.wiring.Capability;
+import org.osgi.framework.wiring.BundleRevision;
public class ExportPackageDescriptionImpl extends BaseDescriptionImpl implements ExportPackageDescription {
public static final String EQUINOX_EE = "x-equinox-ee"; //$NON-NLS-1$
@@ -31,7 +30,20 @@ public class ExportPackageDescriptionImpl extends BaseDescriptionImpl implements
private String[] mandatory;
private Boolean internal = Boolean.FALSE;
private int equinox_ee = -1;
- private volatile int tableIndex;
+ private ExportPackageDescription fragmentDeclaration = null;
+
+ public ExportPackageDescriptionImpl() {
+ super();
+ }
+
+ public ExportPackageDescriptionImpl(BundleDescription host, ExportPackageDescription fragmentDeclaration) {
+ setName(fragmentDeclaration.getName());
+ setVersion(fragmentDeclaration.getVersion());
+ setDirectives(fragmentDeclaration.getDirectives());
+ setAttributes(fragmentDeclaration.getAttributes());
+ setExporter(host);
+ this.fragmentDeclaration = fragmentDeclaration;
+ }
public Map<String, Object> getDirectives() {
synchronized (this.monitor) {
@@ -76,7 +88,7 @@ public class ExportPackageDescriptionImpl extends BaseDescriptionImpl implements
synchronized (this.monitor) {
if (attributes != null)
result.putAll(attributes);
- result.put(Capability.PACKAGE_CAPABILITY, getName());
+ result.put(BundleRevision.PACKAGE_NAMESPACE, getName());
result.put(Constants.VERSION_ATTRIBUTE, getVersion());
Version bundleVersion = getSupplier().getVersion();
if (bundleVersion != null)
@@ -185,19 +197,19 @@ public class ExportPackageDescriptionImpl extends BaseDescriptionImpl implements
this.exporter = exporter;
}
- public String toString() {
- return "Export-Package: " + getName() + "; version=\"" + getVersion() + "\""; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+ public BaseDescription getFragmentDeclaration() {
+ return fragmentDeclaration;
}
- int getTableIndex() {
- return tableIndex;
+ void setFragmentDeclaration(ExportPackageDescription fragmentDeclaration) {
+ this.fragmentDeclaration = fragmentDeclaration;
}
- void setTableIndex(int tableIndex) {
- this.tableIndex = tableIndex;
+ public String toString() {
+ return "Export-Package: " + getName() + "; version=\"" + getVersion() + "\""; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
}
String getInternalNameSpace() {
- return Capability.PACKAGE_CAPABILITY;
+ return BundleRevision.PACKAGE_NAMESPACE;
}
}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/GenericDescriptionImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/GenericDescriptionImpl.java
index b53c563d9..9e438f033 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/GenericDescriptionImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/GenericDescriptionImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2010 IBM Corporation and others.
+ * Copyright (c) 2006, 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
@@ -12,8 +12,7 @@
package org.eclipse.osgi.internal.resolver;
import java.util.*;
-import org.eclipse.osgi.service.resolver.BundleDescription;
-import org.eclipse.osgi.service.resolver.GenericDescription;
+import org.eclipse.osgi.service.resolver.*;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
@@ -22,6 +21,29 @@ public class GenericDescriptionImpl extends BaseDescriptionImpl implements Gener
private volatile BundleDescription supplier;
private volatile String type = GenericDescription.DEFAULT_TYPE;
private Map<String, String> directives;
+ private GenericDescription fragmentDeclaration;
+
+ public GenericDescriptionImpl() {
+ super();
+ }
+
+ public GenericDescriptionImpl(BundleDescription host, GenericDescription fragmentDeclaration) {
+ setType(fragmentDeclaration.getType());
+ Dictionary<String, Object> origAttrs = fragmentDeclaration.getAttributes();
+ if (origAttrs != null) {
+ Hashtable<String, Object> copyAttrs = new Hashtable<String, Object>();
+ for (Enumeration<String> keys = origAttrs.keys(); keys.hasMoreElements();) {
+ String key = keys.nextElement();
+ copyAttrs.put(key, origAttrs.get(key));
+ }
+ setAttributes(copyAttrs);
+ }
+ Map<String, String> origDirectives = fragmentDeclaration.getDeclaredDirectives();
+ Map<String, String> copyDirectives = new HashMap<String, String>(origDirectives);
+ setDirectives(copyDirectives);
+ setSupplier(host);
+ this.fragmentDeclaration = fragmentDeclaration;
+ }
public Dictionary<String, Object> getAttributes() {
synchronized (this.monitor) {
@@ -113,4 +135,12 @@ public class GenericDescriptionImpl extends BaseDescriptionImpl implements Gener
String getInternalNameSpace() {
return getType();
}
+
+ public BaseDescription getFragmentDeclaration() {
+ return fragmentDeclaration;
+ }
+
+ void setFragmentDeclaration(GenericDescription fragmentDeclaration) {
+ this.fragmentDeclaration = fragmentDeclaration;
+ }
}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/GenericSpecificationImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/GenericSpecificationImpl.java
index c919258fa..2afacb7e5 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/GenericSpecificationImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/GenericSpecificationImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2010 IBM Corporation and others.
+ * Copyright (c) 2006, 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
@@ -11,6 +11,7 @@
*******************************************************************************/
package org.eclipse.osgi.internal.resolver;
+import java.util.*;
import org.eclipse.osgi.framework.internal.core.FilterImpl;
import org.eclipse.osgi.service.resolver.*;
import org.osgi.framework.*;
@@ -127,4 +128,28 @@ public class GenericSpecificationImpl extends VersionConstraintImpl implements G
this.suppliers = suppliers;
}
}
+
+ @Override
+ protected Map<String, String> getInternalDirectives() {
+ Map<String, String> result = new HashMap<String, String>(2);
+ synchronized (this.monitor) {
+ if ((resolution & GenericSpecification.RESOLUTION_OPTIONAL) != 0)
+ result.put(Constants.RESOLUTION_DIRECTIVE, Constants.RESOLUTION_OPTIONAL);
+ if (matchingFilter != null) {
+ result.put(Constants.FILTER_DIRECTIVE, matchingFilter.toString());
+ }
+ }
+ return Collections.unmodifiableMap(result);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected Map<String, Object> getInteralAttributes() {
+ return Collections.EMPTY_MAP;
+ }
+
+ @Override
+ protected String getInternalNameSpace() {
+ return getType();
+ }
}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/HostSpecificationImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/HostSpecificationImpl.java
index 527e77620..e433fa74c 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/HostSpecificationImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/HostSpecificationImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2008 IBM Corporation and others.
+ * Copyright (c) 2003, 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
@@ -12,9 +12,10 @@
package org.eclipse.osgi.internal.resolver;
-import java.util.Map;
+import java.util.*;
import org.eclipse.osgi.service.resolver.*;
import org.osgi.framework.Constants;
+import org.osgi.framework.wiring.BundleRevision;
public class HostSpecificationImpl extends VersionConstraintImpl implements HostSpecification {
@@ -111,4 +112,28 @@ public class HostSpecificationImpl extends VersionConstraintImpl implements Host
this.multihost = multihost;
}
}
+
+ @SuppressWarnings("unchecked")
+ protected Map<String, String> getInternalDirectives() {
+ // TODO this does not handle extension directive; but we do not support bootclasspath anyway
+ return Collections.EMPTY_MAP;
+ }
+
+ protected Map<String, Object> getInteralAttributes() {
+ Map<String, Object> result = new HashMap<String, Object>(2);
+ synchronized (this.monitor) {
+ if (attributes != null)
+ result.putAll(attributes);
+ result.put(BundleRevision.HOST_NAMESPACE, getName());
+ VersionRange range = getVersionRange();
+ if (range != null)
+ result.put(Constants.BUNDLE_VERSION_ATTRIBUTE, range.toString());
+ return Collections.unmodifiableMap(result);
+ }
+ }
+
+ @Override
+ protected String getInternalNameSpace() {
+ return BundleRevision.HOST_NAMESPACE;
+ }
}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ImportPackageSpecificationImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ImportPackageSpecificationImpl.java
index edf3107e2..6d34edd7f 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ImportPackageSpecificationImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ImportPackageSpecificationImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2008 IBM Corporation and others.
+ * Copyright (c) 2003, 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
@@ -15,6 +15,7 @@ package org.eclipse.osgi.internal.resolver;
import java.util.*;
import org.eclipse.osgi.framework.internal.core.Constants;
import org.eclipse.osgi.service.resolver.*;
+import org.osgi.framework.wiring.BundleRevision;
public class ImportPackageSpecificationImpl extends VersionConstraintImpl implements ImportPackageSpecification {
private String resolution = ImportPackageSpecification.RESOLUTION_STATIC; // the default is static
@@ -182,4 +183,32 @@ public class ImportPackageSpecificationImpl extends VersionConstraintImpl implem
public String toString() {
return "Import-Package: " + getName() + "; version=\"" + getVersionRange() + "\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
+
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ protected Map<String, String> getInternalDirectives() {
+ Map raw = getDirectives();
+ return Collections.unmodifiableMap(raw);
+ }
+
+ protected Map<String, Object> getInteralAttributes() {
+ Map<String, Object> result = new HashMap<String, Object>(2);
+ synchronized (this.monitor) {
+ if (attributes != null)
+ result.putAll(attributes);
+ result.put(BundleRevision.PACKAGE_NAMESPACE, getName());
+ VersionRange range = getVersionRange();
+ if (range != null)
+ result.put(Constants.VERSION_ATTRIBUTE, range.toString());
+ if (symbolicName != null)
+ result.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, symbolicName);
+ if (bundleVersionRange != null)
+ result.put(Constants.BUNDLE_VERSION_ATTRIBUTE, bundleVersionRange.toString());
+ return Collections.unmodifiableMap(result);
+ }
+ }
+
+ @Override
+ protected String getInternalNameSpace() {
+ return BundleRevision.PACKAGE_NAMESPACE;
+ }
}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/NativeCodeSpecificationImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/NativeCodeSpecificationImpl.java
index 9a808e8d5..ee15b9edd 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/NativeCodeSpecificationImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/NativeCodeSpecificationImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2008 IBM Corporation and others.
+ * Copyright (c) 2007, 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
@@ -156,4 +156,19 @@ public class NativeCodeSpecificationImpl extends VersionConstraintImpl implement
return sb.toString();
}
+
+ @SuppressWarnings("unchecked")
+ protected Map<String, String> getInternalDirectives() {
+ return Collections.EMPTY_MAP;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected Map<String, Object> getInteralAttributes() {
+ return Collections.EMPTY_MAP;
+ }
+
+ @Override
+ protected String getInternalNameSpace() {
+ return null;
+ }
}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ReadOnlyState.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ReadOnlyState.java
index a1d91c352..d0bc359ae 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ReadOnlyState.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ReadOnlyState.java
@@ -12,8 +12,7 @@
*******************************************************************************/
package org.eclipse.osgi.internal.resolver;
-import java.util.Collection;
-import java.util.Dictionary;
+import java.util.*;
import org.eclipse.osgi.service.resolver.*;
import org.osgi.framework.BundleException;
import org.osgi.framework.Version;
@@ -133,7 +132,7 @@ public final class ReadOnlyState implements State {
throw new UnsupportedOperationException();
}
- public void resolveBundle(BundleDescription bundle, boolean status, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, ExportPackageDescription[] substitutedExports, GenericDescription[] selectedCapabilities, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports, GenericDescription[] resolveCapabilities) {
+ public void resolveBundle(BundleDescription bundle, boolean status, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, ExportPackageDescription[] substitutedExports, GenericDescription[] selectedCapabilities, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports, GenericDescription[] resolvedCapabilities, Map<String, List<StateWire>> resolvedRequirements) {
throw new UnsupportedOperationException();
}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateHelperImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateHelperImpl.java
index de1db0560..131d7dd67 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateHelperImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateHelperImpl.java
@@ -17,8 +17,8 @@ import org.eclipse.osgi.internal.baseadaptor.ArrayMap;
import org.eclipse.osgi.service.resolver.*;
import org.osgi.framework.hooks.resolver.ResolverHook;
import org.osgi.framework.hooks.resolver.ResolverHookFactory;
+import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.Capability;
/**
* An implementation for the StateHelper API. Access to this implementation is
@@ -125,7 +125,7 @@ public final class StateHelperImpl implements StateHelper {
Collection<BaseDescription> satisfied = null;
if (constraint instanceof BundleSpecification || constraint instanceof HostSpecification) {
BundleDescription[] suppliers = state.getBundles(constraint.getName());
- satisfied = getPossibleCandidates(constraint, suppliers, constraint instanceof HostSpecification ? Capability.HOST_CAPABILITY : null, hook, false);
+ satisfied = getPossibleCandidates(constraint, suppliers, constraint instanceof HostSpecification ? BundleRevision.HOST_NAMESPACE : null, hook, false);
} else if (constraint instanceof ImportPackageSpecification) {
List<ExportPackageDescription> exports = packages.get(constraint.getName());
if (exports != null)
@@ -194,7 +194,7 @@ public final class StateHelperImpl implements StateHelper {
List<VersionConstraint> unsatisfied = new ArrayList<VersionConstraint>();
HostSpecification host = bundle.getHost();
if (host != null)
- if (!host.isResolved() && !isBundleConstraintResolvable(host, Capability.HOST_CAPABILITY, hook))
+ if (!host.isResolved() && !isBundleConstraintResolvable(host, BundleRevision.HOST_NAMESPACE, hook))
unsatisfied.add(host);
BundleSpecification[] requiredBundles = bundle.getRequiredBundles();
for (int i = 0; i < requiredBundles.length; i++)
@@ -214,11 +214,11 @@ public final class StateHelperImpl implements StateHelper {
return unsatisfied.toArray(new VersionConstraint[unsatisfied.size()]);
}
- private ArrayMap<Capability, BaseDescription> asArrayMap(List<BaseDescription> descriptions, String namespace) {
- List<Capability> capabilities = new ArrayList<Capability>(descriptions.size());
+ private ArrayMap<BundleCapability, BaseDescription> asArrayMap(List<BaseDescription> descriptions, String namespace) {
+ List<BundleCapability> capabilities = new ArrayList<BundleCapability>(descriptions.size());
for (BaseDescription description : descriptions)
capabilities.add(((BaseDescriptionImpl) description).getCapability(namespace));
- return new ArrayMap<Capability, BaseDescription>(capabilities, descriptions);
+ return new ArrayMap<BundleCapability, BaseDescription>(capabilities, descriptions);
}
private List<BaseDescription> getPossibleCandidates(VersionConstraint constraint, BaseDescription[] descriptions, String namespace, ResolverHook hook, boolean resolved) {
@@ -227,7 +227,7 @@ public final class StateHelperImpl implements StateHelper {
if ((!resolved || descriptions[i].getSupplier().isResolved()) && constraint.isSatisfiedBy(descriptions[i]))
candidates.add(descriptions[i]);
if (hook != null)
- hook.filterMatches(constraint.getBundle(), asArrayMap(candidates, namespace));
+ hook.filterMatches(constraint.getRequirement(), asArrayMap(candidates, namespace));
return candidates;
}
@@ -268,7 +268,7 @@ public final class StateHelperImpl implements StateHelper {
* @see StateHelper
*/
public boolean isResolvable(HostSpecification specification) {
- return isBundleConstraintResolvable(specification, Capability.HOST_CAPABILITY);
+ return isBundleConstraintResolvable(specification, BundleRevision.HOST_NAMESPACE);
}
/*
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 beac95554..79d37c5bf 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
@@ -139,7 +139,7 @@ public abstract class StateImpl implements State {
try {
resolving = true;
resolverErrors.remove(existing);
- resolveBundle(existing, false, null, null, null, null, null, null, null);
+ resolveBundle(existing, false, null, null, null, null, null, null, null, null);
} finally {
resolving = false;
}
@@ -311,10 +311,10 @@ public abstract class StateImpl implements State {
* @deprecated
*/
public void resolveBundle(BundleDescription bundle, boolean status, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, ExportPackageDescription[] substitutedExports, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports) {
- resolveBundle(bundle, status, hosts, selectedExports, substitutedExports, null, resolvedRequires, resolvedImports, null);
+ resolveBundle(bundle, status, hosts, selectedExports, substitutedExports, null, resolvedRequires, resolvedImports, null, null);
}
- public void resolveBundle(BundleDescription bundle, boolean status, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, ExportPackageDescription[] substitutedExports, GenericDescription[] selectedCapabilities, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports, GenericDescription[] resolveCapabilities) {
+ public void resolveBundle(BundleDescription bundle, boolean status, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, ExportPackageDescription[] substitutedExports, GenericDescription[] selectedCapabilities, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports, GenericDescription[] resolvedCapabilities, Map<String, List<StateWire>> resolvedWires) {
synchronized (this.monitor) {
if (!resolving)
throw new IllegalStateException(); // TODO need error message here!
@@ -333,12 +333,12 @@ public abstract class StateImpl implements State {
resolvedBundles.remove(modifiable);
modifiable.removeDependencies();
}
- // to support develoment mode we will resolveConstraints even if the resolve status == false
+ // to support development mode we will resolveConstraints even if the resolve status == false
// we only do this if the resolved constraints are not null
if (selectedExports == null || resolvedRequires == null || resolvedImports == null)
unresolveConstraints(modifiable);
else
- resolveConstraints(modifiable, hosts, selectedExports, substitutedExports, selectedCapabilities, resolvedRequires, resolvedImports, resolveCapabilities);
+ resolveConstraints(modifiable, hosts, selectedExports, substitutedExports, selectedCapabilities, resolvedRequires, resolvedImports, resolvedCapabilities, resolvedWires);
}
}
@@ -351,7 +351,7 @@ public abstract class StateImpl implements State {
}
}
- private void resolveConstraints(BundleDescriptionImpl bundle, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, ExportPackageDescription[] substitutedExports, GenericDescription[] selectedCapabilities, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports, GenericDescription[] resolvedCapabilities) {
+ private void resolveConstraints(BundleDescriptionImpl bundle, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, ExportPackageDescription[] substitutedExports, GenericDescription[] selectedCapabilities, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports, GenericDescription[] resolvedCapabilities, Map<String, List<StateWire>> resolvedWires) {
HostSpecificationImpl hostSpec = (HostSpecificationImpl) bundle.getHost();
if (hostSpec != null) {
if (hosts != null) {
@@ -369,6 +369,7 @@ public abstract class StateImpl implements State {
bundle.setSubstitutedExports(substitutedExports);
bundle.setSelectedCapabilities(selectedCapabilities);
bundle.setResolvedCapabilities(resolvedCapabilities);
+ bundle.setStateWires(resolvedWires);
bundle.addDependencies(hosts, true);
bundle.addDependencies(resolvedRequires, true);
@@ -381,25 +382,6 @@ public abstract class StateImpl implements State {
// there are issues here because the order in which fragments are resolved is not always the same ...
}
- // private void checkForSubstitutedExports(BundleDescriptionImpl bundle, ExportPackageDescription[] selectedExports) {
- // ExportPackageDescription[] existingSubstitutes = bundle.getSubstitutedExports();
- // ExportPackageDescription[] declaredExports = bundle.getExportPackages();
- // ArrayList substitutes = new ArrayList();
- // for (int i = 0; i < declaredExports.length; i++) {
- // boolean selected = false;
- // for (int j = 0; !selected && j < selectedExports.length; j++)
- // selected = declaredExports[i] == selectedExports[j];
- // if (!selected)
- // substitutes.add(declaredExports[i]);
- // }
- // if (substitutes.size() > 0) {
- // substitutes.ensureCapacity(substitutes.size() + existingSubstitutes.length);
- // for (int i = 0; i < existingSubstitutes.length; i++)
- // substitutes.add(0, existingSubstitutes[i]);
- // bundle.setSubstitutedExports((ExportPackageDescription[]) substitutes.toArray(new ExportPackageDescription[substitutes.size()]));
- // }
- // }
-
private void unresolveConstraints(BundleDescriptionImpl bundle) {
HostSpecificationImpl host = (HostSpecificationImpl) bundle.getHost();
if (host != null)
@@ -411,6 +393,7 @@ public abstract class StateImpl implements State {
bundle.setSubstitutedExports(null);
bundle.setSelectedCapabilities(null);
bundle.setResolvedCapabilities(null);
+ bundle.setStateWires(null);
bundle.clearAddedDynamicImportPackages();
// remove the constraint suppliers
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateReader.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateReader.java
index ea1954ce3..f31405073 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateReader.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateReader.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2010 IBM Corporation and others.
+ * Copyright (c) 2003, 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
@@ -46,7 +46,7 @@ final class StateReader {
private volatile int numBundles;
private volatile boolean accessedFlag = false;
- public static final byte STATE_CACHE_VERSION = 35;
+ public static final byte STATE_CACHE_VERSION = 36;
public static final byte NULL = 0;
public static final byte OBJECT = 1;
public static final byte INDEX = 2;
@@ -75,7 +75,10 @@ final class StateReader {
}
private Object getFromObjectTable(int index) {
- return objectTable.get(new Integer(index));
+ Object result = objectTable.get(new Integer(index));
+ if (result == null)
+ throw new IllegalStateException("Expected to find an object at table index: " + index); //$NON-NLS-1$
+ return result;
}
private boolean readState(StateImpl state, long expectedTimestamp) throws IOException {
@@ -370,6 +373,10 @@ final class StateReader {
result.setNativeCodeSpecification(readNativeCode(in));
+ @SuppressWarnings("rawtypes")
+ Map raw = readMap(in);
+ result.setStateWires(raw);
+
result.setFullyLoaded(true); // set fully loaded before setting the dependencies
// No need to add bundle dependencies for hosts, imports or requires;
// This is done by readBundleDescription
@@ -377,7 +384,14 @@ final class StateReader {
}
private BundleSpecificationImpl readBundleSpec(DataInputStream in) throws IOException {
+ byte tag = readTag(in);
+ if (tag == NULL)
+ return null;
+ if (tag == INDEX)
+ return (BundleSpecificationImpl) getFromObjectTable(in.readInt());
BundleSpecificationImpl result = new BundleSpecificationImpl();
+ int tableIndex = in.readInt();
+ addToObjectTable(result, tableIndex);
readVersionConstraint(result, in);
result.setSupplier(readBundleDescription(in));
result.setExported(in.readBoolean());
@@ -395,11 +409,11 @@ final class StateReader {
ExportPackageDescriptionImpl exportPackageDesc = new ExportPackageDescriptionImpl();
int tableIndex = in.readInt();
addToObjectTable(exportPackageDesc, tableIndex);
- exportPackageDesc.setTableIndex(tableIndex);
readBaseDescription(exportPackageDesc, in);
exportPackageDesc.setExporter(readBundleDescription(in));
exportPackageDesc.setAttributes(readMap(in));
exportPackageDesc.setDirectives(readMap(in));
+ exportPackageDesc.setFragmentDeclaration(readExportPackageDesc(in));
return exportPackageDesc;
}
@@ -464,6 +478,9 @@ final class StateReader {
case 6 :
list.add(readVersion(in));
break;
+ case 7 :
+ list.add(readStateWire(in));
+ break;
default :
throw new IOException("Invalid type: " + listType); //$NON-NLS-1$
}
@@ -475,6 +492,39 @@ final class StateReader {
return result;
}
+ private Object readStateWire(DataInputStream in) throws IOException {
+ VersionConstraint requirement;
+ BundleDescription requirementHost;
+ BaseDescription capability;
+ BundleDescription capabilityHost;
+
+ byte wireType = in.readByte();
+ switch (wireType) {
+ case 0 :
+ requirement = readImportPackageSpec(in);
+ capability = readExportPackageDesc(in);
+ break;
+ case 1 :
+ requirement = readBundleSpec(in);
+ capability = readBundleDescription(in);
+ break;
+ case 2 :
+ requirement = readHostSpec(in);
+ capability = readBundleDescription(in);
+ break;
+ case 3 :
+ requirement = readGenericSpecification(in);
+ capability = readGenericDescription(in);
+ break;
+ default :
+ throw new IOException("Invalid wire type: " + wireType); //$NON-NLS-1$
+ }
+
+ requirementHost = readBundleDescription(in);
+ capabilityHost = readBundleDescription(in);
+ return new StateWire(requirementHost, requirement, capabilityHost, capability);
+ }
+
private String[] readList(DataInputStream in) throws IOException {
int count = in.readInt();
if (count == 0)
@@ -491,7 +541,14 @@ final class StateReader {
}
private ImportPackageSpecificationImpl readImportPackageSpec(DataInputStream in) throws IOException {
+ byte tag = readTag(in);
+ if (tag == NULL)
+ return null;
+ if (tag == INDEX)
+ return (ImportPackageSpecificationImpl) getFromObjectTable(in.readInt());
ImportPackageSpecificationImpl result = new ImportPackageSpecificationImpl();
+ int tableIndex = in.readInt();
+ addToObjectTable(result, tableIndex);
readVersionConstraint(result, in);
result.setSupplier(readExportPackageDesc(in));
result.setBundleSymbolicName(readString(in, false));
@@ -505,7 +562,11 @@ final class StateReader {
byte tag = readTag(in);
if (tag == NULL)
return null;
+ if (tag == INDEX)
+ return (HostSpecificationImpl) getFromObjectTable(in.readInt());
HostSpecificationImpl result = new HostSpecificationImpl();
+ int tableIndex = in.readInt();
+ addToObjectTable(result, tableIndex);
readVersionConstraint(result, in);
int hostCount = in.readInt();
if (hostCount > 0) {
@@ -542,11 +603,19 @@ final class StateReader {
Map directives = readMap(in);
if (directives != null)
result.setDirectives(directives);
+ result.setFragmentDeclaration(readGenericDescription(in));
return result;
}
private GenericSpecification readGenericSpecification(DataInputStream in) throws IOException {
+ byte tag = readTag(in);
+ if (tag == NULL)
+ return null;
+ if (tag == INDEX)
+ return (GenericSpecification) getFromObjectTable(in.readInt());
GenericSpecificationImpl result = new GenericSpecificationImpl();
+ int tableIndex = in.readInt();
+ addToObjectTable(result, tableIndex);
readVersionConstraint(result, in);
result.setType(readString(in, false));
int num = in.readInt();
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateWriter.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateWriter.java
index 72bc7c2a4..33e39e4de 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateWriter.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateWriter.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2010 IBM Corporation and others.
+ * Copyright (c) 2003, 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
@@ -28,7 +28,7 @@ class StateWriter {
// cached state.
private final Map<Object, Integer> objectTable = new HashMap<Object, Integer>();
- private final List<BundleDescription> forcedWrite = new ArrayList<BundleDescription>();
+ private final List<Object> forcedWrite = new ArrayList<Object>();
private int addToObjectTable(Object object) {
Integer cur = objectTable.get(object);
@@ -336,6 +336,7 @@ class StateWriter {
writeNativeCode(bundle.getNativeCodeSpecification(), out);
+ writeMap(out, ((BundleDescriptionImpl) bundle).getWiresInternal());
// save the size of the lazy data
((BundleDescriptionImpl) bundle).setLazyDataSize(out.size() - dataStart);
}
@@ -347,6 +348,8 @@ class StateWriter {
}
private void writeBundleSpec(BundleSpecificationImpl bundle, DataOutputStream out) throws IOException {
+ if (writePrefix(bundle, out))
+ return;
writeVersionConstraint(bundle, out);
writeBundleDescription((BundleDescription) bundle.getSupplier(), out, false);
out.writeBoolean(bundle.isExported());
@@ -361,6 +364,7 @@ class StateWriter {
writeBundleDescription(exportPackageDesc.getExporter(), out, false);
writeMap(out, exportPackageDesc.getAttributes());
writeMap(out, exportPackageDesc.getDirectives());
+ writeExportPackageDesc((ExportPackageDescriptionImpl) exportPackageDesc.getFragmentDeclaration(), out);
}
private void writeGenericDescription(GenericDescription description, DataOutputStream out) throws IOException {
@@ -378,9 +382,12 @@ class StateWriter {
writeMap(out, mapAttrs);
Map<String, String> directives = description.getDeclaredDirectives();
writeMap(out, directives);
+ writeGenericDescription((GenericDescription) ((BaseDescriptionImpl) description).getFragmentDeclaration(), out);
}
private void writeGenericSpecification(GenericSpecification specification, DataOutputStream out) throws IOException {
+ if (writePrefix(specification, out))
+ return;
writeVersionConstraint(specification, out);
writeStringOrNull(specification.getType() == GenericDescription.DEFAULT_TYPE ? null : specification.getType(), out);
GenericDescription[] suppliers = specification.getSuppliers();
@@ -505,12 +512,45 @@ class StateWriter {
case 6 :
writeVersion((Version) value, out);
break;
+ case 7 :
+ writeStateWire((StateWire) value, out);
default :
break;
}
}
}
+ private void writeStateWire(StateWire wire, DataOutputStream out) throws IOException {
+ VersionConstraint requirement = wire.getDeclaredRequirement();
+ if (requirement instanceof ImportPackageSpecificationImpl) {
+ out.writeByte(0);
+ writeImportPackageSpec((ImportPackageSpecificationImpl) requirement, out);
+ } else if (requirement instanceof BundleSpecificationImpl) {
+ out.writeByte(1);
+ writeBundleSpec((BundleSpecificationImpl) requirement, out);
+ } else if (requirement instanceof HostSpecificationImpl) {
+ out.writeByte(2);
+ writeHostSpec((HostSpecificationImpl) requirement, out, false);
+ } else if (requirement instanceof GenericSpecificationImpl) {
+ out.writeByte(3);
+ writeGenericSpecification((GenericSpecificationImpl) requirement, out);
+ } else
+ throw new IllegalArgumentException("Unknown requiement type: " + requirement.getClass());
+
+ BaseDescription capability = wire.getDeclaredCapability();
+ if (capability instanceof BundleDescription)
+ writeBundleDescription((BundleDescription) capability, out, false);
+ else if (capability instanceof ExportPackageDescriptionImpl)
+ writeExportPackageDesc((ExportPackageDescriptionImpl) capability, out);
+ else if (capability instanceof GenericDescription)
+ writeGenericDescription((GenericDescription) capability, out);
+ else
+ throw new IllegalArgumentException("Unknown capability type: " + requirement.getClass());
+
+ writeBundleDescription(wire.getRequirementHost(), out, false);
+ writeBundleDescription(wire.getCapabilityHost(), out, false);
+ }
+
private byte getListType(List<?> list) {
if (list.size() == 0)
return -1;
@@ -525,6 +565,8 @@ class StateWriter {
return 5;
if (type instanceof Version)
return 6;
+ if (type instanceof StateWire)
+ return 7;
return -2;
}
@@ -544,6 +586,8 @@ class StateWriter {
}
private void writeImportPackageSpec(ImportPackageSpecification importPackageSpec, DataOutputStream out) throws IOException {
+ if (writePrefix(importPackageSpec, out))
+ return;
writeVersionConstraint(importPackageSpec, out);
// TODO this is a hack until the state dynamic loading is cleaned up
// we should only write the supplier if we are resolved
@@ -559,11 +603,13 @@ class StateWriter {
}
private void writeHostSpec(HostSpecificationImpl host, DataOutputStream out, boolean force) throws IOException {
- if (host == null) {
- out.writeByte(StateReader.NULL);
+ if (host != null && force && !forcedWrite.contains(host)) {
+ int index = addToObjectTable(host);
+ out.writeByte(StateReader.OBJECT);
+ out.writeInt(index);
+ forcedWrite.add(host);
+ } else if (writePrefix(host, out))
return;
- }
- out.writeByte(StateReader.OBJECT);
writeVersionConstraint(host, out);
BundleDescription[] hosts = host.getHosts();
if (hosts == null) {
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 5d668cb15..d3c8df191 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2010 IBM Corporation and others.
+ * Copyright (c) 2003, 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
@@ -12,8 +12,12 @@
*******************************************************************************/
package org.eclipse.osgi.internal.resolver;
+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.osgi.framework.wiring.*;
abstract class VersionConstraintImpl implements VersionConstraint {
@@ -89,4 +93,67 @@ abstract class VersionConstraintImpl implements VersionConstraint {
this.supplier = supplier;
}
}
+
+ protected abstract String getInternalNameSpace();
+
+ protected abstract Map<String, String> getInternalDirectives();
+
+ protected abstract Map<String, Object> getInteralAttributes();
+
+ public BundleRequirement getRequirement() {
+ String namespace = getInternalNameSpace();
+ if (namespace == null)
+ return null;
+ return new BundleRequirementImpl(namespace);
+ }
+
+ class BundleRequirementImpl implements BundleRequirement {
+ private final String namespace;
+
+ public BundleRequirementImpl(String namespace) {
+ this.namespace = namespace;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Map<String, String> getDirectives() {
+ return Collections.unmodifiableMap(getInternalDirectives());
+ }
+
+ @SuppressWarnings("unchecked")
+ public Map<String, Object> getAttributes() {
+ return getInteralAttributes();
+ }
+
+ public BundleRevision getRevision() {
+ return getBundle();
+ }
+
+ public boolean matches(BundleCapability capability) {
+ return isSatisfiedBy(((BaseCapability) capability).getBaseDescription());
+ }
+
+ public int hashCode() {
+ return System.identityHashCode(VersionConstraintImpl.this);
+ }
+
+ private VersionConstraintImpl getVersionConstraint() {
+ return VersionConstraintImpl.this;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!(obj instanceof BundleRequirementImpl))
+ return false;
+ return ((BundleRequirementImpl) obj).getVersionConstraint() == VersionConstraintImpl.this;
+ }
+
+ public String toString() {
+ return getNamespace() + BaseDescriptionImpl.toString(getAttributes(), false);
+ }
+ }
}

Back to the top