You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2009/01/08 20:35:09 UTC

svn commit: r732800 [3/4] - in /felix/trunk/framework/src/main/java/org/apache/felix: framework/ framework/cache/ framework/searchpolicy/ framework/util/ moduleloader/

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/FelixResolverState.java Thu Jan  8 11:35:07 2009
@@ -24,6 +24,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import org.apache.felix.framework.searchpolicy.ModuleImpl;
 import org.apache.felix.framework.searchpolicy.Resolver;
 import org.apache.felix.framework.searchpolicy.PackageSource;
 import org.apache.felix.framework.util.Util;
@@ -32,7 +33,6 @@
 import org.apache.felix.moduleloader.IModule;
 import org.apache.felix.moduleloader.IRequirement;
 import org.apache.felix.moduleloader.IWire;
-import org.apache.felix.moduleloader.ModuleImpl;
 import org.osgi.framework.Constants;
 import org.osgi.framework.PackagePermission;
 import org.osgi.framework.Version;
@@ -66,7 +66,7 @@
         // exports to simplify later processing when resolving bundles.
         m_moduleList.add(module);
 
-        ICapability[] caps = module.getDefinition().getCapabilities();
+        ICapability[] caps = module.getCapabilities();
 
         // Add exports to unresolved package map.
         for (int i = 0; (caps != null) && (i < caps.length); i++)
@@ -93,7 +93,7 @@
         m_moduleList.remove(module);
 
         // Remove exports from package maps.
-        ICapability[] caps = module.getDefinition().getCapabilities();
+        ICapability[] caps = module.getCapabilities();
         for (int i = 0; (caps != null) && (i < caps.length); i++)
         {
             if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
@@ -132,6 +132,9 @@
         // Set wires to null, which will remove the module from all
         // of its dependent modules.
         ((ModuleImpl) module).setWires(null);
+        // Close the module's content.
+        ((ModuleImpl) module).close();
+
         // Remove the module from the "resolved" map.
 // TODO: RB - Maybe this can be merged with ModuleData.
         m_resolvedCapMap.remove(module);
@@ -139,6 +142,39 @@
         m_moduleDataMap.remove(module);
     }
 
+/* TODO: RESOLVER - We need to figure out what to do with this.
+    public void moduleRefreshed(ModuleEvent event)
+    {
+        synchronized (m_factory)
+        {
+            IModule module = event.getModule();
+            // Remove exports from package maps.
+            ICapability[] caps = event.getModule().getDefinition().getCapabilities();
+            // Add exports to unresolved package map.
+            for (int i = 0; (caps != null) && (i < caps.length); i++)
+            {
+                ICapability[] resolvedCaps = (ICapability[]) m_resolvedCapMap.get(module);
+                resolvedCaps = addCapabilityToArray(resolvedCaps, caps[i]);
+                m_resolvedCapMap.put(module, resolvedCaps);
+
+                // If the capability is a package, then add the exporter module
+                // of the wire to the "resolved" package index and remove it
+                // from the "unresolved" package index.
+                if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+                {
+                    // Get package name.
+                    String pkgName = (String)
+                        caps[i].getProperties().get(ICapability.PACKAGE_PROPERTY);
+                    // Add to "resolved" package index.
+                    indexPackageCapability(
+                        m_resolvedPkgIndexMap,
+                        module,
+                        caps[i]);
+                }
+            }
+        }
+    }
+*/
     private void dumpPackageIndexMap(Map pkgIndexMap)
     {
         for (Iterator i = pkgIndexMap.entrySet().iterator(); i.hasNext(); )
@@ -164,24 +200,10 @@
         return (IModule[]) m_moduleList.toArray(new IModule[m_moduleList.size()]);
     }
 
