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 2008/10/14 19:54:13 UTC

svn commit: r704593 - in /felix/trunk/framework/src/main/java/org/apache/felix: framework/Felix.java moduleloader/ModuleImpl.java

Author: rickhall
Date: Tue Oct 14 10:54:13 2008
New Revision: 704593

URL: http://svn.apache.org/viewvc?rev=704593&view=rev
Log:
Modified ExportedPackage.getImportingBundles() to include bundles
that requiring the exporting bundle, in addition to those bundles that
import the package. Also tried to simplify dependency management code
by separating it out. (FELIX-764) 

Modified:
    felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java
    felix/trunk/framework/src/main/java/org/apache/felix/moduleloader/ModuleImpl.java

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java?rev=704593&r1=704592&r2=704593&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java Tue Oct 14 10:54:13 2008
@@ -3092,37 +3092,28 @@
         List list = new ArrayList();
 
         // Get exporting bundle information.
-        FelixBundle exporter = (FelixBundle)
-            (ep).getExportingBundle();
+        FelixBundle exporter = (FelixBundle) ep.getExportingBundle();
 
-        // Search the dependents of the exporter's module revisions
-        // for importers of the specific package.
+        // Get all importers and requirers for all revisions of the bundle.
+        // The spec says that require-bundle should be returned with importers.
         IModule[] expModules = exporter.getInfo().getModules();
         for (int expIdx = 0; (expModules != null) && (expIdx < expModules.length); expIdx++)
         {
-            IModule[] depModules = ((ModuleImpl) expModules[expIdx]).getDependents();
-            for (int depIdx = 0; (depModules != null) && (depIdx < depModules.length); depIdx++)
+            IModule[] dependents = ((ModuleImpl) expModules[expIdx]).getDependentImporters();
+            for (int depIdx = 0; (dependents != null) && (depIdx < dependents.length); depIdx++)
             {
-                // ExportedPackage.getImportingBundles() does not expect bundles
-                // to depend on themselves, so we will filter that case here.
-                if (!expModules[expIdx].equals(depModules[depIdx]))
-                {
-                    // See if the dependent module has a wire for the specific
-                    // package. If so, see if the provider module is from the
-                    // exporter and record it if it is.
-                    IWire wire = Util.getWire(depModules[depIdx], ep.getName());
-                    if ((wire != null) && expModules[expIdx].equals(wire.getExporter()) &&
-                        wire.getRequirement().isSatisfied(
-                        new Capability(ICapability.PACKAGE_NAMESPACE, null, new R4Attribute[] {
-                            new R4Attribute(ICapability.PACKAGE_PROPERTY, ep.getName(), false),
-                            new R4Attribute(ICapability.VERSION_PROPERTY, ep.getVersion(), false)
-                        })))
-                    {
-                        // Add the bundle to the list of importers.
-                        list.add(getBundle(Util.getBundleIdFromModuleId(depModules[depIdx].getId())));
-                    }
+                // ExportedPackage.getImportingBundles() does not expect a bundle to
+                // depend on itself, so ignore that case.
+                if (!expModules[expIdx].equals(dependents[depIdx]))
+                {
+                    list.add(getBundle(Util.getBundleIdFromModuleId(dependents[depIdx].getId())));
                 }
             }
+            dependents = ((ModuleImpl) expModules[expIdx]).getDependentRequirers();
+            for (int depIdx = 0; (dependents != null) && (depIdx < dependents.length); depIdx++)
+            {
+                list.add(getBundle(Util.getBundleIdFromModuleId(dependents[depIdx].getId())));
+            }
         }
 
         // Return the results.
@@ -3266,23 +3257,23 @@
         fireFrameworkEvent(FrameworkEvent.PACKAGES_REFRESHED, this, null);
     }
 
-    private void populateImportGraph(FelixBundle exporter, Map map)
+    private void populateDependentGraph(FelixBundle exporter, Map map)
     {
         // Get all dependent bundles of this bundle.
-        Bundle[] importers = getDependentBundles(exporter);
+        Bundle[] dependents = getDependentBundles(exporter);
 
-        for (int impIdx = 0;
-            (importers != null) && (impIdx < importers.length);
-            impIdx++)
+        for (int depIdx = 0;
+            (dependents != null) && (depIdx < dependents.length);
+            depIdx++)
         {
             // Avoid cycles if the bundle is already in map.
-            if (!map.containsKey(importers[impIdx]))
+            if (!map.containsKey(dependents[depIdx]))
             {
                 // Add each importing bundle to map.
-                map.put(importers[impIdx], importers[impIdx]);
+                map.put(dependents[depIdx], dependents[depIdx]);
                 // Now recurse into each bundle to get its importers.
-                populateImportGraph(
-                    (FelixBundle) importers[impIdx], map);
+                populateDependentGraph(
+                    (FelixBundle) dependents[depIdx], map);
             }
         }
     }
