You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pd...@apache.org on 2016/03/21 21:01:34 UTC

svn commit: r1736078 - in /felix/trunk/connect: pom.xml src/main/java/org/apache/felix/connect/PojoSR.java src/main/java/org/apache/felix/connect/URLRevision.java src/main/java/org/apache/felix/connect/VFSRevision.java

Author: pderop
Date: Mon Mar 21 20:01:34 2016
New Revision: 1736078

URL: http://svn.apache.org/viewvc?rev=1736078&view=rev
Log:
FELIX-5206: Added a patch for the support of JBoss VFS URls.

Added:
    felix/trunk/connect/src/main/java/org/apache/felix/connect/VFSRevision.java
Modified:
    felix/trunk/connect/pom.xml
    felix/trunk/connect/src/main/java/org/apache/felix/connect/PojoSR.java
    felix/trunk/connect/src/main/java/org/apache/felix/connect/URLRevision.java

Modified: felix/trunk/connect/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/connect/pom.xml?rev=1736078&r1=1736077&r2=1736078&view=diff
==============================================================================
--- felix/trunk/connect/pom.xml (original)
+++ felix/trunk/connect/pom.xml Mon Mar 21 20:01:34 2016
@@ -65,6 +65,11 @@
             <artifactId>org.osgi.compendium</artifactId>
             <version>5.0.0</version>
         </dependency>
+        <dependency>
+		<groupId>org.jboss</groupId>
+			<artifactId>jboss-vfs</artifactId>
+			<version>3.2.11.Final</version>
+		</dependency>
     </dependencies>
     <repositories />
     <pluginRepositories />

Modified: felix/trunk/connect/src/main/java/org/apache/felix/connect/PojoSR.java
URL: http://svn.apache.org/viewvc/felix/trunk/connect/src/main/java/org/apache/felix/connect/PojoSR.java?rev=1736078&r1=1736077&r2=1736078&view=diff
==============================================================================
--- felix/trunk/connect/src/main/java/org/apache/felix/connect/PojoSR.java (original)
+++ felix/trunk/connect/src/main/java/org/apache/felix/connect/PojoSR.java Mon Mar 21 20:01:34 2016
@@ -82,7 +82,8 @@ public class PojoSR implements PojoServi
     private final EventDispatcher m_dispatcher = new EventDispatcher(m_registry);
     private final Map<Long, Bundle> m_bundles = new HashMap<Long, Bundle>();
     private final Map<String, Object> bundleConfig;
-
+    private final boolean m_hasVFS;
+    
     public static BundleDescriptor createSystemBundle() {
         final Map<String, String> headers = new HashMap<String, String>();
         headers.put(Constants.BUNDLE_SYMBOLICNAME, "org.apache.felix.connect");
@@ -241,6 +242,15 @@ public class PojoSR implements PojoServi
         b.getBundleContext().registerService(PackageAdmin.class.getName(), new PackageAdminImpl(), null);
         m_context = b.getBundleContext();
 
+        boolean hasVFS;
+        try
+        {
+            hasVFS = org.jboss.vfs.VFS.class != null;
+        } catch (Throwable t) {
+            hasVFS = false;
+        }
+        m_hasVFS = hasVFS;
+        
         Collection<BundleDescriptor> scan = (Collection<BundleDescriptor>) config.get(PojoServiceRegistryFactory.BUNDLE_DESCRIPTORS);
 
         if (scan != null)
@@ -317,7 +327,8 @@ public class PojoSR implements PojoServi
         Revision r;
         URL url = new URL(desc.getUrl());
         URL u = new URL(desc.getUrl() + "META-INF/MANIFEST.MF");
-        if (u.toExternalForm().startsWith("file:"))
+        String extF = u.toExternalForm(); 
+        if (extF.startsWith("file:"))
         {
             File root = new File(URLDecoder.decode(url.getFile(), "UTF-8"));
             r = new DirRevision(root);
@@ -339,6 +350,10 @@ public class PojoSR implements PojoServi
                         prefix,
                         uc.getLastModified());
             }