-    public String getBundleSymbolicName(IModule module)
-    {
-        ICapability[] caps = module.getDefinition().getCapabilities();
-        for (int capIdx = 0; (caps != null) && (capIdx < caps.length); capIdx++)
-        {
-            if (caps[capIdx].getNamespace().equals(ICapability.MODULE_NAMESPACE))
-            {
-                return (String)
-                    caps[capIdx].getProperties().get(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE);
-            }
-        }
-        return null;
-    }
-
 // TODO: FRAGMENT - Not very efficient.
     private static Version getBundleVersion(IModule module)
     {
-        ICapability[] caps = module.getDefinition().getCapabilities();
+        ICapability[] caps = module.getCapabilities();
         for (int capIdx = 0; (caps != null) && (capIdx < caps.length); capIdx++)
         {
             if (caps[capIdx].getNamespace().equals(ICapability.MODULE_NAMESPACE))
@@ -193,27 +215,9 @@
         return Version.emptyVersion;
     }
 
-    public synchronized boolean isResolved(IModule module)
+    public synchronized void moduleResolved(IModule module)
     {
-        ModuleData data = (ModuleData) m_moduleDataMap.get(module);
-        if (data != null)
-        {
-            return data.m_resolved;
-        }
-        return false;
-    }
-
-    public synchronized void setResolved(IModule module, boolean b)
-    {
-        ModuleData data = (ModuleData) m_moduleDataMap.get(module);
-        if (data == null)
-        {
-            data = new ModuleData(module);
-            m_moduleDataMap.put(module, data);
-        }
-        data.m_resolved = b;
-
-        if (data.m_resolved)
+        if (module.isResolved())
         {
             // At this point, we need to remove all of the resolved module's
             // capabilities from the "unresolved" package map and put them in
@@ -223,7 +227,7 @@
             // module and not another module. If it points to another module
             // then the capability should be ignored, since the framework
             // decided to honor the import and discard the export.
-            ICapability[] caps = module.getDefinition().getCapabilities();
+            ICapability[] caps = module.getCapabilities();
 
             // First remove all existing capabilities from the "unresolved" map.
             for (int capIdx = 0; (caps != null) && (capIdx < caps.length); capIdx++)
@@ -261,18 +265,15 @@
                 // satisfies any of the wire requirements.
                 for (int wireIdx = 0; (wires != null) && (wireIdx < wires.length); wireIdx++)
                 {
-                    // If the wire requirement is satisfied by the current capability,
-                    // then check to see if the wire is to the module itself. If it
-                    // is to another module, then null the current capability since
-                    // it was both providing and requiring the same capability and
-                    // the resolve process chose to import rather than provide that
-                    // capability, therefore we should ignore it.
+                    // If one of the module's capabilities satifies the requirement
+                    // for an existing wire, this means the capability was
+                    // substituted with another provider by the resolver and
+                    // the module's capability was not used. Therefore, we should
+                    // null it here so it doesn't get added the list of resolved
+                    // capabilities for this module.
                     if (wires[wireIdx].getRequirement().isSatisfied(capsCopy[capIdx]))
                     {
-                        if (!wires[wireIdx].getExporter().equals(module))
-                        {
-                            capsCopy[capIdx] = null;
-                        }
+                        capsCopy[capIdx] = null;
                         break;
                     }
                 }
@@ -314,7 +315,7 @@
     {
         List hostList = new ArrayList();
 
-        IRequirement[] reqs = fragment.getDefinition().getRequirements();
+        IRequirement[] reqs = fragment.getRequirements();
         IRequirement hostReq = null;
         for (int reqIdx = 0; reqIdx < reqs.length; reqIdx++)
         {
@@ -328,14 +329,14 @@
         IModule[] modules = getModules();
         for (int modIdx = 0; (hostReq != null) && (modIdx < modules.length); modIdx++)
         {
-            if (!fragment.equals(modules[modIdx]) && !isResolved(modules[modIdx]))
+            if (!fragment.equals(modules[modIdx]) && !modules[modIdx].isResolved())
             {
-                ICapability[] caps = modules[modIdx].getDefinition().getCapabilities();
+                ICapability[] caps = modules[modIdx].getCapabilities();
                 for (int capIdx = 0; (caps != null) && (capIdx < caps.length); capIdx++)
                 {
                     if (caps[capIdx].getNamespace().equals(ICapability.HOST_NAMESPACE)
                         && hostReq.isSatisfied(caps[capIdx])
-                        && !modules[modIdx].isStale())
+                        && !((BundleImpl) modules[modIdx].getBundle()).isStale())
                     {
                         hostList.add(modules[modIdx]);
                         break;
@@ -353,7 +354,7 @@
 // TODO: FRAGMENT - This should check to make sure that the host allows fragments.
         Map fragmentMap = new HashMap();
 
-        ICapability[] caps = host.getDefinition().getCapabilities();
+        ICapability[] caps = host.getCapabilities();
         ICapability bundleCap = null;
         for (int capIdx = 0; capIdx < caps.length; capIdx++)
         {
@@ -369,12 +370,13 @@
         {
             if (!host.equals(modules[modIdx]))
             {
-                IRequirement[] reqs = modules[modIdx].getDefinition().getRequirements();
+                IRequirement[] reqs = modules[modIdx].getRequirements();
                 for (int reqIdx = 0; (reqs != null) && (reqIdx < reqs.length); reqIdx++)
                 {
                     if (reqs[reqIdx].getNamespace().equals(ICapability.HOST_NAMESPACE)
                         && reqs[reqIdx].isSatisfied(bundleCap)
-                        && !modules[modIdx].isStale())
+                        && !((BundleImpl) modules[modIdx].getBundle()).isStale()
+                        && !((BundleImpl) modules[modIdx].getBundle()).isRemovalPending())
                     {
                         indexFragment(fragmentMap, modules[modIdx]);
                         break;
@@ -404,7 +406,7 @@
                 {
 // TODO: RB - Is this permission check correct.
                     if ((System.getSecurityManager() != null) &&
-                        !((BundleProtectionDomain) modules[modIdx].getContentLoader().getSecurityContext()).impliesDirect(
+                        !((BundleProtectionDomain) modules[modIdx].getSecurityContext()).impliesDirect(
                             new PackagePermission(pkgName,
                                 PackagePermission.EXPORT)))
                     {
@@ -439,7 +441,7 @@
 // TODO: RB - Is this permission check correct.
                         if (resolvedCaps[capIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE) &&
                             (System.getSecurityManager() != null) &&
-                            !((BundleProtectionDomain) module.getContentLoader().getSecurityContext()).impliesDirect(
+                            !((BundleProtectionDomain) module.getSecurityContext()).impliesDirect(
                                 new PackagePermission(
                                     (String) resolvedCaps[capIdx].getProperties().get(ICapability.PACKAGE_PROPERTY),
                                     PackagePermission.EXPORT)))
@@ -486,7 +488,7 @@
             ICapability cap = Util.getSatisfyingCapability(modules[modIdx], req);
             // If compatible and it is not currently resolved, then add
             // the unresolved candidate to the list.
-            if ((cap != null) && !isResolved(modules[modIdx]))
+            if ((cap != null) && !modules[modIdx].isResolved())
             {
                 PackageSource[] tmp = new PackageSource[candidates.length + 1];
                 System.arraycopy(candidates, 0, tmp, 0, candidates.length);
@@ -574,8 +576,7 @@
 
     private void indexFragment(Map map, IModule module)
     {
-        String symName = getBundleSymbolicName(module);
-        IModule[] modules = (IModule[]) map.get(symName);
+        IModule[] modules = (IModule[]) map.get(module.getSymbolicName());
 
         // We want to add the fragment into the list of matching
         // fragments in sorted order (descending version and
@@ -631,7 +632,7 @@
             }
         }
 
-        map.put(symName, modules);
+        map.put(module.getSymbolicName(), modules);
     }
 
     private static IModule[] removeModuleFromArray(IModule[] modules, IModule m)
@@ -682,7 +683,7 @@
 
     public static ICapability getExportPackageCapability(IModule m, String pkgName)
     {
-        ICapability[] caps = m.getDefinition().getCapabilities();
+        ICapability[] caps = m.getCapabilities();
         for (int i = 0; (caps != null) && (i < caps.length); i++)
         {
             if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE) &&
@@ -719,17 +720,4 @@
 
         return caps;
     }
-    //
-    // Simple utility classes.
-    //
-
-    private static class ModuleData
-    {
-        public IModule m_module = null;
-        public boolean m_resolved = false;
-        public ModuleData(IModule module)
-        {
-            m_module = module;
-        }
-    }
 }
\ No newline at end of file

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/FindEntriesEnumeration.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/FindEntriesEnumeration.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/FindEntriesEnumeration.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/FindEntriesEnumeration.java Thu Jan  8 11:35:07 2009
@@ -22,7 +22,7 @@
 
 class FindEntriesEnumeration implements Enumeration
 {
-    private FelixBundle m_bundle = null;
+    private BundleImpl m_bundle = null;
     private Enumeration m_enumeration = null;
     private String m_path = null;
     private String[] m_filePattern = null;
@@ -30,12 +30,12 @@
     private Object m_next = null;
 
     public FindEntriesEnumeration(
-        FelixBundle bundle, String path, String filePattern, boolean recurse)
+        BundleImpl bundle, String path, String filePattern, boolean recurse)
     {
         m_bundle = bundle;
         m_path = path;
-        m_enumeration = (m_bundle.getInfo().getCurrentModule().getContentLoader().getContent() == null)
-            ? null : m_bundle.getInfo().getCurrentModule().getContentLoader().getContent().getEntries();
+        m_enumeration = (m_bundle.getCurrentModule().getContent() == null)
+            ? null : m_bundle.getCurrentModule().getContent().getEntries();
         m_recurse = recurse;
 
         // Sanity check the parameters.
@@ -113,8 +113,8 @@
                     if (checkSubstring(m_filePattern, lastElement))
                     {
                         // Convert entry name into an entry URL.
-                        return m_bundle.getInfo().getCurrentModule()
-                            .getContentLoader().getResourceFromContent(entryName);
+                        return m_bundle.getCurrentModule()
+                            .getResourceFromContent(entryName);
                     }
                 }
             }

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/GetEntryPathsEnumeration.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/GetEntryPathsEnumeration.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/GetEntryPathsEnumeration.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/GetEntryPathsEnumeration.java Thu Jan  8 11:35:07 2009
@@ -23,17 +23,16 @@
 
 class GetEntryPathsEnumeration implements Enumeration
 {
-    private FelixBundle m_bundle = null;
+    private BundleImpl m_bundle = null;
     private Enumeration m_enumeration = null;
     private String m_path = null;
     private Object m_next = null;
 
-    public GetEntryPathsEnumeration(FelixBundle bundle, String path)
+    public GetEntryPathsEnumeration(BundleImpl bundle, String path)
     {
         m_bundle = bundle;
         m_path = path;
-        m_enumeration = m_bundle.getInfo().getCurrentModule()
-            .getContentLoader().getContent().getEntries();
+        m_enumeration = m_bundle.getCurrentModule().getContent().getEntries();
 
         // Sanity check the parameters.
         if (m_path == null)

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java Thu Jan  8 11:35:07 2009
@@ -20,10 +20,10 @@
 
 import java.util.*;
 
+import org.apache.felix.framework.searchpolicy.ModuleImpl;
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.util.VersionRange;
 import org.apache.felix.moduleloader.IModule;
-import org.apache.felix.moduleloader.ModuleImpl;
 import org.osgi.framework.*;
 import org.osgi.service.packageadmin.*;
 
@@ -111,8 +111,8 @@
             String sym = bundles[i].getSymbolicName();
             if ((sym != null) && sym.equals(symbolicName))
             {
-                String s = (String) ((FelixBundle) bundles[i])
-                    .getInfo().getCurrentHeader().get(Constants.BUNDLE_VERSION);
+                String s = (String) ((BundleImpl) bundles[i])
+                    .getCurrentModule().getHeaders().get(Constants.BUNDLE_VERSION);
                 Version v = (s == null) ? new Version("0.0.0") : new Version(s);
                 if ((vr == null) || vr.isInRange(v))
                 {
@@ -128,10 +128,10 @@
         Arrays.sort(bundles,new Comparator() {
             public int compare(Object o1, Object o2)
             {
-                String s1 = (String) ((FelixBundle) o1)
-                    .getInfo().getCurrentHeader().get(Constants.BUNDLE_VERSION);
-                String s2 = (String) ((FelixBundle) o2)
-                    .getInfo().getCurrentHeader().get(Constants.BUNDLE_VERSION);
+                String s1 = (String) ((BundleImpl) o1)
+                    .getCurrentModule().getHeaders().get(Constants.BUNDLE_VERSION);
+                String s2 = (String) ((BundleImpl) o2)
+                    .getCurrentModule().getHeaders().get(Constants.BUNDLE_VERSION);
                 Version v1 = (s1 == null) ? new Version("0.0.0") : new Version(s1);
                 Version v2 = (s2 == null) ? new Version("0.0.0") : new Version(s2);
                 // Compare in reverse order to get descending sort.
@@ -143,7 +143,7 @@
 
     public int getBundleType(Bundle bundle)
     {
-        Map headerMap = ((FelixBundle) bundle).getInfo().getCurrentHeader();
+        Map headerMap = ((BundleImpl) bundle).getCurrentModule().getHeaders();
         if (headerMap.containsKey(Constants.FRAGMENT_HOST))
         {
             return PackageAdmin.BUNDLE_TYPE_FRAGMENT;
@@ -201,13 +201,12 @@
             // Get attached fragments.
             IModule[] modules =
                 ((ModuleImpl)
-                    ((FelixBundle) bundle).getInfo().getCurrentModule()).getFragments();
+                    ((BundleImpl) bundle).getCurrentModule()).getFragments();
             // Convert fragment modules to bundles.
             List list = new ArrayList();
             for (int i = 0; (modules != null) && (i < modules.length); i++)
             {
-                long id = Util.getBundleIdFromModuleId(modules[i].getId());
-                Bundle b = m_felix.getBundle(id);
+                Bundle b = modules[i].getBundle();
                 if (b != null)
                 {
                     list.add(b);
@@ -225,7 +224,7 @@
     {
         if (getBundleType(bundle) == BUNDLE_TYPE_FRAGMENT)
         {
-            return m_felix.getDependentBundles((FelixBundle) bundle);
+            return m_felix.getDependentBundles((BundleImpl) bundle);
         }
         return null;
     }
@@ -236,10 +235,11 @@
         Bundle[] bundles = m_felix.getBundles();
         for (int i = 0; i < bundles.length; i++)
         {
-            FelixBundle fb = (FelixBundle) bundles[i];
-            if ((symbolicName == null) || (symbolicName.equals(fb.getInfo().getSymbolicName())))
+            BundleImpl impl = (BundleImpl) bundles[i];
+            if ((symbolicName == null)
+                || (symbolicName.equals(impl.getCurrentModule().getSymbolicName())))
             {
-                list.add(new RequiredBundleImpl(m_felix, fb));
+                list.add(new RequiredBundleImpl(m_felix, impl));
             }
         }
         return (list.size() == 0)

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/RequiredBundleImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/RequiredBundleImpl.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/RequiredBundleImpl.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/RequiredBundleImpl.java Thu Jan  8 11:35:07 2009
@@ -22,10 +22,10 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import org.apache.felix.framework.searchpolicy.ModuleImpl;
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.moduleloader.ICapability;
 import org.apache.felix.moduleloader.IModule;
-import org.apache.felix.moduleloader.ModuleImpl;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
@@ -34,9 +34,9 @@
 class RequiredBundleImpl implements RequiredBundle
 {
     private final Felix m_felix;
-    private final FelixBundle m_bundle;
+    private final BundleImpl m_bundle;
 
-    public RequiredBundleImpl(Felix felix, FelixBundle bundle)
+    public RequiredBundleImpl(Felix felix, BundleImpl bundle)
     {
         m_felix = felix;
         m_bundle = bundle;
@@ -55,7 +55,7 @@
     public Bundle[] getRequiringBundles()
     {
         // Spec says to return null for stale bundles.
-        if (m_bundle.getInfo().isStale())
+        if (m_bundle.isStale())
         {
             return null;
         }
@@ -64,7 +64,7 @@
         // associated with this bundle.
         List moduleList = new ArrayList();
         // Loop through all of this bundle's modules.
-        IModule[] modules = m_bundle.getInfo().getModules();
+        IModule[] modules = m_bundle.getModules();
         for (int modIdx = 0; (modules != null) && (modIdx < modules.length); modIdx++)
         {
             // For each of this bundle's modules, loop through all of the
@@ -80,8 +80,7 @@
         Set bundleSet = new HashSet();
         for (int modIdx = 0; modIdx < moduleList.size(); modIdx++)
         {
-            long id = Util.getBundleIdFromModuleId(((IModule) moduleList.get(modIdx)).getId());
-            Bundle bundle = m_felix.getBundle(id);
+            Bundle bundle = ((IModule) moduleList.get(modIdx)).getBundle();
             if (bundle != null)
             {
                 bundleSet.add(bundle);
@@ -94,7 +93,7 @@
     {
         ICapability[] caps = 
             Util.getCapabilityByNamespace(
-                m_bundle.getInfo().getCurrentModule(), ICapability.MODULE_NAMESPACE);
+                m_bundle.getCurrentModule(), ICapability.MODULE_NAMESPACE);
         if ((caps != null) && (caps.length > 0))
         {
             return (Version) caps[0].getProperties().get(Constants.BUNDLE_VERSION_ATTRIBUTE);
@@ -104,6 +103,6 @@
 
     public boolean isRemovalPending()
     {
-        return m_bundle.getInfo().isRemovalPending();
+        return m_bundle.isRemovalPending();
     }
 }
\ No newline at end of file

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java Thu Jan  8 11:35:07 2009
@@ -122,8 +122,7 @@
         // Get the package.
         String pkgName =
             Util.getClassPackage(className);
-        IModule requesterModule = 
-            ((FelixBundle) requester).getInfo().getCurrentModule();
+        IModule requesterModule = ((BundleImpl) requester).getCurrentModule();
         // Get package wiring from service requester.
         IWire requesterWire = Util.getWire(requesterModule, pkgName);
 
@@ -148,8 +147,7 @@
         }
 
         // Get package wiring from service provider.
-        IModule providerModule = 
-            ((FelixBundle) m_bundle).getInfo().getCurrentModule();
+        IModule providerModule = ((BundleImpl) m_bundle).getCurrentModule();
         IWire providerWire = Util.getWire(providerModule, pkgName);
         
         // Case 2: Only include service reference if the service
@@ -159,12 +157,12 @@
             // If the provider is not the exporter of the requester's package,
             // then try to use the service registration to see if the requester's
             // class is accessible.
-            if (!((FelixBundle) m_bundle).getInfo().hasModule(requesterWire.getExporter()))
+            if (!((BundleImpl) m_bundle).hasModule(requesterWire.getExporter()))
             {
                 try
                 {
                     // Load the class from the requesting bundle.
-                    Class requestClass = requesterModule.getClass(className);
+                    Class requestClass = requesterModule.getClassByDelegation(className);
                     // Get the service registration and ask it to check
                     // if the service object is assignable to the requesting
                     // bundle's class.

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java Thu Jan  8 11:35:07 2009
@@ -38,16 +38,13 @@
 
     private Logger m_logger = null;
     private Felix m_felix = null;
-    private List m_requestList = null;
-    private Bundle m_systemBundle = null;
+    private final List m_requestList = new ArrayList();
     private Thread m_thread = null;
 
     public StartLevelImpl(Logger logger, Felix felix)
     {
         m_logger = logger;
         m_felix = felix;
-        m_requestList = new ArrayList();
-        m_systemBundle = m_felix.getBundle(0);
         // Start a thread to perform asynchronous package refreshes.
         m_thread = new Thread(this, "FelixStartLevel");
         m_thread.setDaemon(true);
@@ -85,7 +82,7 @@
     **/
     public int getStartLevel()
     {
-        return m_felix.getStartLevel();
+        return m_felix.getActiveStartLevel();
     }
 
     /* (non-Javadoc)
@@ -98,7 +95,7 @@
         if (sm != null)
         {
             ((SecurityManager) sm).checkPermission(
-                new AdminPermission(m_systemBundle, AdminPermission.STARTLEVEL));
+                new AdminPermission(m_felix, AdminPermission.STARTLEVEL));
         }
         
         if (startlevel <= 0)
@@ -202,7 +199,7 @@
         if (sm != null)
         {
             ((SecurityManager) sm).checkPermission(
-                new AdminPermission(m_systemBundle, AdminPermission.STARTLEVEL));
+                new AdminPermission(m_felix, AdminPermission.STARTLEVEL));
         }
         m_felix.setInitialBundleStartLevel(startlevel);
     }
@@ -262,7 +259,7 @@
             if (request instanceof Integer)
             {
                 // Set the new framework start level.
-                m_felix.setFrameworkStartLevel(((Integer) request).intValue());
+                m_felix.setActiveStartLevel(((Integer) request).intValue());
             }
             else
             {

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlers.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlers.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlers.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlers.java Thu Jan  8 11:35:07 2009
@@ -33,7 +33,7 @@
 import java.util.Map;
 import java.util.StringTokenizer;
 
-import org.apache.felix.framework.searchpolicy.ContentClassLoader;
+import org.apache.felix.framework.searchpolicy.ModuleClassLoader;
 import org.apache.felix.framework.util.FelixConstants;
 import org.apache.felix.framework.util.SecureAction;
 import org.apache.felix.framework.util.SecurityManagerEx;
@@ -611,7 +611,7 @@
         for (int i = 0; i < stack.length; i++)
         {
             if ((stack[i].getClassLoader() != null) && 
-                ContentClassLoader.class.getName().equals(
+                ModuleClassLoader.class.getName().equals(
                 stack[i].getClassLoader().getClass().getName()))
             {
                 targetClass = stack[i];

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java Thu Jan  8 11:35:07 2009
@@ -69,7 +69,7 @@
         //     bundle://<module-id>:<bundle-classpath-index>/<resource-path>
         // Where <module-id> = <bundle-id>.<revision>
         long bundleId = Util.getBundleIdFromModuleId(url.getHost());
-        FelixBundle bundle = (FelixBundle) m_framework.getBundle(bundleId);
+        BundleImpl bundle = (BundleImpl) m_framework.getBundle(bundleId);
         if (bundle == null)
         {
             throw new IOException("No bundle associated with resource: " + url);
@@ -77,7 +77,7 @@
         m_contentTime = bundle.getLastModified();
 
         int revision = Util.getModuleRevisionFromModuleId(url.getHost());
-        IModule[] modules = bundle.getInfo().getModules();
+        IModule[] modules = bundle.getModules();
         if ((modules == null) || (revision >= modules.length))
         {
             throw new IOException("Resource does not exist: " + url);
@@ -102,9 +102,9 @@
         {
             m_classPathIdx = 0;
         }
-        if (!modules[revision].getContentLoader().hasInputStream(m_classPathIdx, url.getPath()))
+        if (!modules[revision].hasInputStream(m_classPathIdx, url.getPath()))
         {
-            URL newurl = modules[revision].getContentLoader().getResource(url.getPath());
+            URL newurl = modules[revision].getResourceByDelegation(url.getPath());
             if (newurl == null)
             {
                 throw new IOException("Resource does not exist: " + url);
@@ -121,8 +121,7 @@
             {
                 throw new IOException("Resource does not exist: " + url);
             }
-            m_is = m_targetModule.getContentLoader()
-                .getInputStream(m_classPathIdx, url.getPath());
+            m_is = m_targetModule.getInputStream(m_classPathIdx, url.getPath());
             m_contentLength = (m_is == null) ? 0 : m_is.available();
             m_contentType = URLConnection.guessContentTypeFromName(url.getFile());
             connected = true;

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlersServiceTracker.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlersServiceTracker.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlersServiceTracker.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/URLHandlersServiceTracker.java Thu Jan  8 11:35:07 2009
@@ -49,8 +49,7 @@
     **/
     public URLHandlersServiceTracker(Felix framework, String filter)
     {
-        m_context = ((FelixBundle) 
-            framework.getBundle(0)).getInfo().getBundleContext();
+        m_context = ((BundleImpl) framework).getBundleContext();
         m_filter = filter;
 
         synchronized (this)

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java Thu Jan  8 11:35:07 2009
@@ -22,10 +22,7 @@
 import java.net.URLDecoder;
 
 import org.apache.felix.framework.Logger;
-import org.apache.felix.framework.util.ObjectInputStreamX;
-import org.apache.felix.moduleloader.IModule;
 import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleActivator;
 
 /**
  * <p>
@@ -77,7 +74,6 @@
     private static final transient String BUNDLE_STATE_FILE = "bundle.state";
     private static final transient String BUNDLE_START_LEVEL_FILE = "bundle.startlevel";
     private static final transient String REFRESH_COUNTER_FILE = "refresh.counter";
-    private static final transient String BUNDLE_ACTIVATOR_FILE = "bundle.activator";
     private static final transient String BUNDLE_LASTMODIFIED_FILE = "bundle.lastmodified";
     private static final transient String REVISION_DIRECTORY = "version";
     private static final transient String DATA_DIRECTORY = "data";
@@ -572,90 +568,6 @@
 
     /**
      * <p>
-     * Returns the serialized activator for this archive. This is an
-     * extension to the OSGi specification.
-     * </p>
-     * @return the serialized activator for this archive.
-     * @throws Exception if any error occurs.
-    **/
-    public synchronized BundleActivator getActivator(IModule module)
-        throws Exception
-    {
-        // Get bundle activator file.
-        File activatorFile = new File(m_archiveRootDir, BUNDLE_ACTIVATOR_FILE);
-        // If the activator file doesn't exist, then
-        // assume there isn't one.
-        if (!BundleCache.getSecureAction().fileExists(activatorFile))
-        {
-            return null;
-        }
-
-        // Deserialize the activator object.
-        InputStream is = null;
-        ObjectInputStreamX ois = null;
-        try
-        {
-            is = BundleCache.getSecureAction()
-                .getFileInputStream(activatorFile);
-            ois = new ObjectInputStreamX(is, module);
-            Object o = ois.readObject();
-            return (BundleActivator) o;
-        }
-        catch (Exception ex)
-        {
-            m_logger.log(
-                Logger.LOG_ERROR,
-                getClass().getName() + ": Trying to deserialize - " + ex);
-        }
-        finally
-        {
-            if (ois != null) ois.close();
-            if (is != null) is.close();
-        }
-
-        return null;
-    }
-
-    /**
-     * <p>
-     * Serializes the activator for this archive.
-     * </p>
-     * @param obj the activator to serialize.
-     * @throws Exception if any error occurs.
-    **/
-    public synchronized void setActivator(Object obj) throws Exception
-    {
-        if (!(obj instanceof Serializable))
-        {
-            return;
-        }
-
-        // Serialize the activator object.
-        OutputStream os = null;
-        ObjectOutputStream oos = null;
-        try
-        {
-            os = BundleCache.getSecureAction()
-                .getFileOutputStream(new File(m_archiveRootDir, BUNDLE_ACTIVATOR_FILE));
-            oos = new ObjectOutputStream(os);
-            oos.writeObject(obj);
-        }
-        catch (IOException ex)
-        {
-            m_logger.log(
-                Logger.LOG_ERROR,
-                getClass().getName() + ": Unable to serialize activator - " + ex);
-            throw ex;
-        }
-        finally
-        {
-            if (oos != null) oos.close();
-            if (os != null) os.close();
-        }
-    }
-
-    /**
-     * <p>
      * Returns the number of revisions available for this archive.
      * </p>
      * @return tthe number of revisions available for this archive.
@@ -733,7 +645,7 @@
      * @return true if the undo was a success false if there is no previous revision
      * @throws Exception if any error occurs.
      */
-    public synchronized boolean undoRevise() throws Exception
+    public synchronized boolean rollbackRevise() throws Exception
     {
         // Can only undo the revision if there is more than one.
         if (getRevisionCount() <= 1)

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java?rev=732800&r1=732799&r2=732800&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java Thu Jan  8 11:35:07 2009
@@ -31,7 +31,7 @@
     private static final transient String LIBRARY_DIRECTORY = "lib";
 
     private Logger m_logger;
-    private Object m_revisionLock;
+    private final Object m_revisionLock;
     private File m_rootDir;
     private File m_dir;
 
@@ -168,7 +168,6 @@
                     }
                 }
             }
-            System.out.println("+++ EXTRACTED JAR DIR " + extractedDir);
             return new JarContent(m_logger, m_revisionLock, extractedDir, file);
         }
 

Added: felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/ModuleClassLoader.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/ModuleClassLoader.java?rev=732800&view=auto
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/ModuleClassLoader.java (added)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/ModuleClassLoader.java Thu Jan  8 11:35:07 2009
@@ -0,0 +1,653 @@
+/*
+ * 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.searchpolicy;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.security.SecureClassLoader;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.felix.framework.Logger;
+import org.apache.felix.framework.cache.JarContent;
+import org.apache.felix.framework.util.Util;
+import org.apache.felix.framework.util.manifestparser.R4Library;
+import org.apache.felix.framework.util.manifestparser.Requirement;
+import org.apache.felix.moduleloader.ICapability;
+import org.apache.felix.moduleloader.IContent;
+import org.apache.felix.moduleloader.IModule;
+import org.apache.felix.moduleloader.IRequirement;
+import org.apache.felix.moduleloader.IWire;
+import org.apache.felix.moduleloader.ResourceNotFoundException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+
+public class ModuleClassLoader extends SecureClassLoader
+{
+    private static final Constructor m_dexFileClassConstructor;
+    private static final Method m_dexFileClassLoadClass;
+    static
+    {
+        Constructor dexFileClassConstructor = null;
+        Method dexFileClassLoadClass = null;
+        try
+        {
+            Class dexFileClass;
+            try
+            {
+                dexFileClass = Class.forName("dalvik.system.DexFile");
+            }
+            catch (Exception ex)
+            {
+                dexFileClass = Class.forName("android.dalvik.DexFile");
+            }
+
+            dexFileClassConstructor = dexFileClass.getConstructor(
+                new Class[] { java.io.File.class });
+            dexFileClassLoadClass = dexFileClass.getMethod("loadClass",
+                new Class[] { String.class, ClassLoader.class });
+        }
+        catch (Exception ex)
+        {
+           dexFileClassConstructor = null;
+           dexFileClassLoadClass = null;
+        }
+        m_dexFileClassConstructor = dexFileClassConstructor;
+        m_dexFileClassLoadClass = dexFileClassLoadClass;
+    }
+
+    private final ModuleImpl m_module;
+    private final ProtectionDomain m_protectionDomain;
+    private final Map m_jarContentToDexFile;
+
+    public ModuleClassLoader(ModuleImpl module, ProtectionDomain protectionDomain)
+    {
+        m_module = module;
+        m_protectionDomain = protectionDomain;
+        if (m_dexFileClassConstructor != null)
+        {
+            m_jarContentToDexFile = new HashMap();
+        }
+        else
+        {
+            m_jarContentToDexFile = null;
+        }
+    }
+
+    public IModule getModule()
+    {
+        return m_module;
+    }
+
+    protected Class loadClass(String name, boolean resolve)
+        throws ClassNotFoundException
+    {
+        Class clazz = null;
+
+        // Make sure the class was not already loaded.
+        synchronized (this)
+        {
+            clazz = findLoadedClass(name);
+        }
+
+        if (clazz == null)
+        {
+            try
+            {
+                return (Class) m_module.findClassOrResourceByDelegation(name, true);
+            }
+            catch (ResourceNotFoundException ex)
+            {
+                // This should never happen since we are asking for a class,
+                // so just ignore it.
+            }
+            catch (ClassNotFoundException cnfe)
+            {
+                ClassNotFoundException ex = cnfe;
+                String msg = name;
+                if (m_module.getLogger().getLogLevel() >= Logger.LOG_DEBUG)
+                {
+                    msg = diagnoseClassLoadError(m_module, name);
+                    ex = new ClassNotFoundException(msg, cnfe);
+                }
+                throw ex;
+            }
+        }
+
+        // Resolve the class and return it.
+        if (resolve)
+        {
+            resolveClass(clazz);
+        }
+        return clazz;
+    }
+
+    protected Class findClass(String name) throws ClassNotFoundException
+    {
+        // Do a quick check here to see if we can short-circuit this
+        // entire process if the class was already loaded.
+        Class clazz = null;
+        synchronized (this)
+        {
+            clazz = findLoadedClass(name);
+        }
+
+        // Search for class in module.
+        if (clazz == null)
+        {
+            String actual = name.replace('.', '/') + ".class";
+
+            byte[] bytes = null;
+
+            IContent content = null;
+            // Check the module class path.
+            for (int i = 0;
+                (bytes == null) &&
+                (i < m_module.getClassPath().length); i++)
+            {
+                bytes = m_module.getClassPath()[i].getEntryAsBytes(actual);
+                content = m_module.getClassPath()[i];
+            }
+
+            if (bytes != null)
+            {
+                // Before we actually attempt to define the class, grab
+                // the lock for this class loader and make sure than no
+                // other thread has defined this class in the meantime.
+                synchronized (this)
+                {
+                    clazz = findLoadedClass(name);
+
+                    if (clazz == null)
+                    {
+                        // We need to try to define a Package object for the class
+                        // before we call defineClass(). Get the package name and
+                        // see if we have already created the package.
+                        String pkgName = Util.getClassPackage(name);
+                        if (pkgName.length() > 0)
+                        {
+                            if (getPackage(pkgName) == null)
+                            {
+                                Object[] params = definePackage(pkgName);
+                                if (params != null)
+                                {
+                                    definePackage(
+                                        pkgName,
+                                        (String) params[0],
+                                        (String) params[1],
+                                        (String) params[2],
+                                        (String) params[3],
+                                        (String) params[4],
+                                        (String) params[5],
+                                        null);
+                                }
+                                else
+                                {
+                                    definePackage(pkgName, null, null,
+                                        null, null, null, null, null);
+                                }
+                            }
+                        }
+
+                        // If we can load the class from a dex file do so
+                        if (content instanceof JarContent)
+                        {
+                            try
+                            {
+                                clazz = getDexFileClass((JarContent) content, name, this);
+                            }
+                            catch (Exception ex)
+                            {
+                                // Looks like we can't
+                            }
+                        }
+
+                        if (clazz == null)
+                        {
+                            // If we have a security context, then use it to
+                            // define the class with it for security purposes,
+                            // otherwise define the class without a protection domain.
+                            if (m_protectionDomain != null)
+                            {
+                                clazz = defineClass(name, bytes, 0, bytes.length,
+                                    m_protectionDomain);
+                            }
+                            else
+                            {
+                                clazz = defineClass(name, bytes, 0, bytes.length);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return clazz;
+    }
+
+    private Object[] definePackage(String pkgName)
+    {
+        Map headerMap = m_module.getHeaders();
+        String spectitle = (String) headerMap.get("Specification-Title");
+        String specversion = (String) headerMap.get("Specification-Version");
+        String specvendor = (String) headerMap.get("Specification-Vendor");
+        String impltitle = (String) headerMap.get("Implementation-Title");
+        String implversion = (String) headerMap.get("Implementation-Version");
+        String implvendor = (String) headerMap.get("Implementation-Vendor");
+        if ((spectitle != null)
+            || (specversion != null)
+            || (specvendor != null)
+            || (impltitle != null)
+            || (implversion != null)
+            || (implvendor != null))
+        {
+            return new Object[] {
+                spectitle, specversion, specvendor, impltitle, implversion, implvendor
+            };
+        }
+        return null;
+    }
+
+    private Class getDexFileClass(JarContent content, String name, ClassLoader loader)
+        throws Exception
+    {
+        if (m_jarContentToDexFile == null)
+        {
+            return null;
+        }
+
+        Object dexFile = null;
+
+        if (!m_jarContentToDexFile.containsKey(content))
+        {
+            try
+            {
+                dexFile = m_dexFileClassConstructor.newInstance(
+                    new Object[] { content.getFile() });
+            }
+            finally
+            {
+                m_jarContentToDexFile.put(content, dexFile);
+            }
+        }
+        else
+        {
+            dexFile = m_jarContentToDexFile.get(content);
+        }
+
+        if (dexFile != null)
+        {
+            return (Class) m_dexFileClassLoadClass.invoke(dexFile,
+                new Object[] { name.replace('.','/'), loader });
+        }
+        return null;
+    }
+
+    public URL getResource(String name)
+    {
+        try
+        {
+            return (URL) m_module.findClassOrResourceByDelegation(name, false);
+        }
+        catch (ClassNotFoundException ex)
+        {
+            // This should never happen, so just ignore it.
+        }
+        catch (ResourceNotFoundException ex)
+        {
+            // Not much we can do here since getResource() does not throw any
+            // exceptions, so just ignore it too.
+        }
+        return null;
+    }
+
+    protected URL findResource(String name)
+    {
+        return m_module.getResourceFromModule(name);
+    }
+
+    // This should actually be findResources(), but it can't be for the
+    // reason described below for the actual findResources() method.
+    Enumeration findResourcesFromModule(String name)
+    {
+        return m_module.getResourcesFromModule(name);
+    }
+
+    // The findResources() method should only look at the module itself, but
+    // instead it tries to delegate because in Java version prior to 1.5 the
+    // getResources() method was final and could not be overridden. We should
+    // override getResources() like getResource() to make it delegate, but we
+    // can't. As a workaround, we make findResources() delegate instead.
+    protected Enumeration findResources(String name)
+    {
+        return m_module.getResourcesByDelegation(name);
+    }
+
+    protected String findLibrary(String name)
+    {
+        // Remove leading slash, if present.
+        if (name.startsWith("/"))
+        {
+            name = name.substring(1);
+        }
+
+        R4Library[] libs = m_module.getNativeLibraries();
+        for (int i = 0; (libs != null) && (i < libs.length); i++)
+        {
+            if (libs[i].match(name))
+            {
+                return m_module.getContent()
+                    .getEntryAsNativeLibrary(libs[i].getEntryName());
+            }
+        }
+
+        return null;
+    }
+
+    public String toString()
+    {
+        return m_module.toString();
+    }
+
+    private static String diagnoseClassLoadError(ModuleImpl module, String name)
+    {
+        // We will try to do some diagnostics here to help the developer
+        // deal with this exception.
+
+        // Get package name.
+        String pkgName = Util.getClassPackage(name);
+
+        // First, get the bundle ID of the module doing the class loader.
+        long impId = Util.getBundleIdFromModuleId(module.getId());
+
+        // Next, check to see if the module imports the package.
+        IWire[] wires = module.getWires();
+        for (int i = 0; (wires != null) && (i < wires.length); i++)
+        {
+            if (wires[i].getCapability().getNamespace().equals(ICapability.PACKAGE_NAMESPACE) &&
+                wires[i].getCapability().getProperties().get(ICapability.PACKAGE_PROPERTY).equals(pkgName))
+            {
+                long expId = Util.getBundleIdFromModuleId(wires[i].getExporter().getId());
+
+                StringBuffer sb = new StringBuffer("*** Package '");
+                sb.append(pkgName);
+                sb.append("' is imported by bundle ");
+                sb.append(impId);
+                sb.append(" from bundle ");
+                sb.append(expId);
+                sb.append(", but the exported package from bundle ");
+                sb.append(expId);
+                sb.append(" does not contain the requested class '");
+                sb.append(name);
+                sb.append("'. Please verify that the class name is correct in the importing bundle ");
+                sb.append(impId);
+                sb.append(" and/or that the exported package is correctly bundled in ");
+                sb.append(expId);
+                sb.append(". ***");
+
+                return sb.toString();
+            }
+        }
+
+        // Next, check to see if the package was optionally imported and
+        // whether or not there is an exporter available.
+        IRequirement[] reqs = module.getRequirements();
+/*
+ * TODO: RB - Fix diagnostic message for optional imports.
+        for (int i = 0; (reqs != null) && (i < reqs.length); i++)
+        {
+            if (reqs[i].getName().equals(pkgName) && reqs[i].isOptional())
+            {
+                // Try to see if there is an exporter available.
+                IModule[] exporters = getResolvedExporters(reqs[i], true);
+                exporters = (exporters.length == 0)
+                    ? getUnresolvedExporters(reqs[i], true) : exporters;
+
+                // An exporter might be available, but it may have attributes
+                // that do not match the importer's required attributes, so
+                // check that case by simply looking for an exporter of the
+                // desired package without any attributes.
+                if (exporters.length == 0)
+                {
+                    IRequirement pkgReq = new Requirement(
+                        ICapability.PACKAGE_NAMESPACE, "(package=" + pkgName + ")");
+                    exporters = getResolvedExporters(pkgReq, true);
+                    exporters = (exporters.length == 0)
+                        ? getUnresolvedExporters(pkgReq, true) : exporters;
+                }
+
+                long expId = (exporters.length == 0)
+                    ? -1 : Util.getBundleIdFromModuleId(exporters[0].getId());
+
+                StringBuffer sb = new StringBuffer("*** Class '");
+                sb.append(name);
+                sb.append("' was not found, but this is likely normal since package '");
+                sb.append(pkgName);
+                sb.append("' is optionally imported by bundle ");
+                sb.append(impId);
+                sb.append(".");
+                if (exporters.length > 0)
+                {
+                    sb.append(" However, bundle ");
+                    sb.append(expId);
+                    if (reqs[i].isSatisfied(
+                        Util.getExportPackage(exporters[0], reqs[i].getName())))
+                    {
+                        sb.append(" does export this package. Bundle ");
+                        sb.append(expId);
+                        sb.append(" must be installed before bundle ");
+                        sb.append(impId);
+                        sb.append(" is resolved or else the optional import will be ignored.");
+                    }
+                    else
+                    {
+                        sb.append(" does export this package with attributes that do not match.");
+                    }
+                }
+                sb.append(" ***");
+
+                return sb.toString();
+            }
+        }
+*/
+        // Next, check to see if the package is dynamically imported by the module.
+/* TODO: RESOLVER: Need to fix this too.
+        IRequirement[] dynamics = module.getDefinition().getDynamicRequirements();
+        for (int dynIdx = 0; dynIdx < dynamics.length; dynIdx++)
+        {
+            IRequirement target = createDynamicRequirement(dynamics[dynIdx], pkgName);
+            if (target != null)
+            {
+                // Try to see if there is an exporter available.
+                PackageSource[] exporters = getResolvedCandidates(target);
+                exporters = (exporters.length == 0)
+                    ? getUnresolvedCandidates(target) : exporters;
+
+                // An exporter might be available, but it may have attributes
+                // that do not match the importer's required attributes, so
+                // check that case by simply looking for an exporter of the
+                // desired package without any attributes.
+                if (exporters.length == 0)
+                {
+                    try
+                    {
+                        IRequirement pkgReq = new Requirement(
+                            ICapability.PACKAGE_NAMESPACE, "(package=" + pkgName + ")");
+                        exporters = getResolvedCandidates(pkgReq);
+                        exporters = (exporters.length == 0)
+                            ? getUnresolvedCandidates(pkgReq) : exporters;
+                    }
+                    catch (InvalidSyntaxException ex)
+                    {
+                        // This should never happen.
+                    }
+                }
+
+                long expId = (exporters.length == 0)
+                    ? -1 : Util.getBundleIdFromModuleId(exporters[0].m_module.getId());
+
+                StringBuffer sb = new StringBuffer("*** Class '");
+                sb.append(name);
+                sb.append("' was not found, but this is likely normal since package '");
+                sb.append(pkgName);
+                sb.append("' is dynamically imported by bundle ");
+                sb.append(impId);
+                sb.append(".");
+                if (exporters.length > 0)
+                {
+                    try
+                    {
+                        if (!target.isSatisfied(
+                            Util.getSatisfyingCapability(exporters[0].m_module,
+                                new Requirement(ICapability.PACKAGE_NAMESPACE, "(package=" + pkgName + ")"))))
+                        {
+                            sb.append(" However, bundle ");
+                            sb.append(expId);
+                            sb.append(" does export this package with attributes that do not match.");
+                        }
+                    }
+                    catch (InvalidSyntaxException ex)
+                    {
+                        // This should never happen.
+                    }
+                }
+                sb.append(" ***");
+
+                return sb.toString();
+            }
+        }
+*/
+        IRequirement pkgReq = null;
+        try
+        {
+            pkgReq = new Requirement(ICapability.PACKAGE_NAMESPACE, "(package=" + pkgName + ")");
+        }
+        catch (InvalidSyntaxException ex)
+        {
+            // This should never happen.
+        }
+        PackageSource[] exporters =
+            module.getResolver().getResolvedCandidates(pkgReq);
+        exporters = (exporters.length == 0)
+            ? module.getResolver().getUnresolvedCandidates(pkgReq)
+            : exporters;
+        if (exporters.length > 0)
+        {
+            boolean classpath = false;
+            try
+            {
+                ModuleClassLoader.class.getClassLoader().loadClass(name);
+                classpath = true;
+            }
+            catch (NoClassDefFoundError err)
+            {
+                // Ignore
+            }
+            catch (Exception ex)
+            {
+                // Ignore
+            }
+
+            long expId = Util.getBundleIdFromModuleId(exporters[0].m_module.getId());
+
+            StringBuffer sb = new StringBuffer("*** Class '");
+            sb.append(name);
+            sb.append("' was not found because bundle ");
+            sb.append(impId);
+            sb.append(" does not import '");
+            sb.append(pkgName);
+            sb.append("' even though bundle ");
+            sb.append(expId);
+            sb.append(" does export it.");
+            if (classpath)
+            {
+                sb.append(" Additionally, the class is also available from the system class loader. There are two fixes: 1) Add an import for '");
+                sb.append(pkgName);
+                sb.append("' to bundle ");
+                sb.append(impId);
+                sb.append("; imports are necessary for each class directly touched by bundle code or indirectly touched, such as super classes if their methods are used. ");
+                sb.append("2) Add package '");
+                sb.append(pkgName);
+                sb.append("' to the '");
+                sb.append(Constants.FRAMEWORK_BOOTDELEGATION);
+                sb.append("' property; a library or VM bug can cause classes to be loaded by the wrong class loader. The first approach is preferable for preserving modularity.");
+            }
+            else
+            {
+                sb.append(" To resolve this issue, add an import for '");
+                sb.append(pkgName);
+                sb.append("' to bundle ");
+                sb.append(impId);
+                sb.append(".");
+            }
+            sb.append(" ***");
+
+            return sb.toString();
+        }
+
+        // Next, try to see if the class is available from the system
+        // class loader.
+        try
+        {
+            ModuleClassLoader.class.getClassLoader().loadClass(name);
+
+            StringBuffer sb = new StringBuffer("*** Package '");
+            sb.append(pkgName);
+            sb.append("' is not imported by bundle ");
+            sb.append(impId);
+            sb.append(", nor is there any bundle that exports package '");
+            sb.append(pkgName);
+            sb.append("'. However, the class '");
+            sb.append(name);
+            sb.append("' is available from the system class loader. There are two fixes: 1) Add package '");
+            sb.append(pkgName);
+            sb.append("' to the '");
+            sb.append(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA);
+            sb.append("' property and modify bundle ");
+            sb.append(impId);
+            sb.append(" to import this package; this causes the system bundle to export class path packages. 2) Add package '");
+            sb.append(pkgName);
+            sb.append("' to the '");
+            sb.append(Constants.FRAMEWORK_BOOTDELEGATION);
+            sb.append("' property; a library or VM bug can cause classes to be loaded by the wrong class loader. The first approach is preferable for preserving modularity.");
+            sb.append(" ***");
+
+            return sb.toString();
+        }
+        catch (Exception ex2)
+        {
+        }
+
+        // Finally, if there are no imports or exports for the package
+        // and it is not available on the system class path, simply
+        // log a message saying so.
+        StringBuffer sb = new StringBuffer("*** Class '");
+        sb.append(name);
+        sb.append("' was not found. Bundle ");
+        sb.append(impId);
+        sb.append(" does not import package '");
+        sb.append(pkgName);
+        sb.append("', nor is the package exported by any other bundle or available from the system class loader.");
+        sb.append(" ***");
+
+        return sb.toString();
+    }
+}
\ No newline at end of file