Modified URLHandlersBundleURLConnection to throw an exception if the resource
does not exist. This was rather complicated since it illustrated a whole in
the module abstractions. I extended the abstractions, but may need to revisit
them in the future.


git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@426008 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/SystemBundleContentLoader.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/SystemBundleContentLoader.java
index aa20c2f..70a684f 100644
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/SystemBundleContentLoader.java
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/SystemBundleContentLoader.java
@@ -89,9 +89,14 @@
         return getClass().getClassLoader().getResource(name);
     }
 
-    public InputStream getResourceAsStream(String name) throws IOException
+    public boolean hasInputStream(String urlPath) throws IOException
     {
-        return getClass().getClassLoader().getResourceAsStream(name);
+        return (getClass().getClassLoader().getResource(urlPath) != null);
+    }
+
+    public InputStream getInputStream(String urlPath) throws IOException
+    {
+        return getClass().getClassLoader().getResourceAsStream(urlPath);
     }
 
     public String findLibrary(String name)
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
index 9c5b05e..c8a95ce 100644
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
@@ -22,7 +22,9 @@
 import java.net.URLConnection;
 import java.security.Permission;
 
+import org.apache.felix.framework.searchpolicy.ContentLoaderImpl;
 import org.apache.felix.framework.util.Util;
+import org.apache.felix.moduleloader.IModule;
 
 class URLHandlersBundleURLConnection extends URLConnection
 {
@@ -33,29 +35,46 @@
     private InputStream m_is;
 
     public URLHandlersBundleURLConnection(URL url, Felix framework)
+        throws IOException
     {
         super(url);
         m_framework = framework;
+
+        // If we don't have a framework instance, try to find
+        // one from the call context.
+        if (m_framework == null)
+        {
+            m_framework = URLHandlers.getFrameworkFromContext();
+        }
+
+        // If there is still no framework, then error.
+        if (m_framework == null)
+        {
+            throw new IOException("Unable to find framework for URL: " + url);
+        }
+        // Verify that the resource pointed to be the URL exists.
+        // The URL is constructed like this:
+        //     bundle://<module-id>/<resource-path>
+        // Where <module-id> = <bundle-id>.<revision>
+        long bundleId = Util.getBundleIdFromModuleId(url.getHost());
+        BundleImpl bundle = (BundleImpl) 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) ||
+            !modules[revision].getContentLoader().hasInputStream(url.getPath()))
+        {
+            throw new IOException("Resource does not exist: " + url);
+        }
     }
 
     public void connect() throws IOException
     {
         if (!connected)
         {
-            // If we don't have a framework instance, try to find
-            // one from the call context.
-            if (m_framework == null)
-            {
-                m_framework = URLHandlers.getFrameworkFromContext();
-            }
-
-            // If the framework has disabled the URL Handlers service,
-            // then it will not be found so just return null.
-            if (m_framework == null)
-            {
-                throw new IOException("Unable to find framework instance from context.");
-            }
-
             // The URL is constructed like this:
             //     bundle://<module-id>/<resource-path>
             // Where <module-id> = <bundle-id>.<revision>
@@ -63,10 +82,15 @@
             BundleImpl bundle = (BundleImpl) m_framework.getBundle(bundleId);
             if (bundle == null)
             {
-                throw new IOException("Unable to find bundle.");
+                throw new IOException("No bundle associated with resource: " + url);
             }
             int revision = Util.getModuleRevisionFromModuleId(url.getHost());
-            m_is = bundle.getInfo().getModules()[revision].getContentLoader().getResourceAsStream(url.getPath());
+            IModule[] modules = bundle.getInfo().getModules();
+            if ((modules == null) || (revision < 0) || (revision >= modules.length))
+            {
+                throw new IOException("Resource does not exist: " + url);
+            }
+            m_is = bundle.getInfo().getModules()[revision].getContentLoader().getInputStream(url.getPath());
             m_contentLength = (m_is == null) ? 0 : m_is.available();
             m_contentTime = 0L;
             m_contentType = URLConnection.guessContentTypeFromName(url.getFile());
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 fe45fa6..ccebe16 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
@@ -196,25 +196,47 @@
         return url;
     }
 
-    public InputStream getResourceAsStream(String name)
-        throws IOException
+    public boolean hasInputStream(String urlPath)
     {
-        if (name.startsWith("/"))
+        if (urlPath.startsWith("/"))
         {
-            name = name.substring(1);
+            urlPath = urlPath.substring(1);
         }
-        // The name is the path contructed like this:
+        // 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(name.substring(0, name.indexOf('/')));
-        name = name.substring(name.indexOf('/') + 1);
+        int idx = Integer.parseInt(urlPath.substring(0, urlPath.indexOf('/')));
+        urlPath = urlPath.substring(urlPath.indexOf('/') + 1);
         if (idx == 0)
         {
-            return m_content.getEntryAsStream(name);
+            return m_content.hasEntry(urlPath);
         }
-        return m_contentPath[idx - 1].getEntryAsStream(name);
+        return m_contentPath[idx - 1].hasEntry(urlPath);
+    }
+
+    public InputStream getInputStream(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)
+        {
+            return m_content.getEntryAsStream(urlPath);
+        }
+        return m_contentPath[idx - 1].getEntryAsStream(urlPath);
     }
 
     public String toString()
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/moduleloader/IContentLoader.java b/org.apache.felix.framework/src/main/java/org/apache/felix/moduleloader/IContentLoader.java
index be88eca..7aac6b0 100644
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/moduleloader/IContentLoader.java
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/moduleloader/IContentLoader.java
@@ -36,6 +36,8 @@
     public Class getClass(String name);
     public URL getResource(String name);
 
-    public InputStream getResourceAsStream(String name)
+    public boolean hasInputStream(String urlPath)
+        throws IOException;
+    public InputStream getInputStream(String urlPath)
         throws IOException;
 }
\ No newline at end of file