Bug in Bundle.getEntry
----------------------

                 Key: FELIX-149
                 URL: http://issues.apache.org/jira/browse/FELIX-149
             Project: Felix
          Issue Type: Bug
          Components: Framework
            Reporter: Olivier Gruber
            Priority: Minor


I think I found a bug in the implementation of URL Bundle.getEntry(String 
name); 
It raises a ClassCastException when called on the system bundle since its 
content loader 
is not a ContentLoaderImpl but actually a SystemBundleContentLoader. :-( 

class BundleImpl         
    public URL getEntry(String name) 
    { 
        Object sm = System.getSecurityManager(); 

        if (sm != null) 
        { 
            try 
            { 
                ((SecurityManager) sm).checkPermission(new 
AdminPermission(this, 
                    AdminPermission.RESOURCE)); 
            } 
            catch (Exception e) 
            { 
                return null; // No permission 
            } 
        } 

        return m_felix.getBundleEntry(this, name); 
    } 

class Felix 
    /** 
     * Implementation for Bundle.getEntry(). 
    **/ 
    protected URL getBundleEntry(BundleImpl bundle, String name) 
    { 
        if (bundle.getInfo().getState() == Bundle.UNINSTALLED) 
        { 
            throw new IllegalStateException("The bundle is uninstalled."); 
        } 
==>>        return ((ContentLoaderImpl) bundle.getInfo().getCurrentModule() 
            .getContentLoader()).getResourceFromContent(name); 
    } 

Here is a patch for this problem. 
It is basically moving the getResourceFromContent from ContentLoaderImpl to 
Felix, 
which required to modify the FindEntriesEnumeration slightly. 

Index: org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java
===================================================================
--- org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java      
(revision 440763)
+++ org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java      
(working copy)
@@ -174,39 +174,6 @@
         return v.elements();
     }
 
-    // TODO: API: Investigate making this an API call.
-    public URL getResourceFromContent(String name)
-    {
-        URL url = null;
-
-        // Check for the special case of "/", which represents
-        // the root of the bundle according to the spec.
-        if (name.equals("/"))
-        {
-            url = getURLPolicy().createURL("0/");
-        }
-
-        if (url == null)
-        {
-            // Remove leading slash, if present.
-            if (name.startsWith("/"))
-            {
-                name = name.substring(1);
-            }
-
-            // Check the module content.
-            if (getContent().hasEntry(name))
-            {
-                // Module content URLs start with 0, whereas module
-                // class path URLs start with the index into the class
-                // path + 1.
-                url = getURLPolicy().createURL("0/" + name);
-            }
-        }
-
-        return url;
-    }
-
     public boolean hasInputStream(String urlPath)
     {
         if (urlPath.startsWith("/"))
Index: org/apache/felix/framework/Felix.java
===================================================================
--- org/apache/felix/framework/Felix.java       (revision 440763)
+++ org/apache/felix/framework/Felix.java       (working copy)
@@ -1001,10 +1001,47 @@
         {
             throw new IllegalStateException("The bundle is uninstalled.");
         }
-        return ((ContentLoaderImpl) bundle.getInfo().getCurrentModule()
-            .getContentLoader()).getResourceFromContent(name);
+        IContentLoader loader;
+        loader = bundle.getInfo().getCurrentModule().getContentLoader();
+        return getResourceFromContent(loader,name);
+        //return ((ContentLoaderImpl) bundle.getInfo().getCurrentModule()
+        //    .getContentLoader()).getResourceFromContent(name);
     }
 
+    // TODO: API: Investigate making this an API call.
+    private URL getResourceFromContent(IContentLoader loader, String name)
+    {
+        URL url = null;
+
+        // Check for the special case of "/", which represents
+        // the root of the bundle according to the spec.
+        if (name.equals("/"))
+        {
+            url = loader.getURLPolicy().createURL("0/");
+        }
+
+        if (url == null)
+        {
+            // Remove leading slash, if present.
+            if (name.startsWith("/"))
+            {
+                name = name.substring(1);
+            }
+
+            // Check the module content.
+            IContent content = loader.getContent();
+            if (content!=null && content.hasEntry(name))
+            {
+                // Module content URLs start with 0, whereas module
+                // class path URLs start with the index into the class
+                // path + 1.
+                url = loader.getURLPolicy().createURL("0/" + name);
+            }
+        }
+
+        return url;
+    }
+
     /**
      * Implementation for Bundle.getEntryPaths().
     **/
@@ -1034,8 +1071,8 @@
 
         // Get the entry enumeration from the module content and
         // create a wrapper enumeration to filter it.
-        Enumeration enumeration =
-            new FindEntriesEnumeration(bundle, path, filePattern, recurse);
+        Enumeration enumeration = 
+            new FindEntriesEnumeration(this,bundle, path, filePattern, 
recurse);
 
         // Return the enumeration if it has elements.
         return (!enumeration.hasMoreElements()) ? null : enumeration;
Index: org/apache/felix/framework/FindEntriesEnumeration.java
===================================================================
--- org/apache/felix/framework/FindEntriesEnumeration.java      (revision 
440763)
+++ org/apache/felix/framework/FindEntriesEnumeration.java      (working copy)
@@ -22,6 +22,7 @@
 
 class FindEntriesEnumeration implements Enumeration
 {
+       private Felix m_felix;
     private BundleImpl m_bundle = null;
     private Enumeration m_enumeration = null;
     private String m_path = null;
@@ -29,9 +30,10 @@
     private boolean m_recurse = false;
     private Object m_next = null;
 
-    public FindEntriesEnumeration(
+    public FindEntriesEnumeration(Felix felix,
         BundleImpl bundle, String path, String filePattern, boolean recurse)
     {
+       m_felix = felix;
         m_bundle = bundle;
         m_path = path;
         m_enumeration = m_bundle.getInfo().getCurrentModule()
@@ -49,7 +51,7 @@
             m_path = m_path.substring(1);
         }
         // Add a '/' to the end if not present.
-        if ((m_path.length() > 0) && (m_path.charAt(path.length() - 1) != '/'))
+        if ((m_path.length() > 0) && (m_path.charAt(m_path.length() - 1) != 
'/'))
         {
             m_path = m_path + "/";
         }
@@ -116,10 +118,12 @@
                     // See if the file pattern matches the last element of the 
path.
                     if (checkSubstring(m_filePattern, lastElement))
                     {
+                       return m_felix.getBundleEntry(m_bundle,entryName);
+                       
                         // Convert entry name into an entry URL.
-                        return ((ContentLoaderImpl) m_bundle.getInfo()
-                            .getCurrentModule().getContentLoader())
-                                .getResourceFromContent(entryName);
+                        //return ((ContentLoaderImpl) m_bundle.getInfo()
+                        //    .getCurrentModule().getContentLoader())
+                        //        .getResourceFromContent(entryName);
                     }
                 }
             }


-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to