Modified bundle URL resource handling to remove the bundle class path index
from the resource path to the URL port number. This is a quick and dirty
hack that needs to be revisited, perhaps after spec clarification.


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@544515 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/SystemBundle.java b/framework/src/main/java/org/apache/felix/framework/SystemBundle.java
index c7a32c6..529022a 100644
--- a/framework/src/main/java/org/apache/felix/framework/SystemBundle.java
+++ b/framework/src/main/java/org/apache/felix/framework/SystemBundle.java
@@ -492,12 +492,12 @@
             return null;
         }
 
-        public boolean hasInputStream(String urlPath) throws IOException
+        public boolean hasInputStream(int index, String urlPath) throws IOException
         {
             return (getClass().getClassLoader().getResource(urlPath) != null);
         }
 
-        public InputStream getInputStream(String urlPath) throws IOException
+        public InputStream getInputStream(int index, String urlPath) throws IOException
         {
             return getClass().getClassLoader().getResourceAsStream(urlPath);
         }
diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
index dea7ff1..4bb813a 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
@@ -55,7 +55,7 @@
         }
         // Verify that the resource pointed to be the URL exists.
         // The URL is constructed like this:
-        //     bundle://<module-id>/<resource-path>
+        //     bundle://<module-id>:<bundle-classpath-index>/<resource-path>
         // Where <module-id> = <bundle-id>.<revision>
         long bundleId = Util.getBundleIdFromModuleId(url.getHost());
         BundleImpl bundle = (BundleImpl) m_framework.getBundle(bundleId);
@@ -66,7 +66,7 @@
         int revision = Util.getModuleRevisionFromModuleId(url.getHost());
         IModule[] modules = bundle.getInfo().getModules();
         if ((modules == null) || (revision < 0) || (revision >= modules.length) ||
-            !modules[revision].getContentLoader().hasInputStream(url.getPath()))
+            !modules[revision].getContentLoader().hasInputStream(url.getPort(), url.getPath()))
         {
             throw new IOException("Resource does not exist: " + url);
         }
@@ -77,7 +77,7 @@
         if (!connected)
         {
             // The URL is constructed like this:
-            //     bundle://<module-id>/<resource-path>
+        //     bundle://<module-id>:<module-classpath-index>/<resource-path>
             // Where <module-id> = <bundle-id>.<revision>
             long bundleId = Util.getBundleIdFromModuleId(url.getHost());
             BundleImpl bundle = (BundleImpl) m_framework.getBundle(bundleId);
@@ -91,7 +91,8 @@
             {
                 throw new IOException("Resource does not exist: " + url);
             }
-            m_is = bundle.getInfo().getModules()[revision].getContentLoader().getInputStream(url.getPath());
+            m_is = bundle.getInfo().getModules()[revision]
+                .getContentLoader().getInputStream(url.getPort(), url.getPath());
             m_contentLength = (m_is == null) ? 0 : m_is.available();
             m_contentTime = 0L;
             m_contentType = URLConnection.guessContentTypeFromName(url.getFile());
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java b/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java
index 53e9a87..667d733 100644
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java
@@ -143,7 +143,7 @@
         {
             if (getClassPath()[i].hasEntry(name))
             {
-                url = getURLPolicy().createURL((i + 1) + "/" + name);
+                url = getURLPolicy().createURL(i + 1, name);
             }
         }
 
@@ -169,7 +169,7 @@
                 // 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));
+                v.addElement(getURLPolicy().createURL(i + 1, name));
             }
         }
 
@@ -186,7 +186,7 @@
         // the root of the bundle according to the spec.
         if (name.equals("/"))
         {
-            url = getURLPolicy().createURL("0/");
+            url = getURLPolicy().createURL(0, "/");
         }
 
         if (url == null)
@@ -203,54 +203,38 @@
                 // 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);
+                url = getURLPolicy().createURL(0, name);
             }
         }
 
         return url;
     }
 
