You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2017/08/25 18:14:49 UTC

svn commit: r1806207 - in /sling/trunk/bundles/extensions/bundleresource/src: main/java/org/apache/sling/bundleresource/impl/ test/java/org/apache/sling/bundleresource/impl/ test/java/org/apache/sling/bundleresource/impl/url/

Author: cziegeler
Date: Fri Aug 25 18:14:49 2017
New Revision: 1806207

URL: http://svn.apache.org/viewvc?rev=1806207&view=rev
Log:
SLING-6878 : Bundle resource provider: support mounting of JSON files

Modified:
    sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceCache.java
    sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceIterator.java
    sling/trunk/bundles/extensions/bundleresource/src/test/java/org/apache/sling/bundleresource/impl/BundleResourceProviderTest.java
    sling/trunk/bundles/extensions/bundleresource/src/test/java/org/apache/sling/bundleresource/impl/url/ResourceURLStreamHandler.java

Modified: sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceCache.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceCache.java?rev=1806207&r1=1806206&r2=1806207&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceCache.java (original)
+++ sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceCache.java Fri Aug 25 18:14:49 2017
@@ -22,7 +22,6 @@ import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.Collections;
 import java.util.Enumeration;
-import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
@@ -162,7 +161,7 @@ class BundleResourceCache {
      *         entries considered direct children of the <code>parentPath</code>
      *         or <code>null</code> if the parent entry does not exist.
      */
-    Iterator<String> getEntryPaths(String path) {
+    List<String> getEntryPaths(String path) {
         List<String> list = listCache.get(path);
         if (list == null) {
 
@@ -181,7 +180,7 @@ class BundleResourceCache {
             listCache.put(path, list);
         }
 
-        return (list == NOT_FOUND_CHILDREN) ? null : list.iterator();
+        return list;
     }
 
     // ---------- Management API

Modified: sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceIterator.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceIterator.java?rev=1806207&r1=1806206&r2=1806207&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceIterator.java (original)
+++ sling/trunk/bundles/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceIterator.java Fri Aug 25 18:14:49 2017
@@ -18,8 +18,11 @@
  */
 package org.apache.sling.bundleresource.impl;
 
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.TreeSet;
 
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
@@ -58,31 +61,17 @@ class BundleResourceIterator implements
      */
     BundleResourceIterator(final BundleResource parent) {
 
-        if (parent.isFile()) {
-
-            // if the parent is a file, the iterator is empty
-            this.resourceResolver = null;
-            this.bundle = null;
-            this.entries = null;
-            this.prefixLength = 0;
-            this.mappedPath = null;
-            this.nextResult = null;
-
-        } else {
-            // trailing slash to enumerate children
-            String parentPath = parent.getPath().concat("/");
-
-            this.resourceResolver = parent.getResourceResolver();
-            this.bundle = parent.getBundle();
-            this.mappedPath = parent.getMappedPath();
+        // trailing slash to enumerate children
+        String parentPath = parent.getPath().concat("/");
 
-            parentPath = mappedPath.getEntryPath(parentPath);
+        this.resourceResolver = parent.getResourceResolver();
+        this.bundle = parent.getBundle();
+        this.mappedPath = parent.getMappedPath();
 
-            this.entries = parent.getBundle().getEntryPaths(parentPath);
-            this.prefixLength = parentPath.length();
+        this.entries = getFilteredEntries(mappedPath.getEntryPath(parentPath));
+        this.prefixLength = parentPath.length();
 
-            this.nextResult = (entries != null) ? seek() : null;
-        }
+        this.nextResult = (entries != null) ? seek() : null;
     }
 
     BundleResourceIterator(ResourceResolver resourceResolver, BundleResourceCache bundle,
@@ -96,12 +85,29 @@ class BundleResourceIterator implements
         this.resourceResolver = resourceResolver;
         this.bundle = bundle;
         this.mappedPath = mappedPath;
-        this.entries = bundle.getEntryPaths(parentPath);
+        this.entries = getFilteredEntries(parentPath);
         this.prefixLength = parentPath.length();
 
         this.nextResult = (entries != null) ? seek() : null;
     }
 
+    private Iterator<String> getFilteredEntries(final String parentPath) {
+        final Set<String> bundleEntries = new TreeSet<>(bundle.getEntryPaths(parentPath));
+        if ( this.mappedPath.getJSONPropertiesExtension() != null ) {
+            final Set<String> add = new HashSet<>();
+            final Iterator<String> iter = bundleEntries.iterator();
+            while ( iter.hasNext() ) {
+                final String path = iter.next();
+                if ( path.endsWith(this.mappedPath.getJSONPropertiesExtension()) ) {
+                    iter.remove();
+                    add.add(path.substring(0, path.length() - this.mappedPath.getJSONPropertiesExtension().length()));
+                }
+            }
+            bundleEntries.addAll(add);
+        }
+        return (bundleEntries.isEmpty() ? null : bundleEntries.iterator());
+    }
+
     /** Returns true if there is another Resource available */
     @Override
     public boolean hasNext() {
@@ -143,8 +149,7 @@ class BundleResourceIterator implements
             }
 
             int slash = entry.indexOf('/', prefixLength);
-            if ((slash < 0 || slash == entry.length() - 1)
-                && (mappedPath.getJSONPropertiesExtension() == null || !entry.endsWith(mappedPath.getJSONPropertiesExtension()))) {
+            if (slash < 0 || slash == entry.length() - 1) {
                 log.debug("seek: Using entry {}", entry);
                 final boolean isFolder = entry.endsWith("/");
                 String propsPath = null;

Modified: sling/trunk/bundles/extensions/bundleresource/src/test/java/org/apache/sling/bundleresource/impl/BundleResourceProviderTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/bundleresource/src/test/java/org/apache/sling/bundleresource/impl/BundleResourceProviderTest.java?rev=1806207&r1=1806206&r2=1806207&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/bundleresource/src/test/java/org/apache/sling/bundleresource/impl/BundleResourceProviderTest.java (original)
+++ sling/trunk/bundles/extensions/bundleresource/src/test/java/org/apache/sling/bundleresource/impl/BundleResourceProviderTest.java Fri Aug 25 18:14:49 2017
@@ -21,16 +21,21 @@ package org.apache.sling.bundleresource.
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 
 import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.bundleresource.impl.url.ResourceURLStreamHandler;
 import org.apache.sling.bundleresource.impl.url.ResourceURLStreamHandlerFactory;
 import org.apache.sling.spi.resource.provider.ResolveContext;
@@ -56,6 +61,12 @@ public class BundleResourceProviderTest
         when(bundle.getEntry(path)).thenReturn(url);
     }
 
+    void finishContent(Bundle bundle) {
+        for(final Map.Entry<String, List<String>> entry : ResourceURLStreamHandler.getParentChildRelationship().entrySet()) {
+            when(bundle.getEntryPaths(entry.getKey())).thenReturn(Collections.enumeration(entry.getValue()));
+        }
+    }
+
     void addContent(Bundle bundle, String path, String content) throws IOException {
         final URL url = new URL("resource:" + path);
 
@@ -63,6 +74,23 @@ public class BundleResourceProviderTest
         when(bundle.getEntry(path)).thenReturn(url);
     }
 
+    String getContent(final Resource rsrc) throws IOException {
+        final InputStream is = rsrc.adaptTo(InputStream.class);
+        if ( is == null ) {
+            return null;
+        }
+        final byte[] buffer = new byte[20];
+        final int l = is.read(buffer);
+        return new String(buffer, 0, l, "UTF-8");
+    }
+
+    @SuppressWarnings("unchecked")
+    void assertContent(final BundleResourceProvider provider, final String path, final String content) throws IOException {
+        final Resource rsrc = provider.getResource(mock(ResolveContext.class), path, mock(ResourceContext.class), null);
+        assertNotNull(rsrc);
+        assertEquals(content, getContent(rsrc));
+    }
+
     @Before
     public void setup() {
         ResourceURLStreamHandlerFactory.init();
@@ -113,9 +141,72 @@ public class BundleResourceProviderTest
         assertNotNull(rsrc.adaptTo(URL.class));
         assertNotNull(rsrc.getValueMap());
         assertEquals("foo", rsrc.getValueMap().get("test", String.class));
-        final InputStream is = rsrc.adaptTo(InputStream.class);
-        final byte[] buffer = new byte[20];
-        final int l = is.read(buffer);
-        assertEquals("HELLOWORLD", new String(buffer, 0, l, "UTF-8"));
+        assertEquals("HELLOWORLD", getContent(rsrc));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test public void testTree() throws IOException {
+        final Bundle bundle = getBundle();
+        addContent(bundle, "/libs/foo/", "DIR");
+        addContent(bundle, "/libs/foo/a", "A");
+        addContent(bundle, "/libs/foo/b", "B");
+        addContent(bundle, "/libs/foo/test", "test");
+        addContent(bundle, "/libs/foo/test/x", "X");
+        addContent(bundle, "/libs/foo/test/y", "Y");
+        addContent(bundle, "/libs/foo/test/z.json", Collections.singletonMap(ResourceResolver.PROPERTY_RESOURCE_TYPE, (Object)"rtz"));
+        addContent(bundle, "/libs/foo/test.json", Collections.singletonMap("test", (Object)"foo"));
+
+        finishContent(bundle);
+
+        final MappedPath path = new MappedPath("/libs/foo", null, "json");
+
+        final BundleResourceProvider provider = new BundleResourceProvider(bundle, path);
+
+        assertContent(provider, "/libs/foo/a", "A");
+        assertContent(provider, "/libs/foo/b", "B");
+        assertContent(provider, "/libs/foo/test", "test");
+        assertContent(provider, "/libs/foo/test/x", "X");
+        assertContent(provider, "/libs/foo/test/y", "Y");
+        assertContent(provider, "/libs/foo/test/z", null);
+
+        Resource rsrc = provider.getResource(mock(ResolveContext.class), "/libs/foo", mock(ResourceContext.class), null);
+        assertNotNull(rsrc);
+
+        List<String> rsrcChildren = getChildren(rsrc.listChildren());
+        assertEquals(3, rsrcChildren.size());
+        assertTrue(rsrcChildren.contains("/libs/foo/a"));
+        assertTrue(rsrcChildren.contains("/libs/foo/b"));
+        assertTrue(rsrcChildren.contains("/libs/foo/test"));
+
+        rsrcChildren = getChildren(provider.listChildren(mock(ResolveContext.class), rsrc));
+        assertEquals(3, rsrcChildren.size());
+        assertTrue(rsrcChildren.contains("/libs/foo/a"));
+        assertTrue(rsrcChildren.contains("/libs/foo/b"));
+        assertTrue(rsrcChildren.contains("/libs/foo/test"));
+
+        rsrc = provider.getResource(mock(ResolveContext.class), "/libs/foo/test", mock(ResourceContext.class), null);
+        assertNotNull(rsrc);
+
+        rsrcChildren = getChildren(rsrc.listChildren());
+        assertEquals(3, rsrcChildren.size());
+        assertTrue(rsrcChildren.contains("/libs/foo/test/x"));
+        assertTrue(rsrcChildren.contains("/libs/foo/test/y"));
+        assertTrue(rsrcChildren.contains("/libs/foo/test/z"));
+
+        rsrcChildren = getChildren(provider.listChildren(mock(ResolveContext.class), rsrc));
+        assertEquals(3, rsrcChildren.size());
+        assertTrue(rsrcChildren.contains("/libs/foo/test/x"));
+        assertTrue(rsrcChildren.contains("/libs/foo/test/y"));
+        assertTrue(rsrcChildren.contains("/libs/foo/test/z"));
+    }
+
+    List<String> getChildren(final Iterator<Resource> i) {
+        final List<String> list = new ArrayList<>();
+        if ( i != null ) {
+            while ( i.hasNext() ) {
+                list.add(i.next().getPath());
+            }
+        }
+        return list;
     }
 }

Modified: sling/trunk/bundles/extensions/bundleresource/src/test/java/org/apache/sling/bundleresource/impl/url/ResourceURLStreamHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/bundleresource/src/test/java/org/apache/sling/bundleresource/impl/url/ResourceURLStreamHandler.java?rev=1806207&r1=1806206&r2=1806207&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/bundleresource/src/test/java/org/apache/sling/bundleresource/impl/url/ResourceURLStreamHandler.java (original)
+++ sling/trunk/bundles/extensions/bundleresource/src/test/java/org/apache/sling/bundleresource/impl/url/ResourceURLStreamHandler.java Fri Aug 25 18:14:49 2017
@@ -23,6 +23,7 @@ import java.io.StringWriter;
 import java.net.URL;
 import java.net.URLConnection;
 import java.net.URLStreamHandler;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -32,12 +33,27 @@ import javax.json.JsonArrayBuilder;
 import javax.json.JsonObjectBuilder;
 import javax.json.JsonStructure;
 
+import org.apache.sling.api.resource.ResourceUtil;
+
 public class ResourceURLStreamHandler extends URLStreamHandler {
 
     private static final Map<String, String> contents = new HashMap<>();
 
+    private static final Map<String, List<String>> parentChild = new HashMap<>();
+
     public static void addContents(final String path, final String c) {
         contents.put(path, c);
+        final String parent = ResourceUtil.getParent(path).concat("/");
+        List<String> children = parentChild.get(parent);
+        if ( children == null ) {
+            children = new ArrayList<>();
+            parentChild.put(parent, children);
+        }
+        children.add(path);
+    }
+
+    public static  Map<String, List<String>> getParentChildRelationship() {
+        return parentChild;
     }
 
     public static void addJSON(final String path, final Map<String, Object> props) {