[FELIX-2645] Add  (hidden) way to retrieve a local URL for a given bundle URL

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1005825 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
index 4f6f347..36d673a 100644
--- a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
+++ b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
@@ -610,6 +610,11 @@
         return null;
     }
 
+    public URL getEntryAsURL(String name)
+    {
+        return null;
+    }
+
     //
     // Utility methods.
     //
@@ -757,5 +762,10 @@
         {
             return getClass().getClassLoader().getResourceAsStream(urlPath);
         }
+
+        public URL getLocalURL(int index, String urlPath)
+        {
+            return getClass().getClassLoader().getResource(urlPath);
+        }
     }
 }
diff --git a/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java b/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
index 1d721f8..944e2c7 100644
--- a/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
@@ -1091,6 +1091,19 @@
         return getContentPath()[index - 1].getEntryAsStream(urlPath);
     }
 
+    public URL getLocalURL(int index, String urlPath)
+    {
+        if (urlPath.startsWith("/"))
+        {
+            urlPath = urlPath.substring(1);
+        }
+        if (index == 0)
+        {
+            return m_content.getEntryAsURL(urlPath);
+        }
+        return getContentPath()[index - 1].getEntryAsURL(urlPath);
+    }
+
     private URL createURL(int port, String path)
     {
          // Add a slash if there is one already, otherwise
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 1751567..6835c66 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
@@ -28,7 +28,7 @@
 
 import org.apache.felix.framework.util.Util;
 
-class URLHandlersBundleURLConnection extends URLConnection
+public class URLHandlersBundleURLConnection extends URLConnection
 {
     private Felix m_framework;
     private Module m_targetModule;
@@ -195,4 +195,18 @@
         // re-arranging to get this to work.
         return null;
     }
+
+    /**
+     * Retrieve the entry as a URL using standard protocols such as file: and jar:
+     *
+     * @return the local URL
+     */
+    public URL getLocalURL()
+    {
+        if ((m_targetModule == null) || (m_classPathIdx < 0))
+        {
+            return url;
+        }
+        return m_targetModule.getLocalURL(m_classPathIdx, url.getPath());
+    }
 }
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/ContentDirectoryContent.java b/framework/src/main/java/org/apache/felix/framework/cache/ContentDirectoryContent.java
index 263ba04..aed76c6 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/ContentDirectoryContent.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/ContentDirectoryContent.java
@@ -21,6 +21,7 @@
 import org.apache.felix.framework.resolver.Content;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.URL;
 import java.util.Enumeration;
 import java.util.NoSuchElementException;
 
@@ -81,6 +82,11 @@
         return m_content.getEntryAsStream(m_rootPath + name);
     }
 
+    public URL getEntryAsURL(String name)
+    {
+        return m_content.getEntryAsURL(m_rootPath + name);
+    }
+
     public Content getEntryAsContent(String name)
     {
         if ((name.length() > 0) && (name.charAt(0) == '/'))
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java b/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java
index 9db1ca6..b9ecc1c 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java
@@ -20,6 +20,8 @@
 
 import org.apache.felix.framework.resolver.Content;
 import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.*;
 import org.apache.felix.framework.Logger;
 import org.apache.felix.framework.util.FelixConstants;
@@ -131,6 +133,23 @@
         return new FileInputStream(new File(m_dir, name));
     }
 
+    public URL getEntryAsURL(String name)
+    {
+        if ((name.length() > 0) && (name.charAt(0) == '/'))
+        {
+            name = name.substring(1);
+        }
+
+        try
+        {
+            return new File(m_dir, name).toURI().toURL();
+        }
+        catch (MalformedURLException e)
+        {
+            return null;
+        }
+    }
+
     public Content getEntryAsContent(String entryName)
     {
         // If the entry name refers to the content itself, then
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/JarContent.java b/framework/src/main/java/org/apache/felix/framework/cache/JarContent.java
index 1420eee..5085fd6 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/JarContent.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/JarContent.java
@@ -23,6 +23,8 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Map;
@@ -190,6 +192,18 @@
         return is;
     }
 
+    public URL getEntryAsURL(String name)
+    {
+        try
+        {
+            return new URL("jar:" + m_file.toURI().toURL().toExternalForm() + "!/" + name);
+        }
+        catch (MalformedURLException e)
+        {
+            return null;
+        }
+    }
+
     public Content getEntryAsContent(String entryName)
     {
         // If the entry name refers to the content itself, then
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Content.java b/framework/src/main/java/org/apache/felix/framework/resolver/Content.java
index 3e13a19..3655307 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/Content.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Content.java
@@ -20,6 +20,7 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.URL;
 import java.util.Enumeration;
 
 public interface Content
@@ -109,4 +110,15 @@
      *         corresponding entry was found, <tt>null</tt> otherwise.
     **/
     String getEntryAsNativeLibrary(String name);
+
+    /**
+     * <p>
+     *  This method allows retrieving an entry as a plain standard URL.
+     * </p>
+     *
+     * @param name The name of the entry to retrieve as a URL
+     * @return A URL using a standard protocol such as file, jar
+     *           or null if not possible.
+     */
+    URL getEntryAsURL(String name);
 }
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/resolver/Module.java b/framework/src/main/java/org/apache/felix/framework/resolver/Module.java
index 4220cb0..695bfd3 100644
--- a/framework/src/main/java/org/apache/felix/framework/resolver/Module.java
+++ b/framework/src/main/java/org/apache/felix/framework/resolver/Module.java
@@ -72,4 +72,5 @@
         throws IOException;
     InputStream getInputStream(int index, String urlPath)
         throws IOException;
+    URL getLocalURL(int index, String urlPath);
 }
\ No newline at end of file