-    public boolean hasInputStream(String urlPath)
+    public boolean hasInputStream(int index, String urlPath)
     {
         if (urlPath.startsWith("/"))
         {
             urlPath = urlPath.substring(1);
         }
-        // The urlPath is the path portion of a resource URL
-        // that is contructed above in getResouce() like this:
-        // <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(urlPath.substring(0, urlPath.indexOf('/')));
-        urlPath = urlPath.substring(urlPath.indexOf('/') + 1);
-        if (idx == 0)
+        if (index == 0)
         {
             return m_content.hasEntry(urlPath);
         }
-        return m_contentPath[idx - 1].hasEntry(urlPath);
+        return m_contentPath[index - 1].hasEntry(urlPath);
     }
 
-    public InputStream getInputStream(String urlPath)
+    public InputStream getInputStream(int index, String urlPath)
         throws IOException
     {
         if (urlPath.startsWith("/"))
         {
             urlPath = urlPath.substring(1);
         }
-        // The urlPath is the path portion of a resource URL
-        // that is contructed above in getResouce() like this:
-        // <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(urlPath.substring(0, urlPath.indexOf('/')));
-        urlPath = urlPath.substring(urlPath.indexOf('/') + 1);
-        if (idx == 0)
+        if (index == 0)
         {
             return m_content.getEntryAsStream(urlPath);
         }
-        return m_contentPath[idx - 1].getEntryAsStream(urlPath);
+        return m_contentPath[index - 1].getEntryAsStream(urlPath);
     }
 
     public String toString()
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/URLPolicyImpl.java b/framework/src/main/java/org/apache/felix/framework/searchpolicy/URLPolicyImpl.java
index 2de2b3c..dcd9560 100644
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/URLPolicyImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/searchpolicy/URLPolicyImpl.java
@@ -41,7 +41,7 @@
         m_module = module;
     }
 
-    public URL createURL(String path)
+    public URL createURL(int port, String path)
     {
          // Add a slash if there is one already, otherwise
          // the is no slash separating the host from the file
@@ -55,7 +55,7 @@
          {
              return m_secureAction.createURL(
                  FelixConstants.BUNDLE_URL_PROTOCOL,
-                 m_module.getId(), -1, path, m_streamHandler);
+                 m_module.getId(), port, path, m_streamHandler);
          }
          catch (MalformedURLException ex)
          {
diff --git a/framework/src/main/java/org/apache/felix/moduleloader/IContentLoader.java b/framework/src/main/java/org/apache/felix/moduleloader/IContentLoader.java
index 20f8553..8a01119 100644
--- a/framework/src/main/java/org/apache/felix/moduleloader/IContentLoader.java
+++ b/framework/src/main/java/org/apache/felix/moduleloader/IContentLoader.java
@@ -41,8 +41,16 @@
     public Enumeration getResources(String name);
     public URL getResourceFromContent(String name);
 
-    public boolean hasInputStream(String urlPath)
+    // TODO: ML - For expediency, the index argument was added to these methods
+    // but it is not clear that this makes sense in the long run. This needs to
+    // be readdressed in the future, perhaps by the spec to clearly indicate
+    // how resources on the bundle class path are searched, which is why we
+    // need the index number in the first place -- to differentiate among
+    // resources with the same name on the bundle class path. This was previously
+    // handled as part of the resource path, but that approach is not spec
+    // compliant.
+    public boolean hasInputStream(int index, String urlPath)
         throws IOException;
-    public InputStream getInputStream(String urlPath)
+    public InputStream getInputStream(int index, String urlPath)
         throws IOException;
 }
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/moduleloader/IURLPolicy.java b/framework/src/main/java/org/apache/felix/moduleloader/IURLPolicy.java
index 37e9d28..addcb55 100644
--- a/framework/src/main/java/org/apache/felix/moduleloader/IURLPolicy.java
+++ b/framework/src/main/java/org/apache/felix/moduleloader/IURLPolicy.java
@@ -22,5 +22,13 @@
 
 public interface IURLPolicy
 {
-    public URL createURL(String path);
+    // TODO: ML - For expediency, the port argument was added to this method
+    // but it is not clear that it makes sense in the long run. This needs to
+    // be readdressed in the future, perhaps by the spec to clearly indicate
+    // how resources on the bundle class path are searched, which is why we
+    // need the port number in the first place -- to differentiate among
+    // resources with the same name on the bundle class path. This was previously
+    // handled as part of the resource path, but that approach is not spec
+    // compliant.
+    public URL createURL(int port, String path);
 }
\ No newline at end of file