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/01/25 17:22:48 UTC

svn commit: r615256 - in /felix/trunk/framework/src/main/java/org/apache/felix/framework: searchpolicy/ContentClassLoader.java searchpolicy/R4SearchPolicyCore.java searchpolicy/R4WireModule.java util/CompoundEnumeration.java

Author: rickhall
Date: Fri Jan 25 08:22:48 2008
New Revision: 615256

URL: http://svn.apache.org/viewvc?rev=615256&view=rev
Log:
Applied patches (FELIX-466 and FELIX-467) to improve how Felix finds resources
when getResources() is called.

Added:
    felix/trunk/framework/src/main/java/org/apache/felix/framework/util/CompoundEnumeration.java   (with props)
Modified:
    felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentClassLoader.java
    felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4SearchPolicyCore.java
    felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4WireModule.java

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentClassLoader.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentClassLoader.java?rev=615256&r1=615255&r2=615256&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentClassLoader.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentClassLoader.java Fri Jan 25 08:22:48 2008
@@ -1,4 +1,4 @@
-/* 
+/*
  * 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
@@ -46,7 +46,7 @@
             Class dexFileClass =  Class.forName("android.dalvik.DexFile");
             dexFileClassConstructor = dexFileClass.getConstructor(
                 new Class[] { java.io.File.class });
-            dexFileClassLoadClass = dexFileClass.getMethod("loadClass", 
+            dexFileClassLoadClass = dexFileClass.getMethod("loadClass",
                 new Class[] { String.class, ClassLoader.class });
         }
         catch (Exception ex)
@@ -99,7 +99,7 @@
 
         // Make sure the class was not already loaded.
         synchronized (this)
-        {    
+        {
             clazz = findLoadedClass(name);
         }
 
@@ -138,7 +138,7 @@
             String actual = name.replace('.', '/') + ".class";
 
             byte[] bytes = null;
-            
+
             IContent content = null;
             // Check the module class path.
             for (int i = 0;
@@ -194,7 +194,7 @@
                         // If we can load the class from a dex file do so
                         if (content instanceof JarContent)
                         {
-                            try 
+                            try
                             {
                                 clazz = getDexFileClass((JarContent) content, name, this);
                             }
@@ -237,7 +237,7 @@
 
         Object dexFile = null;
 
-        if (!m_jarContentToDexFile.containsKey(content)) 
+        if (!m_jarContentToDexFile.containsKey(content))
         {
             try
             {
@@ -253,10 +253,10 @@
         {
             dexFile = m_jarContentToDexFile.get(content);
         }
-        
+
         if (dexFile != null)
         {
-            return (Class) m_dexFileClassLoadClass.invoke(dexFile, 
+            return (Class) m_dexFileClassLoadClass.invoke(dexFile,
                 new Object[] { name.replace('.','/'), loader });
         }
         return null;
@@ -290,12 +290,28 @@
 
     protected URL findResource(String name)
     {
-        return m_contentLoader.getResource(name);
+        // Ask the search policy for the resource.
+        try
+        {
+            return m_contentLoader.getSearchPolicy().findResource(name);
+        }
+        catch (ResourceNotFoundException ex)
+        {
+        }
+        return null;
     }
 
     protected Enumeration findResources(String name)
     {
-        return m_contentLoader.getResources(name);
+        // Ask the search policy for the resources.
+        try
+        {
+            return m_contentLoader.getSearchPolicy().findResources(name);
+        }
+        catch (ResourceNotFoundException ex)
+        {
+        }
+        return null;
     }
 
     protected String findLibrary(String name)
@@ -307,4 +323,4 @@
     {
         return m_contentLoader.toString();
     }
-}
+}
\ No newline at end of file

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=615256&r1=615255&r2=615256&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 Fri Jan 25 08:22:48 2008
@@ -32,6 +32,7 @@
 import java.util.StringTokenizer;
 
 import org.apache.felix.framework.Logger;
+import org.apache.felix.framework.util.CompoundEnumeration;
 import org.apache.felix.framework.util.SecurityManagerEx;
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.util.manifestparser.Capability;
@@ -222,6 +223,8 @@
         throws ResourceNotFoundException
     {
         Enumeration urls = null;
+        List enums = new ArrayList();
+
         // First, try to resolve the originating module.
 // TODO: FRAMEWORK - Consider opimizing this call to resolve, since it is called
 // for each class load.
@@ -278,21 +281,20 @@
                         // is nothing we can do, so just ignore it.
                     }
                     // If this is a java.* package, then always terminate the
-                    // search; otherwise, continue to look locally if not found.
-                    if (m_bootPkgs[i].startsWith("java.") || (urls != null))
+                    // search; otherwise, continue to look locally.
+                    if (m_bootPkgs[i].startsWith("java."))
                     {
                         return urls;
                     }
-                    else
-                    {
-                        break;
-                    }
+
+                    enums.add(urls);
+                    break;
                 }
             }
         }
 
         // Look in the module's imports.
-        // We delegate to the module's wires to the resources.
+        // We delegate to the module's wires for the resources.
         // If any resources are found, this means that the package of these
         // resources is imported, we must not keep looking since we do not
         // support split-packages.
@@ -302,37 +304,63 @@
         IWire[] wires = module.getWires();
         for (int i = 0; (wires != null) && (i < wires.length); i++)
         {
-            // If we find the class or resource, then return it.
-            urls = wires[i].getResources(name);
-            if (urls != null)
+            if (wires[i] instanceof R4Wire)
             {
-                return urls;
+                // If we find the class or resource, then return it.
+                urls = wires[i].getResources(name);
+                if (urls != null)
+                {
+                    enums.add(urls);
+                    return new CompoundEnumeration((Enumeration[])
+                        enums.toArray(new Enumeration[enums.size()]));
+                }
             }
         }
 
-        // If not found, try the module's own class path.
-        urls = module.getContentLoader().getResources(name);
-        if (urls != null)
+        // See whether we can get the resource from the required bundles and
+        // regardless of whether or not this is the case continue to the next
+        // step potentially passing on the result of this search (if any).
+        for (int i = 0; (wires != null) && (i < wires.length); i++)
         {
-            return urls;
+            if (wires[i] instanceof R4WireModule)
+            {
+                // If we find the class or resource, then add it.
+                urls = wires[i].getResources(name);
+                if (urls != null)
+                {
+                    enums.add(urls);
+                }
+            }
         }
 
-        // If still not found, then try the module's dynamic imports.
-        // At this point, the module's imports were searched and so was the
-        // the module's content. Now we make an attempt to load the
-        // class/resource via a dynamic import, if possible.
-        IWire wire = attemptDynamicImport(module, pkgName);
-        if (wire != null)
+        // Try the module's own class path. If we can find the resource then
+        // return it together with the results from the other searches else
+        // try to look into the dynamic imports.
+        urls = module.getContentLoader().getResources(name);
+        if (urls != null)
         {
-            urls = wire.getResources(name);
+            enums.add(urls);
         }
-
-        if (urls == null)
+        else
         {
-            throw new ResourceNotFoundException(name);
+            // If not found, then try the module's dynamic imports.
+            // At this point, the module's imports were searched and so was the
+            // the module's content. Now we make an attempt to load the
+            // class/resource via a dynamic import, if possible.
+            IWire wire = attemptDynamicImport(module, pkgName);
+            if (wire != null)
+            {
+                urls = wire.getResources(name);
+
+                if (urls != null)
+                {
+                    enums.add(urls);
+                }
+            }
         }
 
-        return urls;
+        return new CompoundEnumeration((Enumeration[])
+            enums.toArray(new Enumeration[enums.size()]));
     }
 
     private Object findClassOrResource(IModule module, String name, boolean isClass)

Modified: felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4WireModule.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4WireModule.java?rev=615256&r1=615255&r2=615256&view=diff
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4WireModule.java (original)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4WireModule.java Fri Jan 25 08:22:48 2008
@@ -23,6 +23,7 @@
 
 import org.apache.felix.framework.searchpolicy.R4SearchPolicyCore.ResolvedPackage;
 import org.apache.felix.framework.searchpolicy.R4SearchPolicyCore.PackageSource;
+import org.apache.felix.framework.util.CompoundEnumeration;
 import org.apache.felix.framework.util.Util;
 import org.apache.felix.framework.util.manifestparser.Capability;
 import org.apache.felix.moduleloader.*;
@@ -127,6 +128,9 @@
                     return url;
                 }
             }
+
+            // Don't throw ResourceNotFoundException because module
+            // dependencies support split packages.
         }
 
         return null;
@@ -137,8 +141,37 @@
      */
     public Enumeration getResources(String name) throws ResourceNotFoundException
     {
-// TODO: RB - Implement R4WireModule.getResources()
-        return null;
+        // List to hold all enumerations from all package sources.
+        List enums = new ArrayList();
+
+        // Get the package of the target class.
+        String pkgName = Util.getResourcePackage(name);
+
+        // See if we have a resolved package for the resource's package.
+        // If so, loop through all package sources and aggregate any
+        // matching resource enumerations.
+        ResolvedPackage rp = (ResolvedPackage) m_pkgMap.get(pkgName);
+        if (rp != null)
+        {
+            for (int srcIdx = 0; srcIdx < rp.m_sourceList.size(); srcIdx++)
+            {
+                PackageSource ps = (PackageSource) rp.m_sourceList.get(srcIdx);
+                Enumeration urls = ps.m_module.getContentLoader().getResources(name);
+                if (urls != null)
+                {
+                    enums.add(urls);
+                }
+            }
+
+            // Don't throw ResourceNotFoundException because module
+            // dependencies support split packages.
+        }
+
+        return (enums.size() == 0)
+            ? null
+            : new CompoundEnumeration(
+                (Enumeration[]) enums.toArray(new Enumeration[enums.size()]));
+
     }
 
     public String toString()

