Caps/reqs in host bundle revisions should not be wrapped. Also, we need
to properly calcualte resolved caps/reqs in the bundle wiring. (FELIX-2950)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1143086 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
index b015a4e..dc496f2 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
@@ -182,49 +182,91 @@
m_fragments = fragments;
m_fragmentContents = fragmentContents;
- List<BundleCapability> capList =
- new ArrayList<BundleCapability>(m_revision.getDeclaredCapabilities(null));
- for (int fragIdx = 0;
- (m_fragments != null) && (fragIdx < m_fragments.size());
- fragIdx++)
+ // Calculate resolved list of requirements, which includes:
+ // 1. All requirements for which we have a wire.
+ // 2. All dynamic imports from the host and any fragments.
+ // Also create set of imported packages so we can eliminate any
+ // substituted exports from our resolved capabilities.
+ Set<String> imports = new HashSet<String>();
+ List<BundleRequirement> reqList = new ArrayList<BundleRequirement>();
+ // First add resolved requirements from wires.
+ for (BundleWire bw : wires)
{
- List<BundleCapability> caps =
- m_fragments.get(fragIdx).getDeclaredCapabilities(null);
- for (int capIdx = 0;
- (caps != null) && (capIdx < caps.size());
- capIdx++)
+ reqList.add(bw.getRequirement());
+ if (bw.getRequirement().getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
{
-// TODO: OSGi R4.4 - OSGi R4.4 may introduce an identity capability, if so
-// that will need to be excluded from here.
- capList.add(
- new HostedCapability(
- m_revision, (BundleCapabilityImpl) caps.get(capIdx)));
+ imports.add((String)
+ bw.getCapability().getAttributes().get(BundleRevision.PACKAGE_NAMESPACE));
}
}
- m_resolvedCaps = Collections.unmodifiableList(capList);
-
- List<BundleRequirement> reqList =
- new ArrayList(m_revision.getDeclaredRequirements(null));
- for (int fragIdx = 0;
- (m_fragments != null) && (fragIdx < m_fragments.size());
- fragIdx++)
+ // Next add dynamic requirements from host.
+ for (BundleRequirement req : m_revision.getDeclaredRequirements(null))
{
- List<BundleRequirement> reqs =
- m_fragments.get(fragIdx).getDeclaredRequirements(null);
- for (int reqIdx = 0;
- (reqs != null) && (reqIdx < reqs.size());
- reqIdx++)
+ if (req.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
{
- if (!reqs.get(reqIdx).getNamespace().equals(BundleRevision.HOST_NAMESPACE))
+ String resolution = req.getDirectives().get(Constants.RESOLUTION_DIRECTIVE);
+ if ((resolution != null) && (resolution.equals("dynamic")))
{
- reqList.add(
- new HostedRequirement(
- m_revision, (BundleRequirementImpl) reqs.get(reqIdx)));
+ reqList.add(req);
+ }
+ }
+ }
+ // Finally, add dynamic requirements from fragments.
+ if (m_fragments != null)
+ {
+ for (BundleRevision fragment : m_fragments)
+ {
+ for (BundleRequirement req : fragment.getDeclaredRequirements(null))
+ {
+ if (req.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
+ {
+ String resolution = req.getDirectives().get(Constants.RESOLUTION_DIRECTIVE);
+ if ((resolution != null) && (resolution.equals("dynamic")))
+ {
+ reqList.add(req);
+ }
+ }
}
}
}
m_resolvedReqs = Collections.unmodifiableList(reqList);
+ // Calculate resolved list of capabilities, which includes:
+ // 1. All capabilities from host and any fragments except for exported
+ // packages that we have an import (i.e., the export was substituted).
+ // And nothing else at this time.
+ List<BundleCapability> capList = new ArrayList<BundleCapability>();
+ for (BundleCapability cap : m_revision.getDeclaredCapabilities(null))
+ {
+ if (!cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
+ || (cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
+ && !imports.contains(cap.getAttributes()
+ .get(BundleRevision.PACKAGE_NAMESPACE).toString())))
+ {
+ capList.add(cap);
+ }
+ }
+ if (m_fragments != null)
+ {
+ for (BundleRevision fragment : m_fragments)
+ {
+ for (BundleCapability cap : fragment.getDeclaredCapabilities(null))
+ {
+// TODO: OSGi R4.4 - OSGi R4.4 may introduce an identity capability, if so
+// that will need to be excluded from here.
+ capList.add((BundleCapabilityImpl) cap);
+ if (!cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
+ || (cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
+ && !imports.contains(cap.getAttributes()
+ .get(BundleRevision.PACKAGE_NAMESPACE).toString())))
+ {
+ capList.add(cap);
+ }
+ }
+ }
+ }
+ m_resolvedCaps = Collections.unmodifiableList(capList);
+
List<R4Library> libList = (m_revision.getDeclaredNativeLibraries() == null)
? new ArrayList<R4Library>()
: new ArrayList<R4Library>(m_revision.getDeclaredNativeLibraries());
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
index 9e90ea7..436f692 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverImpl.java
@@ -40,6 +40,7 @@
import org.osgi.framework.wiring.BundleRevision;
import org.osgi.framework.wiring.BundleWire;
+// TODO: OSGi R.4.3 - Make sure we have sufficient wrapping of caps/reqs.
public class ResolverImpl implements Resolver
{
private final Logger m_logger;
@@ -640,9 +641,14 @@
{
// Wrap the requirement as a hosted requirement
// if it comes from a fragment, since we will need
- // to know the host.
+ // to know the host. We also need to wrap if the
+ // requirement is a dynamic import, since that
+ // requirement will be shared with any other
+ // matching dynamic imports.
BundleRequirement r = wire.getRequirement();
- if (!r.getRevision().equals(wire.getRequirerWiring().getRevision()))
+ if (!r.getRevision().equals(wire.getRequirerWiring().getRevision())
+ || ((r.getDirectives().get(Constants.RESOLUTION_DIRECTIVE) != null)
+ && r.getDirectives().get(Constants.RESOLUTION_DIRECTIVE).equals("dynamic")))
{
r = new HostedRequirement(
wire.getRequirerWiring().getRevision(),
@@ -847,6 +853,8 @@
{
if (req.getNamespace().equals(BundleRevision.BUNDLE_NAMESPACE))
{
+// TODO: OSGi R.4.3 - Something doesn't seem correct here since we don't calculate
+// reexported packages for resolved bundles. Create a test case.
String value = req.getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
if ((value != null) && value.equals(Constants.VISIBILITY_REEXPORT)
&& (allCandidates.getCandidates(req) != null))
@@ -1338,31 +1346,23 @@
{
if (cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
{
+ if (!cap.getRevision().equals(revision))
+ {
+ cap = new HostedCapability(revision, (BundleCapabilityImpl) cap);
+ }
exports.put(
(String) cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE),
cap);
}
}
// Remove substitutable exports that were imported.
- // For resolved revisions look at the wires, for resolving
- // revisions look in the candidate map to determine which
- // exports are substitutable.
+ // For resolved revisions BundleWiring.getCapabilities()
+ // already excludes imported substitutable exports, but
+ // for resolving revisions we must look in the candidate
+ // map to determine which exports are substitutable.
if (!exports.isEmpty())
{
- if (revision.getWiring() != null)
- {
- for (BundleWire wire : revision.getWiring().getRequiredWires(null))
- {
- if (wire.getRequirement().getNamespace().equals(
- BundleRevision.PACKAGE_NAMESPACE))
- {
- String pkgName = (String) wire.getCapability()
- .getAttributes().get(BundleRevision.PACKAGE_NAMESPACE);
- exports.remove(pkgName);
- }
- }
- }
- else
+ if (revision.getWiring() == null)
{
for (BundleRequirement req : revision.getDeclaredRequirements(null))
{
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWireImpl.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWireImpl.java
index 4f8420f..81ac47d 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWireImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWireImpl.java
@@ -63,6 +63,7 @@
{
return m_req
+ " -> "
- + "[" + m_provider + "]";
+ + "[" + m_cap.getRevision() + " VIA " + m_provider + "]";
+// TODO: OSGi R4.3 - Simplify this message once we know wiring works.
}
}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/wiring/BundleWireImpl.java b/framework/src/main/java/org/apache/felix/framework/wiring/BundleWireImpl.java
index ea5346e..ccb8567 100644
--- a/framework/src/main/java/org/apache/felix/framework/wiring/BundleWireImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/wiring/BundleWireImpl.java
@@ -75,6 +75,7 @@
{
return m_req
+ " -> "
- + "[" + m_provider + "]";
+ + "[" + m_cap.getRevision() + " VIA " + m_provider + "]";
+// TODO: OSGi R4.3 - Simplify this message once we know wiring works.
}
}
\ No newline at end of file