You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pa...@apache.org on 2007/09/16 21:53:22 UTC

svn commit: r576161 - in /felix/trunk/framework/src/main/java/org/apache/felix/framework: Felix.java searchpolicy/R4SearchPolicyCore.java

Author: pauls
Date: Sun Sep 16 12:53:22 2007
New Revision: 576161

URL: http://svn.apache.org/viewvc?rev=576161&view=rev
Log:
Fix a few issues with exporting the same package more then once and handle modified module definitions to make extension bundle exports work again (FELIX-30, FELIX-101).

Modified:
    felix/trunk/framework/src/main/java/org/apache/felix/framework/Felix.java
    felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4SearchPolicyCore.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=576161&r1=576160&r2=576161&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 Sun Sep 16 12:53:22 2007
@@ -40,7 +40,7 @@
 
     // The extension manager to handle extension bundles
     private ExtensionManager m_extensionManager;
-    
+
     // Logging related member variables.
     private Logger m_logger = null; // TODO: KARL - Why package private?
     // Immutable config properties.
@@ -265,7 +265,7 @@
         m_factory = new ModuleFactoryImpl(m_logger);
         m_systemBundleInfo = new BundleInfo(
             m_logger, new SystemBundleArchive(m_cache), null);
-        m_extensionManager = 
+        m_extensionManager =
             new ExtensionManager(m_logger, m_configMap, m_systemBundleInfo);
         m_systemBundleInfo.addModule(
             m_factory.createModule("0", m_extensionManager));
@@ -783,7 +783,7 @@
         // bundle ID from persistent storage. In case of failure, we should
         // keep the max value.
         m_nextId = Math.max(m_nextId, loadNextId());
-        
+
         // Get the framework's default start level.
         int startLevel = FelixConstants.FRAMEWORK_DEFAULT_STARTLEVEL;
         String s = (String) m_configMap.get(FelixConstants.FRAMEWORK_STARTLEVEL_PROP);
@@ -1727,7 +1727,7 @@
                             new AdminPermission(bundle, AdminPermission.LIFECYCLE));
                     }
 
-                    // We need to check whether this is an update to an 
+                    // We need to check whether this is an update to an
                     // extension bundle (info.isExtension) or an update from
                     // a normal bundle to an extension bundle
                     // (isExtensionBundle())
@@ -1744,12 +1744,13 @@
 
                     // If this is an update from a normal to an extension bundle
                     // then attach the extension or else if this already is
-                    // an extension bundle then done allow it to be resolved 
+                    // an extension bundle then done allow it to be resolved
                     // again as per spec.
                     if (!bundle.getInfo().isExtension() &&
                         m_extensionManager.isExtensionBundle(bundle.getInfo().getCurrentHeader()))
                     {
                         m_extensionManager.addExtensionBundle(this, bundle);
+                        m_factory.refreshModule(m_systemBundleInfo.getCurrentModule());
                         bundle.getInfo().setState(Bundle.RESOLVED);
                     }
                     else if (bundle.getInfo().isExtension())
@@ -1803,9 +1804,12 @@
                 for (int i = 0; !used && (i < modules.length); i++)
                 {
                     IModule[] dependents = ((ModuleImpl) modules[i]).getDependents();
-                    if ((dependents != null) && (dependents.length > 0))
+                    for (int j = 0; (dependents != null) && (j < dependents.length) && !used; j++)
                     {
-                        used = true;
+                        if (dependents[j] != modules[i])
+                        {
+                            used = true;
+                        }
                     }
                 }
 
@@ -2065,9 +2069,12 @@
         for (int i = 0; !used && (i < modules.length); i++)
         {
             IModule[] dependents = ((ModuleImpl) modules[i]).getDependents();
-            if ((dependents != null) && (dependents.length > 0))
+            for (int j = 0; (dependents != null) && (j < dependents.length) && !used; j++)
             {
-                used = true;
+                if (dependents[j] != modules[i])
+                {
+                    used = true;
+                }
             }
         }
 
@@ -2239,6 +2246,7 @@
                 else
                 {
                     m_extensionManager.addExtensionBundle(this, bundle);
+                    m_factory.refreshModule(m_systemBundleInfo.getCurrentModule());
                 }
 
             }
@@ -2289,8 +2297,8 @@
             {
                 m_installedBundleMap.put(location, bundle);
             }