@@ -4295,7 +4286,7 @@
                         FelixBundle target = (FelixBundle) newTargets[targetIdx];
                         map.put(target, target);
                         // Add all importing bundles to map.
-                        populateImportGraph(target, map);
+                        populateDependentGraph(target, map);
                     }
 
                     bundles = (FelixBundle[]) map.values().toArray(new FelixBundle[map.size()]);

Modified: felix/trunk/framework/src/main/java/org/apache/felix/moduleloader/ModuleImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/moduleloader/ModuleImpl.java?rev=704593&r1=704592&r2=704593&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/moduleloader/ModuleImpl.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/moduleloader/ModuleImpl.java Tue Oct 14 10:54:13 2008
@@ -33,7 +33,9 @@
     private IContentLoader m_contentLoader = null;
     private IModule[] m_fragments = null;
     private IWire[] m_wires = null;
-    private IModule[] m_dependents = new IModule[0];
+    private IModule[] m_dependentHosts = new IModule[0];
+    private IModule[] m_dependentImporters = new IModule[0];
+    private IModule[] m_dependentRequirers = new IModule[0];
 
     ModuleImpl(Logger logger, String id, IModuleDefinition md)
     {
@@ -69,20 +71,21 @@
         // dependencies when we are uninstalling the module.
         for (int i = 0; (m_fragments != null) && (i < m_fragments.length); i++)
         {
-            ((ModuleImpl) m_fragments[i]).removeDependent(this);
+            ((ModuleImpl) m_fragments[i]).removeDependentHost(this);
         }
 
         // Update the dependencies on the new fragments.
         m_fragments = fragments;
+
+        // We need to add ourself as a dependent of each fragment
+        // module. We also need to create an array of fragment contents
+        // to attach to our content loader.
         if (m_fragments != null)
         {
-            // We need to add ourself as a dependent of each fragment
-            // module. We also need to create an array of fragment contents
-            // to attach to our content loader.
             IContent[] fragmentContents = new IContent[m_fragments.length];
             for (int i = 0; (m_fragments != null) && (i < m_fragments.length); i++)
             {
-                ((ModuleImpl) m_fragments[i]).addDependent(this);
+                ((ModuleImpl) m_fragments[i]).addDependentHost(this);
                 fragmentContents[i] =
                     m_fragments[i].getContentLoader().getContent()
                         .getEntryAsContent(FelixConstants.CLASS_PATH_DOT);
@@ -99,66 +102,105 @@
 
     public synchronized void setWires(IWire[] wires)
     {
-        // Remove module from old wire modules' dependencies.
+        // 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; (m_wires != null) && (i < m_wires.length); i++)
         {
-            ((ModuleImpl) m_wires[i].getExporter()).removeDependent(this);
+            if (m_wires[i].getCapability().getNamespace().equals(ICapability.MODULE_NAMESPACE))
+            {
+                ((ModuleImpl) m_wires[i].getExporter()).removeDependentRequirer(this);
+            }
+            else if (m_wires[i].getCapability().getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+            {
+                ((ModuleImpl) m_wires[i].getExporter()).removeDependentImporter(this);
+            }
         }
+
         m_wires = wires;
-        // Add module to new wire modules' dependencies.
-        for (int i = 0; (wires != null) && (i < wires.length); i++)
-        {
-            ((ModuleImpl) m_wires[i].getExporter()).addDependent(this);
-        }
-    }
 
-    private synchronized void addDependent(IModule module)
-    {
-        // Make sure the dependent module is not already present.
-        for (int i = 0; i < m_dependents.length; i++)
+        // Add ourself as a dependent to the new wires' modules.
+        for (int i = 0; (m_wires != null) && (i < m_wires.length); i++)
         {
-            if (m_dependents[i].equals(module))
+            if (m_wires[i].getCapability().getNamespace().equals(ICapability.MODULE_NAMESPACE))
+            {
+                ((ModuleImpl) m_wires[i].getExporter()).addDependentRequirer(this);
+            }
+            else if (m_wires[i].getCapability().getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
             {
-                return;
+                ((ModuleImpl) m_wires[i].getExporter()).addDependentImporter(this);
             }
         }
-        IModule[] tmp = new IModule[m_dependents.length + 1];
-        System.arraycopy(m_dependents, 0, tmp, 0, m_dependents.length);
-        tmp[m_dependents.length] = module;
-        m_dependents = tmp;
     }
 
-    private synchronized void removeDependent(IModule module)
+    public synchronized IModule[] getDependentHosts()
     {
-        // Make sure the dependent module is not already present.
-        for (int i = 0; i < m_dependents.length; i++)
-        {
-            if (m_dependents[i].equals(module))
-            {
-                // If this is the module, then point to empty list.
-                if ((m_dependents.length - 1) == 0)
-                {
-                    m_dependents = new IModule[0];
-                }
-                // Otherwise, we need to do some array copying.
-                else
-                {
-                    IModule[] tmp = new IModule[m_dependents.length - 1];
-                    System.arraycopy(m_dependents, 0, tmp, 0, i);
-                    if (i < tmp.length)
-                    {
-                        System.arraycopy(
-                            m_dependents, i + 1, tmp, i, tmp.length - i);
-                    }
-                    m_dependents = tmp;
-                }
-            }
-        }
+        return m_dependentHosts;
+    }
+
+    public synchronized void addDependentHost(IModule module)
+    {
+        m_dependentHosts = addDependent(m_dependentHosts, module);
+    }
+
+    public synchronized void removeDependentHost(IModule module)
+    {
+        m_dependentHosts = removeDependent(m_dependentHosts, module);
+    }
+
+    public synchronized IModule[] getDependentImporters()
+    {
+        return m_dependentImporters;
+    }
+
+    public synchronized void addDependentImporter(IModule module)
+    {
+        m_dependentImporters = addDependent(m_dependentImporters, module);
+    }
+
+    public synchronized void removeDependentImporter(IModule module)
+    {
+        m_dependentImporters = removeDependent(m_dependentImporters, module);
+    }
+
+    public synchronized IModule[] getDependentRequirers()
+    {
+        return m_dependentRequirers;
+    }
+
+    public synchronized void addDependentRequirer(IModule module)
+    {
+        m_dependentRequirers = addDependent(m_dependentRequirers, module);
+    }
+
+    public synchronized void removeDependentRequirer(IModule module)
+    {
+        m_dependentRequirers = removeDependent(m_dependentRequirers, module);
     }
 
     public synchronized IModule[] getDependents()
     {
-        return m_dependents;
+        IModule[] dependents = new IModule[
+            m_dependentHosts.length + m_dependentImporters.length + m_dependentRequirers.length];
+        System.arraycopy(
+            m_dependentHosts,
+            0,
+            dependents,
+            0,
+            m_dependentHosts.length);
+        System.arraycopy(
+            m_dependentImporters,
+            0,
+            dependents,
+            m_dependentHosts.length,
+            m_dependentImporters.length);
+        System.arraycopy(
+            m_dependentRequirers,
+            0,
+            dependents,
+            m_dependentHosts.length + m_dependentImporters.length,
+            m_dependentRequirers.length);
+        return dependents;
     }
 
     public Class getClass(String name) throws ClassNotFoundException
@@ -213,4 +255,51 @@
     {
         return m_id;
     }
+
+    private static IModule[] addDependent(IModule[] modules, IModule module)
+    {
+        // Make sure the dependent module is not already present.
+        for (int i = 0; i < modules.length; i++)
+        {
+            if (modules[i].equals(module))
+            {
+                return modules;
+            }
+        }
+        IModule[] tmp = new IModule[modules.length + 1];
+        System.arraycopy(modules, 0, tmp, 0, modules.length);
+        tmp[modules.length] = module;
+        return tmp;
+    }
+
+    private static IModule[] removeDependent(IModule[] modules, IModule module)
+    {
+        IModule[] tmp = modules;
+
+        // Make sure the dependent module is not already present.
+        for (int i = 0; i < modules.length; i++)
+        {
+            if (modules[i].equals(module))
+            {
+                // If this is the module, then point to empty list.
+                if ((modules.length - 1) == 0)
+                {
+                    tmp = new IModule[0];
+                }
+                // Otherwise, we need to do some array copying.
+                else
+                {
+                    tmp = new IModule[modules.length - 1];
+                    System.arraycopy(modules, 0, tmp, 0, i);
+                    if (i < tmp.length)
+                    {
+                        System.arraycopy(modules, i + 1, tmp, i, tmp.length - i);
+                    }
+                }
+                break;
+            }
+        }
+
+        return tmp;
+    }
 }
\ No newline at end of file