+            else if (m_hasVFS && extF.startsWith("vfs")) 
+            {
+                r = new VFSRevision(url, url.openConnection().getLastModified());
+            }
             else
             {
                 r = new URLRevision(url, url.openConnection().getLastModified());

Modified: felix/trunk/connect/src/main/java/org/apache/felix/connect/URLRevision.java
URL: http://svn.apache.org/viewvc/felix/trunk/connect/src/main/java/org/apache/felix/connect/URLRevision.java?rev=1736078&r1=1736077&r2=1736078&view=diff
==============================================================================
--- felix/trunk/connect/src/main/java/org/apache/felix/connect/URLRevision.java (original)
+++ felix/trunk/connect/src/main/java/org/apache/felix/connect/URLRevision.java Mon Mar 21 20:01:34 2016
@@ -18,15 +18,30 @@
  */
 package org.apache.felix.connect;
 
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarInputStream;
+import java.lang.ref.WeakReference;
 
 class URLRevision implements Revision
 {
     private final URL m_url;
     private final long m_lastModified;
+    private WeakReference<byte[]> m_urlContent;
 
     public URLRevision(URL url, long lastModified)
     {
@@ -50,13 +65,39 @@ class URLRevision implements Revision
     @Override
     public Enumeration<String> getEntries()
     {
-        return Collections.enumeration(Collections.EMPTY_LIST);
-    }
+        InputStream content = null;
+        JarInputStream jarInput = null;
+        
+        try
+        {
+            content = getUrlContent();
+            jarInput = new JarInputStream(content);
+            List<String> entries = new ArrayList<String>();
+            JarEntry jarEntry;
+
+            while ((jarEntry = jarInput.getNextJarEntry()) != null)
+            {
+                entries.add(jarEntry.getName());
+            }
+            return Collections.enumeration(entries);
+        }
 
+        catch (IOException e)
+        {
+            e.printStackTrace();
+            return Collections.enumeration(Collections.EMPTY_LIST);
+        }
+
+        finally
+        {
+            close(content);
+            close(jarInput);
+        }
+    }
+    
     @Override
     public URL getEntry(String entryName)
     {
-        // TODO Auto-generated method stub
         try
         {
             return new URL(m_url, entryName);
@@ -68,4 +109,59 @@ class URLRevision implements Revision
             return null;
         }
     }
+    
+    /**
+     * Loads the URL content, and cache it using a weak reference.
+     * 
+     * @return the URL content
+     * @throws IOException on any io errors
+     */
+    private synchronized InputStream getUrlContent() throws IOException {
+        BufferedInputStream in = null;
+        ByteArrayOutputStream out = null;
+        byte[] content = null;
+
+        try
+        {
+            if (m_urlContent == null || (content = m_urlContent.get()) == null)
+            {
+                out = new ByteArrayOutputStream(4096);
+                in = new BufferedInputStream(m_url.openStream(), 4096);
+                int c;
+                while ((c = in.read()) != -1)
+                {
+                    out.write(c);
+                }
+                content = out.toByteArray();
+                m_urlContent = new WeakReference<byte[]>(content);
+            }
+
+            return new ByteArrayInputStream(content);
+        }
+
+        finally
+        {
+            close(out);
+            close(in);
+        }
+    }     
+    
+    /**
+     * Helper method used to simply close a stream.
+     * 
+     * @param closeable the stream to close
+     */
+    private void close(Closeable closeable) 
+    {
+        try
+        {
+            if (closeable != null) 
+            {
+                closeable.close();
+            }
+        }
+        catch (IOException e) 
+        {               
+        }
+    }
 }

Added: felix/trunk/connect/src/main/java/org/apache/felix/connect/VFSRevision.java
URL: http://svn.apache.org/viewvc/felix/trunk/connect/src/main/java/org/apache/felix/connect/VFSRevision.java?rev=1736078&view=auto
==============================================================================
--- felix/trunk/connect/src/main/java/org/apache/felix/connect/VFSRevision.java (added)
+++ felix/trunk/connect/src/main/java/org/apache/felix/connect/VFSRevision.java Mon Mar 21 20:01:34 2016
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.connect;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.vfs.VFS;
+import org.jboss.vfs.VirtualFile;
+import org.jboss.vfs.VirtualFileVisitor;
+import org.jboss.vfs.VisitorAttributes;
+
+/**
+ * Loads the content of a bundle using JBoss VFS protocol.
+ */
+public class VFSRevision implements Revision
+{
+    private final URL m_url;
+    private final long m_lastModified;
+    private final Map<String, VirtualFile> m_entries = new HashMap<String, VirtualFile>();
+    
+    public VFSRevision(URL url, long lastModified)
+    {
+        m_url = url;
+        m_lastModified = lastModified;
+    }
+
+    public long getLastModified()
+    {
+        return m_lastModified;
+    }
+
+    public Enumeration<String> getEntries()
+    {
+        try
+        {
+            loadEntries(); // lazily load entries
+            return Collections.enumeration(m_entries.keySet());
+        }
+        catch (URISyntaxException e)
+        {
+            e.printStackTrace();
+            return null;
+        }
+        catch (IOException e)
+        {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public URL getEntry(String entryName)
+    {
+        try
+        {
+            loadEntries();
+            VirtualFile vfile = m_entries.get(entryName);
+            return vfile != null ? vfile.toURL() : null;
+        }
+        catch (MalformedURLException e)
+        {
+            e.printStackTrace();
+            return null;
+        }
+        catch (URISyntaxException e)
+        {
+            e.printStackTrace();
+            return null;
+        }
+        catch (IOException e)
+        {
+            e.printStackTrace();
+            return null;
+        }
+    }
+    
+    private synchronized void loadEntries() throws URISyntaxException, IOException
+    {
+        if (m_entries.size() == 0)
+        {
+            final VirtualFile root = VFS.getChild(m_url.toURI());
+            final String uriPath = m_url.toURI().getPath();
+
+            root.visit(new VirtualFileVisitor()
+            {
+                public void visit(VirtualFile vfile)
+                {
+                    String entryPath = vfile.getPathName().substring(uriPath.length());
+                    m_entries.put(entryPath, vfile);
+                }
+
+                public VisitorAttributes getAttributes()
+                {
+                    return VisitorAttributes.RECURSE_LEAVES_ONLY;
+                }
+            });
+        }
+    }
+}