-            
-            if (bundle.getInfo().isExtension()) 
+
+            if (bundle.getInfo().isExtension())
             {
                 FelixBundle systemBundle = (FelixBundle) getBundle(0);
                 acquireBundleLock(systemBundle);
@@ -2852,8 +2860,6 @@
     **/
     protected ExportedPackage[] getExportedPackages(String pkgName)
     {
-        ExportedPackage[] pkgs = null;
-
         // First, get all exporters of the package.
         R4SearchPolicyCore.PackageSource[] exporters =
             m_policyCore.getInUseCandidates(
@@ -2865,8 +2871,14 @@
 
         if (exporters != null)
         {
-            pkgs = new ExportedPackage[exporters.length];
-            for (int pkgIdx = 0; pkgIdx < pkgs.length; pkgIdx++)
+            List pkgs = new ArrayList();
+
+            Requirement req = new Requirement(ICapability.PACKAGE_NAMESPACE,
+                null,
+                null,
+                new R4Attribute[] { new R4Attribute(ICapability.PACKAGE_PROPERTY, pkgName, false) });
+
+            for (int pkgIdx = 0; pkgIdx < exporters.length; pkgIdx++)
             {
                 // Get the bundle associated with the current exporting module.
                 FelixBundle bundle = (FelixBundle) getBundle(
@@ -2885,25 +2897,22 @@
                 IModule[] modules = bundle.getInfo().getModules();
                 for (int modIdx = 0; modIdx < modules.length; modIdx++)
                 {
-                    Capability ec = (Capability)
-                        Util.getSatisfyingCapability(
-                            modules[modIdx],
-                            new Requirement(
-                                ICapability.PACKAGE_NAMESPACE,
-                                null,
-                                null,
-                                new R4Attribute[] { new R4Attribute(ICapability.PACKAGE_PROPERTY, pkgName, false) }));
-
-                    if (ec != null)
+                    ICapability[] ec = modules[modIdx].getDefinition().getCapabilities();
+                    for (int i = 0; (ec != null) && (i < ec.length); i++)
                     {
-                        pkgs[pkgIdx] =
-                            new ExportedPackageImpl(this, bundle, modules[modIdx], ec);
+                        if (ec[i].getNamespace().equals(req.getNamespace()) &&
+                            req.isSatisfied(ec[i]))
+                        {
+                            pkgs.add(new ExportedPackageImpl(this, bundle, modules[modIdx], (Capability) ec[i]));
+                        }
                     }
                 }
             }
+
+            return (pkgs.isEmpty()) ? null : (ExportedPackage[]) pkgs.toArray(new ExportedPackage[pkgs.size()]);
         }
 
-        return pkgs;
+        return null;
     }
 
     /**
@@ -3060,7 +3069,12 @@
                 // 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()))
+                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())));
@@ -3121,7 +3135,7 @@
         FelixBundle[] bundles = acquireBundleRefreshLocks(targets);
 
         boolean restart = false;
-        
+
         Bundle systemBundle = getBundle(0);
 
         // We need to restart the framework if either an extension bundle is

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4SearchPolicyCore.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4SearchPolicyCore.java?rev=576161&r1=576160&r2=576161&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4SearchPolicyCore.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4SearchPolicyCore.java Sun Sep 16 12:53:22 2007
@@ -780,6 +780,7 @@
             {
                 String pkgName = ((Requirement) req).getPackageName();
                 IModule[] modules = (IModule[]) m_inUsePkgIndexMap.get(pkgName);
+
                 for (int modIdx = 0; (modules != null) && (modIdx < modules.length); modIdx++)
                 {
                     ICapability inUseCap = Util.getSatisfyingCapability(modules[modIdx], req);
@@ -2456,6 +2457,64 @@
         }
     }
 
+    /**
+     * This is an experimental method that is likely to change or go
+     * away - so don't use it for now.
+     *
+     * Note to self, we need to think about what the implications of
+     * this are and whether we are fine with them.
+     */
+    /*
+     * This method is used by the framework to let us know that we need to re-read
+     * the system bundle capabilities which have been extended by an extension bundle.
+     *
+     * For now we assume that capabilities have been added only. We might need to
+     * enforce that at one point of time.
+     */
+    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 available package map.
+            for (int i = 0; (caps != null) && (i < caps.length); i++)
+            {
+                if (caps[i].getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
+                {
+                    indexPackageCapability(m_availPkgIndexMap, module, caps[i]);
+                }
+
+
+                ICapability[] inUseCaps = (ICapability[]) m_inUseCapMap.get(module);
+                inUseCaps = addCapabilityToArray(inUseCaps, caps[i]);
+                m_inUseCapMap.put(module, inUseCaps);
+
+                // If the capability is a package, then add the exporter module
+                // of the wire to the "in use" package index and remove it
+                // from the "available" 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 "in use" package index.
+                    indexPackageCapability(
+                        m_inUsePkgIndexMap,
+                        module,
+                        caps[i]);
+                    // Remove from "available" package index.
+                    m_availPkgIndexMap.put(
+                        pkgName,
+                        removeModuleFromArray(
+                            (IModule[]) m_availPkgIndexMap.get(pkgName),
+                            module));
+                }
+            }
+        }
+    }
+
     private void indexPackageCapability(Map map, IModule module, ICapability capability)
     {
         if (capability.getNamespace().equals(ICapability.PACKAGE_NAMESPACE))
@@ -2579,35 +2638,39 @@
         }
 
         int idx = -1;
-        for (int i = 0; i < modules.length; i++)
+        do
         {
-            if (modules[i] == m)
+            idx = -1;
+            for (int i = 0; i < modules.length; i++)
             {
-                idx = i;
-                break;
+                if (modules[i] == m)
+                {
+                    idx = i;
+                    break;
+                }
             }
-        }
 
-        if (idx >= 0)
-        {
-            // If this is the module, then point to empty list.
-            if ((modules.length - 1) == 0)
-            {
-                modules = m_emptyModules;
-            }
-            // Otherwise, we need to do some array copying.
-            else
+            if (idx >= 0)
             {
-                IModule[] newModules = new IModule[modules.length - 1];
-                System.arraycopy(modules, 0, newModules, 0, idx);
-                if (idx < newModules.length)
+                // If this is the module, then point to empty list.
+                if ((modules.length - 1) == 0)
                 {
-                    System.arraycopy(
-                        modules, idx + 1, newModules, idx, newModules.length - idx);
+                    modules = m_emptyModules;
+                }
+                // Otherwise, we need to do some array copying.
+                else
+                {
+                    IModule[] newModules = new IModule[modules.length - 1];
+                    System.arraycopy(modules, 0, newModules, 0, idx);
+                    if (idx < newModules.length)
+                    {
+                        System.arraycopy(
+                            modules, idx + 1, newModules, idx, newModules.length - idx);
+                    }
+                    modules = newModules;
                 }
-                modules = newModules;
             }
-        }
+        } while (idx >= 0);
         return modules;
     }