Added: felix/trunk/framework/src/main/java/org/apache/felix/framework/util/CompoundEnumeration.java
URL: http://svn.apache.org/viewvc/felix/trunk/framework/src/main/java/org/apache/felix/framework/util/CompoundEnumeration.java?rev=615256&view=auto
==============================================================================
--- felix/trunk/framework/src/main/java/org/apache/felix/framework/util/CompoundEnumeration.java (added)
+++ felix/trunk/framework/src/main/java/org/apache/felix/framework/util/CompoundEnumeration.java Fri Jan 25 08:22:48 2008
@@ -0,0 +1,91 @@
+package org.apache.felix.framework.util;
+
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+public class CompoundEnumeration implements Enumeration
+{
+    private Enumeration[] m_enums = null;
+    private int index = 0;
+
+    public CompoundEnumeration(Enumeration[] enums)
+    {
+        m_enums = enums;
+    }
+
+    public boolean hasMoreElements()
+    {
+        // if the current enum is null that means this enum is finished
+        if (currentEnumeration() == null)
+        {
+            // No next enum
+            return false;
+        }
+        // If the current enum has more elements, lets go
+        return currentEnumeration().hasMoreElements();
+    }
+
+    private Enumeration findNextEnumeration(boolean moveCursor)
+    {
+        return findNextEnumeration(index, moveCursor);
+    }
+
+    private Enumeration findNextEnumeration(int cursor, boolean moveCursor)
+    {
+        // next place in the array
+        int next = cursor + 1;
+        // If the cursor is still in the array
+        if (next < m_enums.length)
+        {
+
+            // If there is something in that place
+            // AND the enum is not empty
+            if (m_enums[next] != null &&
+                m_enums[next].hasMoreElements())
+            {
+                // OK
+                if (moveCursor)
+                {
+                    index = next;
+                }
+                return m_enums[next];
+            }
+            // Try next element
+            return findNextEnumeration(next, moveCursor);
+        }
+        // No more elements available
+        return null;
+    }
+
+    public Object nextElement()
+    {
+        // ask for the next element of the current enum.
+        if (currentEnumeration() != null)
+        {
+            return currentEnumeration().nextElement();
+        }
+
+        // no more elements in this Enum
+        // We must throw a NoSuchElementException
+        throw new NoSuchElementException("No more elements");
+    }
+
+    private Enumeration currentEnumeration()
+    {
+        if (m_enums != null)
+        {
+            if (index < m_enums.length)
+            {
+                Enumeration e = m_enums[index];
+                if (e == null || !e.hasMoreElements())
+                {
+                    // the current enum is null or empty
+                    // we probably want to switch to the next one
+                    e = findNextEnumeration(true);
+                }
+                return e;
+            }
+        }
+        return null;
+    }
+}
\ No newline at end of file

Propchange: felix/trunk/framework/src/main/java/org/apache/felix/framework/util/CompoundEnumeration.java
------------------------------------------------------------------------------
    svn:eol-style = native