Implemented Bundle.getEntry() for accessing the raw bundle JAR file; this
uses non-API methods from the Module Loader layer so it will need to be
tweaked in the future, but it appears to work for now.


git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@375026 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/BundleImpl.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/BundleImpl.java
index 48e8a75..cc05008 100644
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/BundleImpl.java
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/BundleImpl.java
@@ -55,6 +55,11 @@
         return m_info.getBundleId();
     }
 
+    public URL getEntry(String name)
+    {
+        return m_felix.getBundleEntry(this, name);
+    }
+
     public Dictionary getHeaders()
     {
         return m_felix.getBundleHeaders(this);
@@ -169,12 +174,6 @@
         return null;
     }
 
-    public URL getEntry(String name)
-    {
-        // TODO: Implement Bundle.getEntry()
-        return null;
-    }
-
     public Enumeration findEntries(String path, String filePattern, boolean recurse)
     {
         // TODO: Implement Bundle.findEntries()
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/Felix.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/Felix.java
index ce789ff..f946fbf 100644
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -966,6 +966,24 @@
         return bundle.getInfo().getCurrentModule().getResource(name);
     }
 
+    /**
+     * Implementation for Bundle.getEntry().
+    **/
+    protected URL getBundleEntry(BundleImpl bundle, String name)
+    {
+        if (bundle.getInfo().getState() == Bundle.UNINSTALLED)
+        {
+            throw new IllegalStateException("The bundle is uninstalled.");
+        }
+// TODO: SECURITY - Implement correct check.
+        else if (System.getSecurityManager() != null)
+        {
+            AccessController.checkPermission(m_adminPerm);
+        }
+        return ((ContentLoaderImpl) bundle.getInfo().getCurrentModule()
+            .getContentLoader()).getResourceFromContent(name);
+    }
+
     protected ServiceReference[] getBundleRegisteredServices(BundleImpl bundle)
     {
         if (bundle.getInfo().getState() == Bundle.UNINSTALLED)
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentClassLoader.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentClassLoader.java
index 8c73300..5486312 100644
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentClassLoader.java
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentClassLoader.java
@@ -21,7 +21,6 @@
 import java.security.SecureClassLoader;
 import java.security.cert.Certificate;
 import java.util.Enumeration;
-import java.util.Vector;
 
 import org.apache.felix.framework.Logger;
 import org.apache.felix.framework.util.Util;
@@ -198,48 +197,12 @@
 
     protected URL findResource(String name)
     {
-        URL url = null;
-
-        // Remove leading slash, if present.
-        if (name.startsWith("/"))
-        {
-            name = name.substring(1);
-        }
-
-        // Check the module class path.
-        for (int i = 0;
-            (url == null) &&
-            (i < m_contentLoader.getClassPath().length); i++)
-        {
-            if (m_contentLoader.getClassPath()[i].hasEntry(name))
-            {
-                url = m_contentLoader.getURLPolicy().createURL(i + "/" + name);
-            }
-        }
-
-        return url;
+        return m_contentLoader.getResource(name);
     }
 
     protected Enumeration findResources(String name)
     {
-        Vector v = new Vector();
-
-        // Remove leading slash, if present.
-        if (name.startsWith("/"))
-        {
-            name = name.substring(1);
-        }
-
-        // Check the module class path.
-        for (int i = 0; i < m_contentLoader.getClassPath().length; i++)
-        {
-            if (m_contentLoader.getClassPath()[i].hasEntry(name))
-            {
-                v.addElement(m_contentLoader.getURLPolicy().createURL(i + "/" + name));
-            }
-        }
-
-        return v.elements();
+        return m_contentLoader.getResources(name);
     }
 
     protected String findLibrary(String name)
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java
index 2abd263..a81e278 100644
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java
@@ -19,6 +19,8 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
+import java.util.Enumeration;
+import java.util.Vector;
 
 import org.apache.felix.framework.Logger;
 import org.apache.felix.moduleloader.*;
@@ -111,12 +113,74 @@
 
     public URL getResource(String name)
     {
-        if (m_classLoader == null)
+        URL url = null;
+        // Remove leading slash, if present.
+        if (name.startsWith("/"))
         {
-            m_classLoader = new ContentClassLoader(this);
+            name = name.substring(1);
         }
 
-        return m_classLoader.getResourceFromModule(name);
+        // Check the module class path.
+        for (int i = 0;
+            (url == null) &&
+            (i < getClassPath().length); i++)
+        {
+            if (getClassPath()[i].hasEntry(name))
+            {
+                url = getURLPolicy().createURL((i + 1) + "/" + name);
+            }
+        }
+
+        return url;
+    }
+
+    protected Enumeration getResources(String name)
+    {
+        Vector v = new Vector();
+
+        // Remove leading slash, if present.
+        if (name.startsWith("/"))
+        {
+            name = name.substring(1);
+        }
+
+        // Check the module class path.
+        for (int i = 0; i < getClassPath().length; i++)
+        {
+            if (getClassPath()[i].hasEntry(name))
+            {
+                // Use the class path index + 1 for creating the path so
+                // that we can differentiate between module content URLs
+                // (where the path will start with 0) and module class
+                // path URLs.
+                v.addElement(getURLPolicy().createURL((i + 1) + "/" + name));
+            }
+        }
+
+        return v.elements();
+    }
+
+    // TODO: API: Investigate making this an API call.
+    public URL getResourceFromContent(String name)
+    {
+        URL 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 InputStream getResourceAsStream(String name)
@@ -127,10 +191,17 @@
             name = name.substring(1);
         }
         // The name is the path contructed like this:
-        // <class-path-index> / <relative-resource-path>
+        // <index> / <relative-resource-path>
+        // where <index> == 0 is the module content
+        // and <index> > 0 is the index into the class
+        // path - 1.
         int idx = Integer.parseInt(name.substring(0, name.indexOf('/')));
         name = name.substring(name.indexOf('/') + 1);
-        return m_contentPath[idx].getEntryAsStream(name);
+        if (idx == 0)
+        {
+            return m_content.getEntryAsStream(name);
+        }
+        return m_contentPath[idx - 1].getEntryAsStream(name);
     }
 
     public String toString()