Modifies bundle resource URL handling such that if a resource URL points
to a resource that does not exist, a bundle class path search for the
resource will be instigated and if any matching resource is found, that
one will be used instead. This partially addresses (FELIX-383), which is
concerned with constructing resource URLs from other resource URLs.


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@585150 13f79535-47bb-0310-9956-ffa450edef68
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 ec5a30a..69a3d7e 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
@@ -30,6 +30,8 @@
 class URLHandlersBundleURLConnection extends URLConnection
 {
     private Felix m_framework;
+    private IModule m_targetModule;
+    private int m_classPathIdx = -1;
     private int m_contentLength;
     private long m_contentTime;
     private String m_contentType;
@@ -65,34 +67,41 @@
         }
         int revision = Util.getModuleRevisionFromModuleId(url.getHost());
         IModule[] modules = bundle.getInfo().getModules();
-        if ((modules == null) || (revision < 0) || (revision >= modules.length) ||
-            !modules[revision].getContentLoader().hasInputStream(url.getPort(), url.getPath()))
+        if ((modules == null) || (revision < 0) || (revision >= modules.length))
         {
             throw new IOException("Resource does not exist: " + url);
         }
+
+        // If the resource cannot be found at the current class path index,
+        // then search them all in order to see if it can be found. This is
+        // necessary since the user might create a resource URL from another
+        // resource URL and not realize they have the wrong class path entry.
+        // Of course, this approach won't work in cases where there are multiple
+        // resources with the same path, since it will always find the first
+        // one on the class path.
+        m_targetModule = modules[revision];
+        m_classPathIdx = url.getPort();
+        if (!modules[revision].getContentLoader().hasInputStream(m_classPathIdx, url.getPath()))
+        {
+            URL newurl = modules[revision].getContentLoader().getResource(url.getPath());
+            if (newurl == null)
+            {
+                throw new IOException("Resource does not exist: " + url);
+            }
+            m_classPathIdx = newurl.getPort();
+        }
     }
 
     public void connect() throws IOException
     {
         if (!connected)
         {
-            // The URL is constructed like this:
-        //     bundle://<module-id>:<module-classpath-index>/<resource-path>
-            // Where <module-id> = <bundle-id>.<revision>
-            long bundleId = Util.getBundleIdFromModuleId(url.getHost());
-            FelixBundle bundle = (FelixBundle) m_framework.getBundle(bundleId);
-            if (bundle == null)
-            {
-                throw new IOException("No bundle associated with resource: " + url);
-            }
-            int revision = Util.getModuleRevisionFromModuleId(url.getHost());
-            IModule[] modules = bundle.getInfo().getModules();
-            if ((modules == null) || (revision < 0) || (revision >= modules.length))
+            if ((m_targetModule == null) || (m_classPathIdx < 0))
             {
                 throw new IOException("Resource does not exist: " + url);
             }
-            m_is = bundle.getInfo().getModules()[revision]
-                .getContentLoader().getInputStream(url.getPort(), url.getPath());
+            m_is = m_targetModule.getContentLoader()
+                .getInputStream(m_classPathIdx, url.getPath());
             m_contentLength = (m_is == null) ? 0 : m_is.available();
             m_contentTime = 0L;
             m_contentType = URLConnection.guessContentTypeFromName(url.getFile());
@@ -174,4 +183,4 @@
         // re-arranging to get this to work.
         return null;
     }
-}
\ No newline at end of file
+}