Initial implementation of Bundle.getEntryPaths().


git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@375245 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 cc05008..161b1de 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
@@ -60,6 +60,11 @@
         return m_felix.getBundleEntry(this, name);
     }
 
+    public Enumeration getEntryPaths(String path)
+    {
+        return m_felix.getBundleEntryPaths(this, path);
+    }
+
     public Dictionary getHeaders()
     {
         return m_felix.getBundleHeaders(this);
@@ -168,12 +173,6 @@
         return null;
     }
 
-    public Enumeration getEntryPaths(String path)
-    {
-        // TODO: Implement Bundle.getEntryPaths()
-        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 f946fbf..01820b0 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
@@ -984,6 +984,29 @@
             .getContentLoader()).getResourceFromContent(name);
     }
 
+    /**
+     * Implementation for Bundle.getEntryPaths().
+    **/
+    protected Enumeration getBundleEntryPaths(BundleImpl bundle, String path)
+    {
+        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);
+        }
+        // Strip leading '/' if present.
+        if (path.charAt(0) == '/')
+        {
+            path = path.substring(1);
+        }
+        return bundle.getInfo().getCurrentModule()
+            .getContentLoader().getContent().getEntryPaths(path);
+    }
+
     protected ServiceReference[] getBundleRegisteredServices(BundleImpl bundle)
     {
         if (bundle.getInfo().getState() == Bundle.UNINSTALLED)
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/moduleloader/IContent.java b/org.apache.felix.framework/src/main/java/org/apache/felix/moduleloader/IContent.java
index a0e5653..7261fdc 100644
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/moduleloader/IContent.java
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/moduleloader/IContent.java
@@ -18,6 +18,7 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Enumeration;
 
 public interface IContent
 {
@@ -27,5 +28,5 @@
     public byte[] getEntry(String name);
     public InputStream getEntryAsStream(String name)
         throws IOException;
-    public String[] getEntryPaths(String path);
+    public Enumeration getEntryPaths(String path);
 }
\ No newline at end of file
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/moduleloader/JarContent.java b/org.apache.felix.framework/src/main/java/org/apache/felix/moduleloader/JarContent.java
index b7c9aa8..cca51cf 100644
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/moduleloader/JarContent.java
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/moduleloader/JarContent.java
@@ -17,8 +17,8 @@
 package org.apache.felix.moduleloader;
 
 import java.io.*;
-import java.io.File;
-import java.io.IOException;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
 import java.util.jar.JarFile;
 import java.util.zip.ZipEntry;
 
@@ -224,9 +224,31 @@
         return is;
     }
 
-    public String[] getEntryPaths(String path)
+    public synchronized Enumeration getEntryPaths(String path)
     {
-        return null;
+        if (!m_opened)
+        {
+            throw new IllegalStateException("JarContent is not open");
+        }
+
+        // Open JAR file if not already opened.
+        if (m_jarFile == null)
+        {
+            try
+            {
+                openJarFile();
+            }
+            catch (IOException ex)
+            {
+                System.err.println("JarResourceSource: " + ex);
+                return null;
+            }
+        }
+
+        // Wrap entries enumeration to filter non-matching entries.
+        Enumeration e = new FilteredEnumeration(m_jarFile.entries(), path);
+        // Spec says to return null if there are no entries.
+        return (e.hasMoreElements()) ? e : null;
     }
 
     private void openJarFile() throws IOException
@@ -241,4 +263,49 @@
     {
         return "JAR " + m_file.getPath();
     }
+
+    private static class FilteredEnumeration implements Enumeration
+    {
+        private Enumeration m_enumeration = null;
+        private String m_path = null;
+        private Object m_next = null;
+
+        public FilteredEnumeration(Enumeration enumeration, String path)
+        {
+            m_enumeration = enumeration;
+            // Add a '/' to the end if not present.
+            m_path = (path.length() > 0) && (path.charAt(path.length() - 1) != '/')
+                ? path + "/" : path;
+            m_next = findNext();
+        }
+
+        public boolean hasMoreElements()
+        {
+            return (m_next != null);
+        }
+
+        public Object nextElement()
+        {
+            if (m_next == null)
+            {
+                throw new NoSuchElementException("No more entry paths.");
+            }
+            Object last = m_next;
+            m_next = findNext();
+            return last;
+        }
+
+        private Object findNext()
+        {
+            while (m_enumeration.hasMoreElements())
+            {
+                ZipEntry entry = (ZipEntry) m_enumeration.nextElement();
+                if (entry.getName().startsWith(m_path))
+                {
+                    return entry.getName();
+                }
+            }
+            return null;
+        }
+    }
 }
\ No newline at end of file