You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ju...@apache.org on 2015/01/14 23:36:58 UTC

svn commit: r1651858 - in /sling/trunk/contrib/extensions/resourcemerger/src: main/java/org/apache/sling/resourcemerger/impl/ main/java/org/apache/sling/resourcemerger/impl/picker/ test/java/org/apache/sling/resourcemerger/impl/

Author: justin
Date: Wed Jan 14 22:36:57 2015
New Revision: 1651858

URL: http://svn.apache.org/r1651858
Log:
SLING-4311 - have the overriding resource picker create stub (non-existing) resources to accommodate for missing hierarchy nodes.

Added:
    sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/StubResource.java
Modified:
    sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergingResourceProvider.java
    sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/picker/OverridingResourcePicker.java
    sling/trunk/contrib/extensions/resourcemerger/src/test/java/org/apache/sling/resourcemerger/impl/OverridingResourceProviderTest.java

Modified: sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergingResourceProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergingResourceProvider.java?rev=1651858&r1=1651857&r2=1651858&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergingResourceProvider.java (original)
+++ sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/MergingResourceProvider.java Wed Jan 14 22:36:57 2015
@@ -68,32 +68,65 @@ class MergingResourceProvider implements
 
     protected static final class ParentHidingHandler {
 
-        private List<ExcludeEntry> entries;
+        private List<ExcludeEntry> entries = new ArrayList<ExcludeEntry>();
 
         public ParentHidingHandler(final Resource parent) {
             final ValueMap parentProps = ResourceUtil.getValueMap(parent);
             final String[] childrenToHideArray = parentProps.get(MergedResourceConstants.PN_HIDE_CHILDREN, String[].class);
-            if ( childrenToHideArray != null ) {
-                this.entries = new ArrayList<ExcludeEntry>();
-                for(final String value : childrenToHideArray) {
+            if (childrenToHideArray != null) {
+                for (final String value : childrenToHideArray) {
                     final ExcludeEntry entry = new ExcludeEntry(value);
                     this.entries.add(entry);
                 }
             }
+            if (parent != null) {
+                Resource ancestor = parent.getParent();
+                while (ancestor != null) {
+                    String previousAncestorName = parent.getName();
+                    final ValueMap ancestorProps = ResourceUtil.getValueMap(ancestor);
+                    final String[] ancestorChildrenToHideArray = ancestorProps.get(MergedResourceConstants.PN_HIDE_CHILDREN, String[].class);
+                    if (ancestorChildrenToHideArray != null) {
+                        for (final String value : ancestorChildrenToHideArray) {
+                            final ExcludeEntry entry = new ExcludeEntry(value);
+                            final Boolean hides = hides(entry, previousAncestorName);
+                            if (hides != null && hides.booleanValue() == true) {
+                                this.entries.add(new ExcludeEntry("*"));
+                                break;
+                            }
+                        }
+                    }
+                    ancestor = ancestor.getParent();
+                }
+            }
         }
 
         public boolean isHidden(final String name) {
             boolean hidden = false;
             if ( this.entries != null ) {
                 for(final ExcludeEntry entry : this.entries) {
-                    if ( entry.name.equals("*") || entry.name.equals(name) ) {
-                        hidden = !entry.exclude;
+                    Boolean result = hides(entry, name);
+                    if (result != null) {
+                        hidden = result.booleanValue();
                         break;
                     }
                 }
             }
             return hidden;
         }
+
+        /**
+         * Determine if an entry should hide the named resource.
+         * 
+         * @return a non-null value if the entry matches; a null value if it does not
+         */
+        private Boolean hides(final ExcludeEntry entry, final String name) {
+            Boolean result = null;
+            if (entry.name.equals("*") || entry.name.equals(name)) {
+                result = Boolean.valueOf(!entry.exclude);
+            }
+            return result;
+        }
+
     }
 
     protected static final class ResourceHolder {

Added: sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/StubResource.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/StubResource.java?rev=1651858&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/StubResource.java (added)
+++ sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/StubResource.java Wed Jan 14 22:36:57 2015
@@ -0,0 +1,75 @@
+/*
+ * 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.sling.resourcemerger.impl;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.SyntheticResource;
+
+/**
+ * Simple helper class representing nonexisting resources.
+ * 
+ * This is similar to NonExistingResource, with the exception that it 
+ * always returns a valid resource for the parent resource unless
+ * this is a top level (e.g. /foo) path.
+ */
+public final class StubResource extends SyntheticResource {
+
+    /**
+     * Create a new stub resource.
+     * @param resourceResolver The resource resolver.
+     * @param resourceURI The path of the resource.
+     */
+    public StubResource(final ResourceResolver resourceResolver,
+            final String resourceURI) {
+        super(resourceResolver, resourceURI, RESOURCE_TYPE_NON_EXISTING);
+    }
+
+    /**
+     * @see org.apache.sling.api.resource.SyntheticResource#getResourceType()
+     */
+    public final String getResourceType() {
+        // overwrite to prevent overwriting of this method in extensions of
+        // this class because the specific resource type is the marker of a
+        // NonExistingResource
+        return RESOURCE_TYPE_NON_EXISTING;
+    }
+
+    public String toString() {
+        // overwrite to only list the class name and path, type is irrelevant
+        return getClass().getSimpleName() + ", path=" + getPath();
+    }
+
+    @Override
+    public Resource getParent() {
+        final Resource parent = super.getParent();
+        if (parent != null) {
+            return parent;
+        } else {
+            final String absPath = getPath();
+            final int lastIdx = absPath.lastIndexOf('/');
+            if (lastIdx <= 0) {
+                return null;
+            } else {
+                final String parentPath = absPath.substring(0, lastIdx);
+                return new StubResource(getResourceResolver(), parentPath);
+            }
+        }
+    }
+}

Modified: sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/picker/OverridingResourcePicker.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/picker/OverridingResourcePicker.java?rev=1651858&r1=1651857&r2=1651858&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/picker/OverridingResourcePicker.java (original)
+++ sling/trunk/contrib/extensions/resourcemerger/src/main/java/org/apache/sling/resourcemerger/impl/picker/OverridingResourcePicker.java Wed Jan 14 22:36:57 2015
@@ -30,6 +30,7 @@ import org.apache.felix.scr.annotations.
 import org.apache.sling.api.resource.NonExistingResource;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.resourcemerger.impl.StubResource;
 import org.apache.sling.resourcemerger.spi.MergedResourcePicker;
 
 @Component(name = "org.apache.sling.resourcemerger.picker.overriding",
@@ -55,39 +56,42 @@ public class OverridingResourcePicker im
 
         Resource currentTarget = resolver.getResource(absPath);
 
-        if (currentTarget != null) {
-            resources.add(currentTarget);
+        if (currentTarget == null) {
+            currentTarget = new StubResource(resolver, absPath);
+        }
+
+        resources.add(currentTarget);
 
-            while (currentTarget != null) {
-                final Resource inheritanceRootResource = findInheritanceRoot(currentTarget);
-                if (inheritanceRootResource == null) {
+        while (currentTarget != null) {
+            final Resource inheritanceRootResource = findInheritanceRoot(currentTarget);
+            if (inheritanceRootResource == null) {
+                currentTarget = null;
+            } else {
+                final String relPath = currentTarget.getPath()
+                        .substring(inheritanceRootResource.getPath().length());
+                final String superType = inheritanceRootResource.getResourceSuperType();
+                if (superType == null) {
                     currentTarget = null;
                 } else {
-                    final String relPath = currentTarget.getPath()
-                            .substring(inheritanceRootResource.getPath().length());
-                    final String superType = inheritanceRootResource.getResourceSuperType();
-                    if (superType == null) {
-                        currentTarget = null;
+                    final String superTypeChildPath = superType + relPath;
+                    final Resource superTypeResource = resolver.getResource(superTypeChildPath);
+                    if (superTypeResource != null) {
+                        resources.add(superTypeResource);
+                        currentTarget = superTypeResource;
                     } else {
-                        final String superTypeChildPath = superType + relPath;
-                        final Resource superTypeResource = resolver.getResource(superTypeChildPath);
-                        if (superTypeResource != null) {
-                            resources.add(superTypeResource);
-                            currentTarget = superTypeResource;
-                        } else {
-                            resources.add(new NonExistingResource(resolver, superTypeChildPath));
-                            currentTarget = null;
-                        }
+                        resources.add(new NonExistingResource(resolver, superTypeChildPath));
+                        currentTarget = null;
                     }
                 }
             }
-
-            Collections.reverse(resources);
         }
+
+        Collections.reverse(resources);
+
         return resources;
     }
 
-    private Resource findInheritanceRoot(Resource target) {
+    private Resource findInheritanceRoot(final Resource target) {
         String superType = target.getResourceSuperType();
         if (superType != null) {
             return target;

Modified: sling/trunk/contrib/extensions/resourcemerger/src/test/java/org/apache/sling/resourcemerger/impl/OverridingResourceProviderTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/resourcemerger/src/test/java/org/apache/sling/resourcemerger/impl/OverridingResourceProviderTest.java?rev=1651858&r1=1651857&r2=1651858&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/resourcemerger/src/test/java/org/apache/sling/resourcemerger/impl/OverridingResourceProviderTest.java (original)
+++ sling/trunk/contrib/extensions/resourcemerger/src/test/java/org/apache/sling/resourcemerger/impl/OverridingResourceProviderTest.java Wed Jan 14 22:36:57 2015
@@ -52,8 +52,13 @@ public class OverridingResourceProviderT
      * /apps/a/1/a
      * /apps/a/1/b
      * /apps/a/1/b/1
+     * /apps/a/1/d
+     * /apps/a/1/d/1
+     * /apps/a/1/d/1/a
      * /apps/a/1/c
      * /apps/a/2/c
+     * 
+     * /apps/a/2 has the super type of /apps/a/1
      */
     @Before
     public void setup() throws Exception {
@@ -68,6 +73,9 @@ public class OverridingResourceProviderT
                     .resource("a").p("1", "a").p("2", "b")
                     .resource(".b").p("1", "a").p("2", "b")
                     .resource("1")
+                    .resource("/apps/a/1/d").p("a", "1").p("b", "2")
+                    .resource("1").p("1", "a").p("2", "b")
+                    .resource("a")
                     .resource("/apps/a/1/c").p("1", "a").p("2", "b")
                     .resource("/apps/a/2").p(SUPER_TYPE, "a/1").p("b", "2").p(MergedResourceConstants.PN_HIDE_CHILDREN, new String[] {"b"})
                     .resource("c").p("1", "c")
@@ -116,4 +124,31 @@ public class OverridingResourceProviderT
         assertNull(this.provider.getResource(this.resolver, "/override/apps/a/2/b/1"));
     }
 
+    // doing it this way because the mock resource resolver doesn't
+    // access the resource provider
+    private Resource getChildResource(Resource parent, String name) {
+        final Iterator<Resource> children = this.provider.listChildren(parent);
+        while (children.hasNext()) {
+            final Resource candidate = children.next();
+            if (candidate.getName().equals(name)) {
+               return candidate;
+            }
+        }
+        return null;
+    }
+
+    @Test
+    public void testOverriddenIncludesChildFromSuper() {
+        final Resource rsrcA2 = this.provider.getResource(this.resolver, "/override/apps/a/2");
+
+        Resource d = getChildResource(rsrcA2, "d");
+        assertNotNull(d);
+
+        Resource d1 = getChildResource(d, "1");
+        assertNotNull(d1);
+
+        Resource d1a = getChildResource(d1, "a");
+        assertNotNull(d1a);
+    }
+
 }