Change class loader delegation to revision-to-revision instead
of revision-to-wire. (FELIX-2950)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1102809 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
index 9e01017..f6d2c99 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
@@ -18,7 +18,6 @@
*/
package org.apache.felix.framework;
-import com.sun.xml.internal.ws.api.server.Module;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@@ -29,9 +28,9 @@
import org.apache.felix.framework.ext.SecurityProvider;
import org.apache.felix.framework.util.StringMap;
import org.apache.felix.framework.util.Util;
-import org.apache.felix.framework.wiring.FelixBundleWire;
import org.osgi.framework.*;
import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
class BundleImpl implements Bundle
{
@@ -145,7 +144,7 @@
}
// Set wires to null, which will remove the revision from all
// of its dependent revisions.
- ((BundleRevisionImpl) br).setWires(null);
+ ((BundleRevisionImpl) br).setWires(null, null);
// Close the revision's content.
((BundleRevisionImpl) br).close();
@@ -480,7 +479,7 @@
// search the revision itself.
if (Util.isFragment(bri))
{
- List<FelixBundleWire> hostWires = bri.getWires();
+ List<BundleWire> hostWires = bri.getWires();
if ((hostWires != null) && (hostWires.size() > 0))
{
bri = (BundleRevisionImpl) hostWires.get(0).getProviderWiring().getRevision();
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
index 18aa2fa..032419d 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
@@ -48,6 +48,7 @@
import org.apache.felix.framework.resolver.HostedCapability;
import org.apache.felix.framework.resolver.HostedRequirement;
import org.apache.felix.framework.resolver.ResolveException;
+import org.apache.felix.framework.resolver.ResolverWire;
import org.apache.felix.framework.resolver.ResourceNotFoundException;
import org.apache.felix.framework.util.CompoundEnumeration;
import org.apache.felix.framework.util.FelixConstants;
@@ -58,7 +59,7 @@
import org.apache.felix.framework.util.manifestparser.R4Library;
import org.apache.felix.framework.wiring.BundleCapabilityImpl;
import org.apache.felix.framework.wiring.BundleRequirementImpl;
-import org.apache.felix.framework.wiring.FelixBundleWire;
+import org.apache.felix.framework.wiring.BundleWireImpl;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.BundleReference;
@@ -102,7 +103,9 @@
private final Bundle m_bundle;
private List<BundleRevision> m_fragments = null;
- private List<FelixBundleWire> m_wires = null;
+ private List<BundleWire> m_wires = null;
+ private Map<String, BundleRevision> m_importedPkgs = null;
+ private Map<String, List<BundleRevision>> m_requiredPkgs = null;
private List<BundleRevision> m_dependentImporters = new ArrayList<BundleRevision>(0);
private List<BundleRevision> m_dependentRequirers = new ArrayList<BundleRevision>(0);
private volatile boolean m_isResolved = false;
@@ -446,12 +449,7 @@
public List<BundleWire> getRequiredWires(String namespace)
{
- return asBundleWires(m_wires);
- }
-
- private static List<BundleWire> asBundleWires(List<? extends BundleWire> l)
- {
- return (List<BundleWire>) l;
+ return m_wires;
}
public BundleRevision getRevision()
@@ -645,12 +643,55 @@
return m_id;
}
- public synchronized List<FelixBundleWire> getWires()
+// TODO: OSGi R4.3 - This really shouldn't be public, but it is needed by the
+// resolver to determine if a bundle can dynamically import.
+ public synchronized boolean hasPackageSource(String pkgName)
+ {
+ return (m_importedPkgs.containsKey(pkgName) || m_requiredPkgs.containsKey(pkgName));
+ }
+
+// TODO: OSGi R4.3 - This really shouldn't be public, but it is needed by the
+// to implement dynamic imports.
+ public synchronized BundleRevision getImportedPackageSource(String pkgName)
+ {
+ return m_importedPkgs.get(pkgName);
+ }
+
+ private synchronized List<BundleRevision> getRequiredPackageSources(String pkgName)
+ {
+ return m_requiredPkgs.get(pkgName);
+ }
+
+ public synchronized List<BundleWire> getWires()
{
return m_wires;
}
- public synchronized void setWires(List<FelixBundleWire> wires)
+ public synchronized void addDynamicWire(ResolverWire rw)
+ {
+ // This not only sets the wires for the module, but it also records
+ // the dependencies this module has on other modules (i.e., the provider
+ // end of the wire) to simplify bookkeeping.
+
+ BundleWire wire = new BundleWireImpl(
+ rw.getRequirer(),
+ rw.getRequirement(),
+ rw.getProvider(),
+ rw.getCapability());
+ m_wires.add(wire);
+ m_importedPkgs.put(
+ (String) wire.getCapability().getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR),
+ rw.getProvider());
+
+// TODO: OSGi R4.3 - What's the correct way to handle this?
+// ((BundleRevisionImpl) m_wires.get(i).getProviderWiring().getRevision())
+// .addDependentImporter(this);
+ ((BundleRevisionImpl) rw.getProvider()).addDependentImporter(this);
+ }
+
+ public synchronized void setWires(
+ List<ResolverWire> rws,
+ Map<ResolverWire, Set<String>> requiredPkgWires)
{
// This not only sets the wires for the module, but it also records
// the dependencies this module has on other modules (i.e., the provider
@@ -661,43 +702,122 @@
// new wires. The wires are to the hosts to which the fragment is attached.
boolean isFragment = Util.isFragment(this);
+ // Fragments are allowed to add new wires to existing wires, but
+ // normal bundles should never be wired again if they already
+ // have wires.
+ if (!isFragment && (m_wires != null) && (rws != null))
+ {
+ throw new IllegalStateException("The revision already has wires.");
+ }
+
+ // Convert resolver wires to bundle wires and aggregate all imported
+ // or required packages.
+ List<BundleWire> wires = null;
+ Map<String, BundleRevision> importedPkgs = null;
+ Map<String, List<BundleRevision>> requiredPkgs = null;
+ if (rws != null)
+ {
+ wires = new ArrayList<BundleWire>(rws.size());
+ importedPkgs = new HashMap<String, BundleRevision>();
+ requiredPkgs = new HashMap<String, List<BundleRevision>>();
+
+ for (ResolverWire rw : rws)
+ {
+ wires.add(
+ new BundleWireImpl(
+ rw.getRequirer(),
+ rw.getRequirement(),
+ rw.getProvider(),
+ rw.getCapability()));
+
+ if (isFragment)
+ {
+ m_logger.log(
+ Logger.LOG_DEBUG,
+ "FRAGMENT WIRE: "
+ + this + " -> hosted by -> " + rw.getProvider());
+ }
+ else
+ {
+ m_logger.log(Logger.LOG_DEBUG, "WIRE: " + rw);
+
+ if (rw.getCapability().getNamespace()
+ .equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ {
+ importedPkgs.put(
+ (String) rw.getCapability().getAttributes()
+ .get(BundleCapabilityImpl.PACKAGE_ATTR),
+ rw.getProvider());
+ }
+ else if (rw.getCapability().getNamespace()
+ .equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
+ {
+ for (String pkgName : requiredPkgWires.get(rw))
+ {
+ List<BundleRevision> revs = requiredPkgs.get(pkgName);
+ if (revs != null)
+ {
+ revs.add(rw.getProvider());
+ }
+ else
+ {
+ revs = new ArrayList<BundleRevision>();
+ revs.add(rw.getProvider());
+ requiredPkgs.put(pkgName, revs);
+ }
+ }
+ }
+ }
+ }
+ }
+
// Remove module from old wire modules' dependencies,
// since we are no longer dependent on any the moduels
// from the old wires.
for (int i = 0; !isFragment && (m_wires != null) && (i < m_wires.size()); i++)
{
- if (m_wires.get(i).getCapability().getNamespace().equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
+ if (m_wires.get(i).getCapability().getNamespace()
+ .equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
{
((BundleRevisionImpl) m_wires.get(i).getProviderWiring().getRevision())
.removeDependentRequirer(this);
}
- else if (m_wires.get(i).getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ else if (m_wires.get(i).getCapability().getNamespace()
+ .equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
{
((BundleRevisionImpl) m_wires.get(i).getProviderWiring().getRevision())
.removeDependentImporter(this);
}
}
- m_wires = wires;
+ // If we already have wires, then add new wires to existing list (this
+ // should only happen for fragments). Otherwise, simply set wires value.
+ if ((m_wires != null) && (wires != null))
+ {
+ m_wires.addAll(wires);
+ }
+ else
+ {
+ m_wires = wires;
+ }
+ m_importedPkgs = importedPkgs;
+ m_requiredPkgs = requiredPkgs;
// Add ourself as a dependent to the new wires' modules.
- for (int i = 0; !isFragment && (m_wires != null) && (i < m_wires.size()); i++)
+ if (!isFragment && (rws != null))
{
- if (m_wires.get(i).getCapability().getNamespace().equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
+ for (ResolverWire rw : rws)
{
-// TODO: OSGi R4.3 - What's the correct way to handle this?
-// ((BundleRevisionImpl) m_wires.get(i).getProviderWiring().getRevision())
-// .addDependentRequirer(this);
- ((BundleRevisionImpl) ((FelixBundleWire)
- m_wires.get(i)).getProvider()).addDependentRequirer(this);
- }
- else if (m_wires.get(i).getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
- {
-// TODO: OSGi R4.3 - What's the correct way to handle this?
-// ((BundleRevisionImpl) m_wires.get(i).getProviderWiring().getRevision())
-// .addDependentImporter(this);
- ((BundleRevisionImpl) ((FelixBundleWire)
- m_wires.get(i)).getProvider()).addDependentImporter(this);
+ if (rw.getCapability().getNamespace()
+ .equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
+ {
+ ((BundleRevisionImpl) rw.getProvider()).addDependentRequirer(this);
+ }
+ else if (rw.getCapability().getNamespace()
+ .equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ {
+ ((BundleRevisionImpl) rw.getProvider()).addDependentImporter(this);
+ }
}
}
}
@@ -939,7 +1059,7 @@
// Look in the revision's imports. Note that the search may
// be aborted if this method throws an exception, otherwise
// it continues if a null is returned.
- result = searchImports(name, isClass);
+ result = searchImports(pkgName, name, isClass);
// If not found, try the revision's own class path.
if (result == null)
@@ -951,7 +1071,7 @@
// If still not found, then try the revision's dynamic imports.
if (result == null)
{
- result = searchDynamicImports(name, pkgName, isClass);
+ result = searchDynamicImports(pkgName, name, isClass);
}
}
}
@@ -1119,59 +1239,46 @@
completeUrlList.add(urls);
}
- // Look in the module's imports.
- // We delegate to the module's wires for the resources.
- // If any resources are found, this means that the package of these
- // resources is imported, we must not keep looking since we do not
- // support split-packages.
-
- // Note that the search may be aborted if this method throws an
- // exception, otherwise it continues if a null is returned.
- List<FelixBundleWire> wires = getWires();
- for (int i = 0; (wires != null) && (i < wires.size()); i++)
+ // Look in the revisions's imported packages. If the package is
+ // imported, then we stop searching no matter the result since
+ // imported packages cannot be split.
+ BundleRevision provider = getImportedPackageSource(pkgName);
+ if (provider != null)
{
- if (wires.get(i).getRequirement().getNamespace()
- .equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ // Delegate to the provider revision.
+ urls = ((BundleRevisionImpl) provider).getResourcesByDelegation(name);
+
+ // If we find any resources, then add them.
+ if ((urls != null) && (urls.hasMoreElements()))
{
- try
- {
- // If we find the class or resource, then return it.
- urls = wires.get(i).getResources(name);
- }
- catch (ResourceNotFoundException ex)
- {
- urls = null;
- }
- if (urls != null)
- {
- completeUrlList.add(urls);
- return new CompoundEnumeration((Enumeration[])
- completeUrlList.toArray(new Enumeration[completeUrlList.size()]));
- }
+ completeUrlList.add(urls);
}
+
+ // Always return here since imported packages cannot be split
+ // across required bundles or the revision's content.
+ return new CompoundEnumeration((Enumeration[])
+ completeUrlList.toArray(new Enumeration[completeUrlList.size()]));
}
// See whether we can get the resource from the required bundles and
// regardless of whether or not this is the case continue to the next
// step potentially passing on the result of this search (if any).
- for (int i = 0; (wires != null) && (i < wires.size()); i++)
+ List<BundleRevision> providers = getRequiredPackageSources(pkgName);
+ if (providers != null)
{
- if (wires.get(i).getRequirement().getNamespace()
- .equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
+ for (BundleRevision p : providers)
{
- try
- {
- // If we find the class or resource, then add it.
- urls = wires.get(i).getResources(name);
- }
- catch (ResourceNotFoundException ex)
- {
- urls = null;
- }
- if (urls != null)
+ // Delegate to the provider revision.
+ urls = ((BundleRevisionImpl) p).getResourcesByDelegation(name);
+
+ // If we find any resources, then add them.
+ if ((urls != null) && (urls.hasMoreElements()))
{
completeUrlList.add(urls);
}
+
+ // Do not return here, since required packages can be split
+ // across the revision's content.
}
}
@@ -1189,26 +1296,21 @@
// At this point, the module's imports were searched and so was the
// the module's content. Now we make an attempt to load the
// class/resource via a dynamic import, if possible.
- FelixBundleWire wire = null;
try
{
- wire = m_resolver.resolve(this, pkgName);
+ provider = m_resolver.resolve(this, pkgName);
}
catch (ResolveException ex)
{
// Ignore this since it is likely normal.
}
- if (wire != null)
+ if (provider != null)
{
- try
- {
- urls = wire.getResources(name);
- }
- catch (ResourceNotFoundException ex)
- {
- urls = null;
- }
- if (urls != null)
+ // Delegate to the provider revision.
+ urls = ((BundleRevisionImpl) provider).getResourcesByDelegation(name);
+
+ // If we find any resources, then add them.
+ if ((urls != null) && (urls.hasMoreElements()))
{
completeUrlList.add(urls);
}
@@ -1368,30 +1470,33 @@
return m_fragments;
}
+ private synchronized void detachHost(BundleRevision host)
+ {
+ if (m_wires != null)
+ {
+ for (Iterator<BundleWire> it = m_wires.iterator(); it.hasNext(); )
+ {
+ BundleWire wire = it.next();
+ if (wire.getCapability().getNamespace().equals(BundleCapabilityImpl.HOST_NAMESPACE)
+ && wire.getProviderWiring().getRevision().equals(host))
+ {
+ it.remove();
+ break;
+ }
+ }
+ }
+ }
+
public synchronized void attachFragments(List<BundleRevision> fragments) throws Exception
{
// Remove the host wires for this module from old fragments.
// We will generally only remove host wires when we are uninstalling
// the module.
- for (int i = 0; (m_fragments != null) && (i < m_fragments.size()); i++)
+ if (m_fragments != null)
{
- // If the fragment has no wires, then there is no reason to try to
- // remove ourself from its wires since it has apparently already
- // been refreshed.
- if (((BundleRevisionImpl) m_fragments.get(i)).getWires() != null)
+ for (BundleRevision fragment : m_fragments)
{
- List<FelixBundleWire> hostWires = new ArrayList<FelixBundleWire>(
- ((BundleRevisionImpl) m_fragments.get(i)).getWires());
- for (Iterator<FelixBundleWire> it = hostWires.iterator(); it.hasNext(); )
- {
- FelixBundleWire hostWire = it.next();
- if (hostWire.getProviderWiring().getRevision().equals(this))
- {
- it.remove();
- ((BundleRevisionImpl) m_fragments.get(i)).setWires(hostWires);
- break;
- }
- }
+ ((BundleRevisionImpl) fragment).detachHost(this);
}
}
@@ -1565,37 +1670,69 @@
return parent;
}
- private Object searchImports(String name, boolean isClass)
+ private Object searchImports(String pkgName, String name, boolean isClass)
throws ClassNotFoundException, ResourceNotFoundException
{
- // We delegate to the module's wires to find the class or resource.
- List<FelixBundleWire> wires = getWires();
- for (int i = 0; (wires != null) && (i < wires.size()); i++)
+ // Check if the package is imported.
+ BundleRevision provider = getImportedPackageSource(pkgName);
+ if (provider != null)
{
// If we find the class or resource, then return it.
Object result = (isClass)
- ? (Object) wires.get(i).getClass(name)
- : (Object) wires.get(i).getResource(name);
+ ? (Object) ((BundleRevisionImpl) provider).getClassByDelegation(name)
+ : (Object) ((BundleRevisionImpl) provider).getResourceByDelegation(name);
if (result != null)
{
return result;
}
+
+ // If no class was found, then we must throw an exception
+ // since the provider of this package did not contain the
+ // requested class and imported packages are atomic.
+ throw new ClassNotFoundException(name);
+ }
+
+ // Check if the package is required.
+ List<BundleRevision> providers = getRequiredPackageSources(pkgName);
+ if (providers != null)
+ {
+ for (BundleRevision p : providers)
+ {
+ // If we find the class or resource, then return it.
+ try
+ {
+ Object result = (isClass)
+ ? (Object) ((BundleRevisionImpl) p).getClassByDelegation(name)
+ : (Object) ((BundleRevisionImpl) p).getResourceByDelegation(name);
+ if (result != null)
+ {
+ return result;
+ }
+ }
+ catch (ClassNotFoundException ex)
+ {
+ // Since required packages can be split, don't throw an
+ // exception here if it is not found. Instead, we'll just
+ // continue searching other required bundles and the
+ // revision's local content.
+ }
+ }
}
return null;
}
private Object searchDynamicImports(
- final String name, String pkgName, final boolean isClass)
+ final String pkgName, final String name, final boolean isClass)
throws ClassNotFoundException, ResourceNotFoundException
{
// At this point, the module's imports were searched and so was the
// the module's content. Now we make an attempt to load the
// class/resource via a dynamic import, if possible.
- FelixBundleWire wire = null;
+ BundleRevision provider = null;
try
{
- wire = m_resolver.resolve(this, pkgName);
+ provider = m_resolver.resolve(this, pkgName);
}
catch (ResolveException ex)
{
@@ -1604,15 +1741,15 @@
// If the dynamic import was successful, then this initial
// time we must directly return the result from dynamically
- // created wire, but subsequent requests for classes/resources
- // in the associated package will be processed as part of
- // normal static imports.
- if (wire != null)
+ // created package sources, but subsequent requests for
+ // classes/resources in the associated package will be
+ // processed as part of normal static imports.
+ if (provider != null)
{
// Return the class or resource.
return (isClass)
- ? (Object) wire.getClass(name)
- : (Object) wire.getResource(name);
+ ? (Object) ((BundleRevisionImpl) provider).getClassByDelegation(name)
+ : (Object) ((BundleRevisionImpl) provider).getResourceByDelegation(name);
}
// If implicit boot delegation is enabled, then try to guess whether
@@ -2362,7 +2499,7 @@
String importer = revision.getBundle().toString();
// Next, check to see if the revision imports the package.
- List<FelixBundleWire> wires = revision.getWires();
+ List<BundleWire> wires = revision.getWires();
for (int i = 0; (wires != null) && (i < wires.size()); i++)
{
if (wires.get(i).getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) &&
@@ -2462,14 +2599,14 @@
revision, BundleCapabilityImpl.PACKAGE_NAMESPACE, dirs, attrs);
Set<BundleCapability> exporters = resolver.getCandidates(req, false);
- FelixBundleWire wire = null;
+ BundleRevision provider = null;
try
{
- wire = resolver.resolve(revision, pkgName);
+ provider = resolver.resolve(revision, pkgName);
}
catch (Exception ex)
{
- wire = null;
+ provider = null;
}
String exporter = (exporters.isEmpty())
@@ -2482,7 +2619,7 @@
sb.append("' is dynamically imported by bundle ");
sb.append(importer);
sb.append(".");
- if ((exporters.size() > 0) && (wire == null))
+ if ((exporters.size() > 0) && (provider == null))
{
sb.append(" However, bundle ");
sb.append(exporter);
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index 98b8183..db092bc 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -46,8 +46,6 @@
import org.apache.felix.framework.util.manifestparser.R4LibraryClause;
import org.apache.felix.framework.wiring.BundleCapabilityImpl;
import org.apache.felix.framework.wiring.BundleRequirementImpl;
-import org.apache.felix.framework.wiring.FelixBundleWire;
-import org.apache.felix.framework.wiring.FelixBundleWireImpl;
import org.osgi.framework.AdminPermission;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
@@ -74,6 +72,7 @@
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRequirement;
import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.startlevel.StartLevel;
@@ -3480,15 +3479,13 @@
((BundleRevisionImpl) expRevisions.get(expIdx)).getDependentImporters();
for (int depIdx = 0; (dependents != null) && (depIdx < dependents.size()); depIdx++)
{
- List<FelixBundleWire> wires =
- ((BundleRevisionImpl) dependents.get(depIdx)).getWires();
- for (int wireIdx = 0; (wires != null) && (wireIdx < wires.size()); wireIdx++)
+ BundleRevision providerRevision =
+ ((BundleRevisionImpl) dependents.get(depIdx))
+ .getImportedPackageSource(ep.getName());
+ if ((providerRevision != null)
+ && (providerRevision == expRevisions.get(expIdx)))
{
- if ((wires.get(wireIdx).getProviderWiring().getRevision() == expRevisions.get(expIdx))
- && (wires.get(wireIdx).hasPackage(ep.getName())))
- {
- list.add(dependents.get(depIdx).getBundle());
- }
+ list.add(dependents.get(depIdx).getBundle());
}
}
dependents = ((BundleRevisionImpl) expRevisions.get(expIdx)).getDependentRequirers();
@@ -4182,9 +4179,11 @@
}
}
- FelixBundleWire resolve(BundleRevision revision, String pkgName) throws ResolveException
+ BundleRevision resolve(BundleRevision revision, String pkgName)
+ throws ResolveException
{
- FelixBundleWire candidateWire = null;
+ BundleRevision provider = null;
+
// We cannot dynamically import if the revision is not already resolved
// or if it is not allowed, so check that first. Note: We check if the
// dynamic import is allowed without holding any locks, but this is
@@ -4207,41 +4206,33 @@
// dynamically importing the package, which can happen if two
// threads are racing to do so. If we have an existing wire,
// then just return it instead.
- List<FelixBundleWire> wires = ((BundleRevisionImpl) revision).getWires();
- for (int i = 0; (wires != null) && (i < wires.size()); i++)
+ provider = ((BundleRevisionImpl)revision)
+ .getImportedPackageSource(pkgName);
+ if (provider == null)
{
- if (wires.get(i).hasPackage(pkgName))
+ wireMap = m_resolver.resolve(
+ m_resolverState, revision, pkgName,
+ m_resolverState.getFragments());
+
+ if ((wireMap != null) && wireMap.containsKey(revision))
{
- return wires.get(i);
- }
- }
+ List<ResolverWire> dynamicWires = wireMap.remove(revision);
+ ResolverWire dynamicWire = dynamicWires.get(0);
- wireMap = m_resolver.resolve(
- m_resolverState, revision, pkgName, m_resolverState.getFragments());
+ // Mark all revisions as resolved.
+ markResolvedRevisions(wireMap);
- if ((wireMap != null) && wireMap.containsKey(revision))
- {
- List<ResolverWire> dynamicWires = wireMap.remove(revision);
- ResolverWire rw = dynamicWires.get(0);
- candidateWire = new FelixBundleWireImpl(
- rw.getRequirer(),
- rw.getRequirement(),
- rw.getProvider(),
- rw.getCapability());
+ // Dynamically add new wire to importing revision.
+ if (dynamicWire != null)
+ {
+ ((BundleRevisionImpl) revision).addDynamicWire(dynamicWire);
+ m_logger.log(
+ Logger.LOG_DEBUG,
+ "DYNAMIC WIRE: " + dynamicWire);
- // Mark all revisions as resolved.
- markResolvedRevisions(wireMap);
-
- // Dynamically add new wire to importing revision.
- if (candidateWire != null)
- {
- wires = new ArrayList(wires.size() + 1);
- wires.addAll(((BundleRevisionImpl) revision).getWires());
- wires.add(candidateWire);
- ((BundleRevisionImpl) revision).setWires(wires);
- m_logger.log(
- Logger.LOG_DEBUG,
- "DYNAMIC WIRE: " + wires.get(wires.size() - 1));
+ provider = ((BundleRevisionImpl) revision)
+ .getImportedPackageSource(pkgName);
+ }
}
}
}
@@ -4254,7 +4245,7 @@
fireResolvedEvents(wireMap);
}
- return candidateWire;
+ return provider;
}
// This method duplicates a lot of logic from:
@@ -4287,14 +4278,12 @@
return false;
}
}
- // If any of our wires have this package, then we cannot
- // attempt to dynamically import it.
- for (FelixBundleWire w : ((BundleRevisionImpl) revision).getWires())
+
+ // If this revision already imports or requires this package, then
+ // we cannot dynamically import it.
+ if (((BundleRevisionImpl) revision).hasPackageSource(pkgName))
{
- if (w.hasPackage(pkgName))
- {
- return false;
- }
+ return false;
}
// Loop through the importer's dynamic requirements to determine if
@@ -4354,41 +4343,25 @@
{
BundleRevision revision = entry.getKey();
List<ResolverWire> resolverWires = entry.getValue();
- List<FelixBundleWire> wires = new ArrayList<FelixBundleWire>();
- // Convert resolver wires into bundle wires.
- for (Iterator<ResolverWire> itWires = resolverWires.iterator();
- itWires.hasNext(); )
+ Map<ResolverWire, Set<String>> requiredPkgWires =
+ new HashMap<ResolverWire, Set<String>>();
+ for (ResolverWire rw : resolverWires)
{
- ResolverWire rw = itWires.next();
- if (!Util.isFragment(revision))
+ if (rw.getCapability().getNamespace()
+ .equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
{
- m_logger.log(Logger.LOG_DEBUG, "WIRE: " + rw);
+ Set<String> pkgs =
+ calculateExportedAndReexportedPackages(
+ rw.getProvider(),
+ wireMap,
+ new HashSet<String>(),
+ new HashSet<BundleRevision>());
+ requiredPkgWires.put(rw, pkgs);
}
- else
- {
- m_logger.log(
- Logger.LOG_DEBUG,
- "FRAGMENT WIRE: "
- + revision + " -> hosted by -> " + rw.getProvider());
- }
- wires.add(
- new FelixBundleWireImpl(
- rw.getRequirer(),
- rw.getRequirement(),
- rw.getProvider(),
- rw.getCapability()));
}
- // Set the revision's wires. If the revision is a resolved
- // fragment, then we must actually append any new host
- // wires to the existing ones, since fragments can be attached
- // to multiple hosts spanning multiple resolve operations.
- if (Util.isFragment(revision) && (revision.getWiring() != null))
- {
- wires.addAll(((BundleRevisionImpl) revision).getWires());
- }
- ((BundleRevisionImpl) revision).setWires(wires);
+ ((BundleRevisionImpl) revision).setWires(resolverWires, requiredPkgWires);
// Attach fragments, if any.
List<BundleRevision> fragments = hosts.get(revision);
@@ -4407,7 +4380,7 @@
revision = reentry.getKey();
// Undo wires.
- ((BundleRevisionImpl) revision).setWires(null);
+ ((BundleRevisionImpl) revision).setWires(null, null);
fragments = hosts.get(revision);
if (fragments != null)
@@ -4530,6 +4503,73 @@
}
}
+ private static Set<String> calculateExportedAndReexportedPackages(
+ BundleRevision br,
+ Map<BundleRevision, List<ResolverWire>> wireMap,
+ Set<String> pkgs,
+ Set<BundleRevision> cycles)
+ {
+ if (!cycles.contains(br))
+ {
+ cycles.add(br);
+
+ // Add all exported packages.
+ for (BundleCapability cap : br.getDeclaredCapabilities(null))
+ {
+ if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
+ {
+ pkgs.add((String)
+ cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
+ }
+ }
+
+ // Now check to see if any required bundles are required with reexport
+ // visibility, since we need to include those packages too.
+ if (br.getWiring() == null)
+ {
+ for (ResolverWire rw : wireMap.get(br))
+ {
+ if (rw.getCapability().getNamespace().equals(
+ BundleCapabilityImpl.BUNDLE_NAMESPACE))
+ {
+ String dir = rw.getRequirement()
+ .getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
+ if ((dir != null) && (dir.equals(Constants.VISIBILITY_REEXPORT)))
+ {
+ calculateExportedAndReexportedPackages(
+ rw.getProvider(),
+ wireMap,
+ pkgs,
+ cycles);
+ }
+ }
+ }
+ }
+ else
+ {
+ for (BundleWire bw : br.getWiring().getRequiredWires(null))
+ {
+ if (bw.getCapability().getNamespace().equals(
+ BundleCapabilityImpl.BUNDLE_NAMESPACE))
+ {
+ String dir = bw.getRequirement()
+ .getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
+ if ((dir != null) && (dir.equals(Constants.VISIBILITY_REEXPORT)))
+ {
+ calculateExportedAndReexportedPackages(
+ bw.getProviderWiring().getRevision(),
+ wireMap,
+ pkgs,
+ cycles);
+ }
+ }
+ }
+ }
+ }
+
+ return pkgs;
+ }
+
class SystemBundleActivator implements BundleActivator
{
public void start(BundleContext context) throws Exception
diff --git a/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java b/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
index 3718642..f19531f 100644
--- a/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
@@ -20,13 +20,13 @@
import java.util.*;
import org.apache.felix.framework.util.VersionRange;
-import org.apache.felix.framework.wiring.FelixBundleWire;
import org.osgi.framework.AdminPermission;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.packageadmin.RequiredBundle;
@@ -237,7 +237,7 @@
BundleRevisionImpl revision = (BundleRevisionImpl) revisions.get(modIdx);
if (revision.isResolved())
{
- List<FelixBundleWire> hostWires = revision.getWires();
+ List<BundleWire> hostWires = revision.getWires();
for (int i = 0; (hostWires != null) && (i < hostWires.size()); i++)
{
Bundle b = hostWires.get(i).getProviderWiring().getBundle();
diff --git a/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java b/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java
index ff69464..b76ade8 100644
--- a/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ResolverStateImpl.java
@@ -35,12 +35,12 @@
import org.apache.felix.framework.util.manifestparser.R4Library;
import org.apache.felix.framework.wiring.BundleCapabilityImpl;
import org.apache.felix.framework.wiring.BundleRequirementImpl;
-import org.apache.felix.framework.wiring.FelixBundleWire;
import org.osgi.framework.BundlePermission;
import org.osgi.framework.Constants;
import org.osgi.framework.PackagePermission;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
class ResolverStateImpl implements Resolver.ResolverState
{
@@ -145,7 +145,7 @@
// If so, then the framework must have chosen to have the revision
// import rather than export the package, so we need to remove the
// corresponding package capability from the package capability set.
- for (FelixBundleWire w : ((BundleRevisionImpl) br).getWires())
+ for (BundleWire w : ((BundleRevisionImpl) br).getWires())
{
if (w.getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
{
diff --git a/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java b/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
index 7cfb8cb..f544c4a 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceRegistrationImpl.java
@@ -27,10 +27,10 @@
import org.apache.felix.framework.util.StringMap;
import org.apache.felix.framework.util.Util;
import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-import org.apache.felix.framework.wiring.FelixBundleWire;
import org.osgi.framework.*;
import org.osgi.framework.BundleReference;
import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
class ServiceRegistrationImpl implements ServiceRegistration
{
@@ -487,10 +487,10 @@
Util.getClassPackage(className);
BundleRevision requesterRevision = ((BundleImpl) requester).getCurrentRevision();
// Get package wiring from service requester.
- FelixBundleWire requesterWire = Util.getWire(requesterRevision, pkgName);
+ BundleWire requesterWire = Util.getWire(requesterRevision, pkgName);
// Get package wiring from service provider.
BundleRevision providerRevision = ((BundleImpl) m_bundle).getCurrentRevision();
- FelixBundleWire providerWire = Util.getWire(providerRevision, pkgName);
+ BundleWire providerWire = Util.getWire(providerRevision, pkgName);
// There are four situations that may occur here:
// 1. Neither the requester, nor provider have wires for the package.
@@ -550,7 +550,8 @@
{
// If requester has access to the class, verify it is the
// same class as the provider.
- allow = (providerWire.getClass(className) == requestClass);
+ allow = (((BundleRevisionImpl) providerRevision)
+ .getClassByDelegation(className) == requestClass);
}
catch (Exception ex)
{
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java b/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
index 2d01768..c6d6a5c 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Candidates.java
@@ -356,6 +356,7 @@
{
hostReq = r;
it.remove();
+ break;
}
}
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 9dc122d..829098e 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
@@ -34,11 +34,11 @@
import org.apache.felix.framework.util.Util;
import org.apache.felix.framework.wiring.BundleCapabilityImpl;
import org.apache.felix.framework.wiring.BundleRequirementImpl;
-import org.apache.felix.framework.wiring.FelixBundleWire;
import org.osgi.framework.Constants;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRequirement;
import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
public class ResolverImpl implements Resolver
{
@@ -376,14 +376,12 @@
return null;
}
}
- // If any of our wires have this package, then we cannot
- // attempt to dynamically import it.
- for (FelixBundleWire w : ((BundleRevisionImpl) revision).getWires())
+
+ // If this revision already imports or requires this package, then
+ // we cannot dynamically import it.
+ if (((BundleRevisionImpl) revision).hasPackageSource(pkgName))
{
- if (w.hasPackage(pkgName))
- {
- return null;
- }
+ return null;
}
// Loop through the importer's dynamic requirements to determine if
@@ -468,7 +466,7 @@
if (revision.getWiring() != null)
{
// Use wires to get actual requirements and satisfying capabilities.
- for (FelixBundleWire wire : ((BundleRevisionImpl) revision).getWires())
+ for (BundleWire wire : ((BundleRevisionImpl) revision).getWires())
{
// Wrap the requirement as a hosted requirement
// if it comes from a fragment, since we will need
@@ -1173,7 +1171,7 @@
// exports are substitutable.
if (revision.getWiring() != null)
{
- for (FelixBundleWire wire : ((BundleRevisionImpl) revision).getWires())
+ for (BundleWire wire : ((BundleRevisionImpl) revision).getWires())
{
if (wire.getRequirement().getNamespace().equals(
BundleCapabilityImpl.PACKAGE_NAMESPACE))
@@ -1350,14 +1348,15 @@
if ((cands != null) && (cands.size() > 0))
{
BundleCapability cand = cands.iterator().next();
- if (cand.getRevision().getWiring() == null)
- {
- populateWireMap(cand.getRevision(),
- revisionPkgMap, wireMap, allCandidates);
- }
// Ignore revisions that import themselves.
if (!revision.equals(cand.getRevision()))
{
+ if (cand.getRevision().getWiring() == null)
+ {
+ populateWireMap(cand.getRevision(),
+ revisionPkgMap, wireMap, allCandidates);
+ }
+ Packages candPkgs = revisionPkgMap.get(cand.getRevision());
ResolverWire wire = new ResolverWireImpl(
unwrappedRevision,
(BundleRequirementImpl) getActualRequirement(req),
@@ -1428,6 +1427,7 @@
allCandidates);
}
+ Packages candPkgs = revisionPkgMap.get(blame.m_cap.getRevision());
Map<String, Object> attrs = new HashMap(1);
attrs.put(BundleCapabilityImpl.PACKAGE_ATTR, pkgName);
packageWires.add(
@@ -1595,44 +1595,6 @@
{
m_revision = revision;
}
-
- public List<String> getExportedAndReexportedPackages()
- {
- List<String> pkgs = new ArrayList();
- // Grab the revision's actual exported packages.
- // Note that we ignore the calculated exported packages here,
- // because bundles that import their own exports still continue
- // to provide access to their exports when they are required; i.e.,
- // the implicitly reexport the packages if wired to another provider.
- List<BundleCapability> caps = (m_revision.getWiring() != null)
- ? m_revision.getWiring().getCapabilities(null)
- : m_revision.getDeclaredCapabilities(null);
- for (BundleCapability cap : caps)
- {
- if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
- {
- pkgs.add((String)
- cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
- }
- }
- // Grab all required and reexported required packages.
- for (Entry<String, List<Blame>> entry : m_requiredPkgs.entrySet())
- {
- for (Blame blame : entry.getValue())
- {
- String value = blame.m_reqs.get(
- blame.m_reqs.size() - 1).getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
- if ((value != null)
- && value.equals(Constants.VISIBILITY_REEXPORT))
- {
- pkgs.add((String)
- blame.m_cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
- break;
- }
- }
- }
- return pkgs;
- }
}
private static class Blame
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWire.java b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWire.java
index 69162b9..324c6df 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWire.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/ResolverWire.java
@@ -18,6 +18,7 @@
*/
package org.apache.felix.framework.resolver;
+import java.util.Set;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRequirement;
import org.osgi.framework.wiring.BundleRevision;
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 7a51877..d89012e 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
@@ -18,8 +18,6 @@
*/
package org.apache.felix.framework.resolver;
-import org.apache.felix.framework.wiring.BundleCapabilityImpl;
-import org.apache.felix.framework.wiring.BundleRequirementImpl;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRequirement;
import org.osgi.framework.wiring.BundleRevision;
@@ -31,7 +29,8 @@
private final BundleRevision m_provider;
private final BundleCapability m_cap;
- public ResolverWireImpl(BundleRevision requirer, BundleRequirement req,
+ public ResolverWireImpl(
+ BundleRevision requirer, BundleRequirement req,
BundleRevision provider, BundleCapability cap)
{
m_requirer = requirer;
diff --git a/framework/src/main/java/org/apache/felix/framework/util/Util.java b/framework/src/main/java/org/apache/felix/framework/util/Util.java
index 38f8ecf..817ad66 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/Util.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/Util.java
@@ -31,12 +31,12 @@
import org.apache.felix.framework.capabilityset.CapabilitySet;
import org.apache.felix.framework.wiring.BundleCapabilityImpl;
import org.apache.felix.framework.wiring.BundleRequirementImpl;
-import org.apache.felix.framework.wiring.FelixBundleWire;
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
public class Util
{
@@ -327,15 +327,17 @@
return matching;
}
- public static FelixBundleWire getWire(BundleRevision br, String name)
+ public static BundleWire getWire(BundleRevision br, String name)
{
- List<FelixBundleWire> wires = ((BundleRevisionImpl) br).getWires();
+ List<BundleWire> wires = ((BundleRevisionImpl) br).getWires();
if (wires != null)
{
- for (FelixBundleWire w : wires)
+ for (BundleWire w : wires)
{
- if (w.getCapability().getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) &&
- w.getCapability().getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR).equals(name))
+ if (w.getCapability().getNamespace()
+ .equals(BundleCapabilityImpl.PACKAGE_NAMESPACE) &&
+ w.getCapability().getAttributes()
+ .get(BundleCapabilityImpl.PACKAGE_ATTR).equals(name))
{
return w;
}
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
new file mode 100644
index 0000000..2909b0a
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/wiring/BundleWireImpl.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.felix.framework.wiring;
+
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
+
+// TODO: OSGi R4.3 - Should this be in framework package?
+public class BundleWireImpl implements BundleWire
+{
+ private final BundleRevision m_requirer;
+ private final BundleRequirement m_req;
+ private final BundleRevision m_provider;
+ private final BundleCapability m_cap;
+
+ public BundleWireImpl(BundleRevision requirer, BundleRequirement req,
+ BundleRevision provider, BundleCapability cap)
+ {
+ m_requirer = requirer;
+ m_req = req;
+ m_provider = provider;
+ m_cap = cap;
+ }
+
+ public BundleWiring getRequirerWiring()
+ {
+ return m_requirer.getWiring();
+ }
+
+ public BundleRequirement getRequirement()
+ {
+ return m_req;
+ }
+
+ public BundleWiring getProviderWiring()
+ {
+ return m_provider.getWiring();
+ }
+
+ public BundleCapability getCapability()
+ {
+ return m_cap;
+ }
+
+ public String toString()
+ {
+ return "[" + m_requirer + "] "
+ + m_req
+ + " -> "
+ + "[" + m_provider + "]";
+ }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/wiring/FelixBundleWire.java b/framework/src/main/java/org/apache/felix/framework/wiring/FelixBundleWire.java
deleted file mode 100644
index 539e24b..0000000
--- a/framework/src/main/java/org/apache/felix/framework/wiring/FelixBundleWire.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.apache.felix.framework.wiring;
-
-import java.net.URL;
-import java.util.Enumeration;
-import org.apache.felix.framework.resolver.ResourceNotFoundException;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
-
-public interface FelixBundleWire extends BundleWire
-{
- public BundleRevision getRequirer();
-
- public BundleRevision getProvider();
-
- /**
- * Returns whether or not the wire has a given package name. For some
- * wires, such as ones for Require-Bundle, there may be many packages.
- * This method is necessary since the set of packages attained by wires
- * restrict which packages can be dynamically imported (i.e., you cannot
- * dynamically import a package that is already attainable from an
- * existing wire).
- * @return <tt>true</tt> if the package name is attainable from this wire,
- * <tt>false</tt> otherwise.
- **/
- boolean hasPackage(String pkgName);
- /**
- * Requests a class from the exporting module. If the class is found, then
- * it is returned. If the class is not found, then this method may or may
- * not throw an exception depending on the wire type (e.g., for an
- * imported package or a required bundle). Throwing an exception indicates
- * that the search should be aborted, while returning a <tt>null</tt>
- * indicates that the search should continue.
- * @return The class if found or <tt>null</tt> if not found and the search
- * should continue.
- * @throws java.lang.ClassNotFoundException If the class was not found and
- * the search should be aborted.
- **/
- Class getClass(String name) throws ClassNotFoundException;
- /**
- * Requests a resource from the exporting module. If the resource is found,
- * then an URL is returned. If the resource is not found, then this method may
- * or may not throw an exception depending on the wire type (e.g., for an
- * imported package or a required bundle). Throwing an exception indicates
- * that the search should be aborted, while returning a <tt>null</tt>
- * indicates that the search should continue.
- * @return An URL to the resource if found or <tt>null</tt> if not found
- * and the search should continue.
- * @throws ResourceNotFoundException If the resource was not found and
- * the search should be aborted.
- **/
- URL getResource(String name) throws ResourceNotFoundException;
- /**
- * Requests resources from the exporting module. If the resources are found,
- * then an enumeration of URLs is returned. If the resources are not found,
- * then this method may or may not throw an exception depending on the wire
- * type (e.g., for an imported package or a required bundle). Throwing an
- * exception indicates that the search should be aborted, while returning a
- * <tt>null</tt> indicates that the search should continue.
- * @return An enumeration of URLs for the resource if found or <tt>null</tt>
- * if not found and the search should continue.
- * @throws ResourceNotFoundException If the resource was not found and
- * the search should be aborted.
- **/
- Enumeration getResources(String name) throws ResourceNotFoundException;
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/wiring/FelixBundleWireImpl.java b/framework/src/main/java/org/apache/felix/framework/wiring/FelixBundleWireImpl.java
deleted file mode 100644
index c075a02..0000000
--- a/framework/src/main/java/org/apache/felix/framework/wiring/FelixBundleWireImpl.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.apache.felix.framework.wiring;
-
-import org.apache.felix.framework.resolver.*;
-import java.net.URL;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Set;
-import org.apache.felix.framework.BundleRevisionImpl;
-import org.apache.felix.framework.util.Util;
-import org.osgi.framework.Constants;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
-import org.osgi.framework.wiring.BundleWiring;
-
-// TODO: OSGi R4.3 - Should this be in framework package?
-public class FelixBundleWireImpl implements FelixBundleWire
-{
- private final BundleRevision m_requirer;
- private final BundleRequirement m_req;
- private final BundleRevision m_provider;
- private final BundleCapability m_cap;
- private volatile Set<String> m_packages;
-
- public FelixBundleWireImpl(BundleRevision requirer, BundleRequirement req,
- BundleRevision provider, BundleCapability cap)
- {
- m_requirer = requirer;
- m_req = req;
- m_provider = provider;
- m_cap = cap;
- }
-
- public BundleRevision getRequirer()
- {
- return m_requirer;
- }
-
- public BundleWiring getRequirerWiring()
- {
- return m_requirer.getWiring();
- }
-
- public BundleRequirement getRequirement()
- {
- return m_req;
- }
-
- public BundleRevision getProvider()
- {
- return m_provider;
- }
-
- public BundleWiring getProviderWiring()
- {
- return m_provider.getWiring();
- }
-
- public BundleCapability getCapability()
- {
- return m_cap;
- }
-
- public String toString()
- {
- return "[" + m_requirer + "] "
- + m_req
- + " -> "
- + "[" + m_provider + "]";
- }
-
- /* (non-Javadoc)
- * @see org.apache.felix.framework.searchpolicy.IWire#getClass(java.lang.String)
- */
- public boolean hasPackage(String pkgName)
- {
- boolean result = false;
- if (m_cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
- {
- result = m_cap.getAttributes()
- .get(BundleCapabilityImpl.PACKAGE_ATTR).equals(pkgName);
- }
- else if (m_cap.getNamespace().equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
- {
- if (m_packages == null)
- {
- m_packages = calculateRequiredPackages(
- m_provider.getWiring(), new HashSet<String>());
- }
- result = m_packages.contains(pkgName);
- }
- return result;
- }
-
- /* (non-Javadoc)
- * @see org.apache.felix.framework.searchpolicy.IWire#getClass(java.lang.String)
- */
- public Class getClass(String name) throws ClassNotFoundException
- {
- Class clazz = null;
-
- // Get the package of the target class.
- String pkgName = Util.getClassPackage(name);
-
- // Only check if this wire provides the target package.
- if (hasPackage(pkgName))
- {
- String namespace = m_cap.getNamespace();
- if (namespace.equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
- {
- // Check the include/exclude filters from the target package
- // to make sure that the class is actually visible. We delegate
- // to the exporting revision, rather than its content, so it can
- // it can follow any internal wires it may have (e.g., if the
- // package has multiple sources).
- if (((BundleCapabilityImpl) m_cap).isIncluded(name))
- {
- clazz = ((BundleRevisionImpl) m_provider).getClassByDelegation(name);
- }
-
- // If no class was found, then we must throw an exception
- // since the exporter for this package did not contain the
- // requested class.
- if (clazz == null)
- {
- throw new ClassNotFoundException(name);
- }
- }
- else if (namespace.equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
- {
- try
- {
- clazz = ((BundleRevisionImpl) m_provider).getClassByDelegation(name);
- }
- catch (ClassNotFoundException ex)
- {
- // Do not throw the exception here, since we want
- // to continue search other package sources and
- // ultimately the revision's own content.
- }
- }
- }
-
- return clazz;
- }
-
- /* (non-Javadoc)
- * @see org.apache.felix.framework.searchpolicy.IWire#getResource(java.lang.String)
- */
- public URL getResource(String name) throws ResourceNotFoundException
- {
- URL url = null;
-
- // Get the package of the target class.
- String pkgName = Util.getResourcePackage(name);
-
- // Only check if this wire provides the target package.
- if (hasPackage(pkgName))
- {
- String namespace = m_cap.getNamespace();
- if (namespace.equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
- {
- // Delegate to the exporting revision, rather than its
- // content, so that it can follow any internal wires it may have
- // (e.g., if the package has multiple sources).
- url = ((BundleRevisionImpl) m_provider).getResourceByDelegation(name);
-
- // If no resource was found, then we must throw an exception
- // since the exporter for this package did not contain the
- // requested class.
- if (url == null)
- {
- throw new ResourceNotFoundException(name);
- }
- }
- else if (namespace.equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
- {
- url = ((BundleRevisionImpl) m_provider).getResourceByDelegation(name);
-
- // Don't throw ResourceNotFoundException because require-bundle
- // dependencies support split packages.
- }
-
- }
-
- return url;
- }
-
- /* (non-Javadoc)
- * @see org.apache.felix.framework.searchpolicy.IWire#getResources(java.lang.String)
- */
- public Enumeration getResources(String name) throws ResourceNotFoundException
- {
- Enumeration urls = null;
-
- // Get the package of the target class.
- String pkgName = Util.getResourcePackage(name);
-
- // Only check if this wire provides the target package.
- if (hasPackage(pkgName))
- {
- String namespace = m_cap.getNamespace();
- if (namespace.equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
- {
- urls = ((BundleRevisionImpl) m_provider).getResourcesByDelegation(name);
-
- // If no resource was found, then we must throw an exception
- // since the exporter for this package did not contain the
- // requested class.
- if ((urls == null) || !urls.hasMoreElements())
- {
- throw new ResourceNotFoundException(name);
- }
- }
- else if (namespace.equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
- {
- urls = ((BundleRevisionImpl) m_provider).getResourcesByDelegation(name);
-
- // Don't throw ResourceNotFoundException because require-bundle
- // dependencies support split packages.
- }
- }
-
- return urls;
- }
-
- private static Set<String> calculateRequiredPackages(
- BundleWiring providerWiring, Set<String> packages)
- {
-// TODO: OSGi R4.3 - This might be calcualted differently when BundleWiring
-// returns the proper information.
-
- // Add exported packages.
- for (BundleCapability cap : providerWiring.getCapabilities(null))
- {
- if (cap.getNamespace().equals(BundleCapabilityImpl.PACKAGE_NAMESPACE))
- {
- packages.add(
- (String) cap.getAttributes().get(BundleCapabilityImpl.PACKAGE_ATTR));
- }
- }
-
- // Add re-exported packages for any required bundle dependencies
- // that are re-exported.
- for (BundleWire bw : providerWiring.getRequiredWires(null))
- {
- if (bw.getRequirement().getNamespace().equals(BundleCapabilityImpl.BUNDLE_NAMESPACE))
- {
- String dir =
- bw.getRequirement().getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
- if ((dir != null) && (dir.equals(Constants.VISIBILITY_REEXPORT)))
- {
- calculateRequiredPackages(bw.getProviderWiring(), packages);
- }
- }
- }
- return packages;
- }
-}
\ No newline at end of file