This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.resourcemerger-1.3.2
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-resourcemerger.git

commit ba2a044d65b8ce10358c5fb8cf12d6290af2d459
Author: Konrad Windszus <[email protected]>
AuthorDate: Fri Feb 12 09:45:19 2016 +0000

    SLNG-5468, make wildcards in sling:hideProperties and sling:hideChildren 
only act on inherited children/properties (not on the local ones) to allow to 
easily replace an existing resource
    
    git-svn-id: 
https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/resourcemerger@1729965
 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            |  27 ++-
 .../impl/CRUDMergingResourceProvider.java          |   2 +-
 .../sling/resourcemerger/impl/MergedValueMap.java  |  19 +-
 .../impl/MergingResourceProvider.java              |  73 +++++--
 .../impl/CommonMergedResourceProviderTest.java     | 241 +++++++++++++++++++++
 ...ergedResourceProviderTestForMergingPicker.java} |   8 +-
 ...edResourceProviderTestForOverridingPicker.java} |   2 +-
 7 files changed, 339 insertions(+), 33 deletions(-)

diff --git a/pom.xml b/pom.xml
index 77c8fb9..0ddc453 100644
--- a/pom.xml
+++ b/pom.xml
@@ -93,12 +93,30 @@
             <version>2.2.0</version>
             <scope>provided</scope>
         </dependency>
-    <!-- Testing -->
+        <!-- Testing -->
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-library</artifactId>
+            <version>1.3</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.hamcrest</artifactId>
+            <version>0.9.0-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.sling-mock</artifactId>
+            <version>1.6.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.apache.sling</groupId>
             
<artifactId>org.apache.sling.testing.resourceresolver-mock</artifactId>
             <version>1.1.12</version>
@@ -110,5 +128,12 @@
             <version>1.4.0</version>
             <scope>test</scope>
         </dependency>
+        <!-- only for IteratorIterable used in Tests -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-collections4</artifactId>
+            <version>4.1</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git 
a/src/main/java/org/apache/sling/resourcemerger/impl/CRUDMergingResourceProvider.java
 
b/src/main/java/org/apache/sling/resourcemerger/impl/CRUDMergingResourceProvider.java
index ff6407f..e900f4a 100644
--- 
a/src/main/java/org/apache/sling/resourcemerger/impl/CRUDMergingResourceProvider.java
+++ 
b/src/main/java/org/apache/sling/resourcemerger/impl/CRUDMergingResourceProvider.java
@@ -78,7 +78,7 @@ public class CRUDMergingResourceProvider
                 // check parent for hiding
                 // SLING 3521 : if parent is not readable, nothing is hidden
                 final Resource parent = rsrc.getParent();
-                hidden = (parent == null ? false : new 
ParentHidingHandler(parent, this.traverseHierarchie).isHidden(holder.name));
+                hidden = (parent == null ? false : new 
ParentHidingHandler(parent, this.traverseHierarchie).isHidden(holder.name, 
true));
             }
             if (hidden) {
                 holder.resources.clear();
diff --git 
a/src/main/java/org/apache/sling/resourcemerger/impl/MergedValueMap.java 
b/src/main/java/org/apache/sling/resourcemerger/impl/MergedValueMap.java
index d0bfe6b..1dfdac8 100644
--- a/src/main/java/org/apache/sling/resourcemerger/impl/MergedValueMap.java
+++ b/src/main/java/org/apache/sling/resourcemerger/impl/MergedValueMap.java
@@ -18,6 +18,7 @@
  */
 package org.apache.sling.resourcemerger.impl;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -51,28 +52,32 @@ public class MergedValueMap extends ValueMapDecorator {
      */
     public MergedValueMap(final List<ValueMap> valueMaps) {
         super(new HashMap<String, Object>());
+        
+        List<String> propertyNamesToHide = new 
ArrayList<String>(EXCLUDED_PROPERTIES);
+        
         // Iterate over value maps
         for (final ValueMap vm : valueMaps) {
-            // Add all properties
-            this.putAll(vm);
-
-            // Get properties to hide
+            // Get properties to hide from local or underlying value maps
             final String[] propertiesToHide = 
vm.get(MergedResourceConstants.PN_HIDE_PROPERTIES, String[].class);
             if ( propertiesToHide != null ) {
                 for (final String propName : propertiesToHide) {
                     if (propName.equals("*")) {
+                        // hiding by wildcard only hides the underlying 
properties (not the local ones)
                         this.clear();
                         break;
                     } else {
-                        this.remove(propName);
+                        propertyNamesToHide.add(propName);
                     }
                 }
             }
+            
+            // Add all local properties
+            this.putAll(vm);
         }
 
         // Hide excluded properties
-        for (final String excludedProperty : EXCLUDED_PROPERTIES) {
-            this.remove(excludedProperty);
+        for (final String propertyNameToHide : propertyNamesToHide) {
+            this.remove(propertyNameToHide);
         }
     }
 }
diff --git 
a/src/main/java/org/apache/sling/resourcemerger/impl/MergingResourceProvider.java
 
b/src/main/java/org/apache/sling/resourcemerger/impl/MergingResourceProvider.java
index 3224b67..81d3a3c 100644
--- 
a/src/main/java/org/apache/sling/resourcemerger/impl/MergingResourceProvider.java
+++ 
b/src/main/java/org/apache/sling/resourcemerger/impl/MergingResourceProvider.java
@@ -55,8 +55,10 @@ public class MergingResourceProvider extends 
ResourceProvider<Void> {
 
         public final String name;
         public final boolean exclude;
+        public final boolean onlyUnderlying; // if only underlying resources 
should be affected (and not the local ones)
 
-        public ExcludeEntry(final String value) {
+        public ExcludeEntry(final String value, boolean onlyUnderlying) {
+            this.onlyUnderlying = onlyUnderlying;
             if ( value.startsWith("!!") ) {
                 this.name = value.substring(1);
                 this.exclude = false;
@@ -78,15 +80,28 @@ public class MergingResourceProvider extends 
ResourceProvider<Void> {
 
         private List<ExcludeEntry> entries = new ArrayList<ExcludeEntry>();
 
+        /**
+         * 
+         * @param parent the underlying resource
+         * @param traverseParent
+         */
         public ParentHidingHandler(final Resource parent, final boolean 
traverseParent) {
+            // evaluate the sling:hideChildren property on the current resource
             final ValueMap parentProps = parent.getValueMap();
             final String[] childrenToHideArray = 
parentProps.get(MergedResourceConstants.PN_HIDE_CHILDREN, String[].class);
             if (childrenToHideArray != null) {
                 for (final String value : childrenToHideArray) {
-                    final ExcludeEntry entry = new ExcludeEntry(value);
+                    final boolean onlyUnderlying;
+                    if (value.equals("*")) {
+                        onlyUnderlying = true;
+                    } else {
+                        onlyUnderlying = false;
+                    }
+                    final ExcludeEntry entry = new ExcludeEntry(value, 
onlyUnderlying);
                     this.entries.add(entry);
                 }
             }
+            // also check on the parent's parent whether that was hiding the 
parent
             if (parent != null) {
                 Resource ancestor = parent.getParent();
                 String previousAncestorName = parent.getName();
@@ -95,10 +110,10 @@ public class MergingResourceProvider extends 
ResourceProvider<Void> {
                     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);
+                            final ExcludeEntry entry = new ExcludeEntry(value, 
false);
+                            final Boolean hides = hides(entry, 
previousAncestorName, true);
                             if (hides != null && hides.booleanValue() == true) 
{
-                                this.entries.add(new ExcludeEntry("*"));
+                                this.entries.add(new ExcludeEntry("*", false));
                                 break;
                             }
                         }
@@ -112,11 +127,17 @@ public class MergingResourceProvider extends 
ResourceProvider<Void> {
             }
         }
 
-        public boolean isHidden(final String name) {
+        /**
+         * 
+         * @param name the name of the resource to check
+         * @param isLocalResource {@code true} if the check is on a local 
resource, {@code false} if the check is on an underlying/inherited resource
+         * @return {@code true} if the local/inherited resource should be 
hidden, otherwise {@code false}
+         */
+        public boolean isHidden(final String name, boolean isLocalResource) {
             boolean hidden = false;
             if ( this.entries != null ) {
                 for(final ExcludeEntry entry : this.entries) {
-                    Boolean result = hides(entry, name);
+                    Boolean result = hides(entry, name, isLocalResource);
                     if (result != null) {
                         hidden = result.booleanValue();
                         break;
@@ -131,10 +152,12 @@ public class MergingResourceProvider extends 
ResourceProvider<Void> {
          *
          * @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) {
+        private Boolean hides(final ExcludeEntry entry, final String name, 
boolean isLocalResource) {
             Boolean result = null;
             if (entry.name.equals("*") || entry.name.equals(name)) {
-                result = Boolean.valueOf(!entry.exclude);
+                if ((isLocalResource && !entry.onlyUnderlying) || 
!isLocalResource) {
+                    result = Boolean.valueOf(!entry.exclude);
+                }
             }
             return result;
         }
@@ -238,9 +261,9 @@ public class MergingResourceProvider extends 
ResourceProvider<Void> {
                     isUnderlying = false;
                 } else {
                     // check parent for hiding
-                    // SLING 3521 : if parent is not readable, nothing is 
hidden
+                    // SLING-3521 : if parent is not readable, nothing is 
hidden
                     final Resource resourceParent = resource.getParent();
-                    hidden = resourceParent != null && new 
ParentHidingHandler(resourceParent, 
this.traverseHierarchie).isHidden(holder.name);
+                    hidden = resourceParent != null && new 
ParentHidingHandler(resourceParent, 
this.traverseHierarchie).isHidden(holder.name, true);
 
                     // TODO Usually, the parent does not exist if the resource 
is a NonExistingResource. Ideally, this
                     // common case should be optimised
@@ -277,9 +300,21 @@ public class MergingResourceProvider extends 
ResourceProvider<Void> {
                 final ParentHidingHandler handler = !isUnderlying ? new 
ParentHidingHandler(parentResource, this.traverseHierarchie) : null;
                 isUnderlying = false;
 
+                // remove the hidden child resources from the underlying 
resource
+                if (handler != null) {
+                    final Iterator<ResourceHolder> iter = 
candidates.iterator();
+                    while (iter.hasNext()) {
+                        final ResourceHolder holder = iter.next();
+                        if (handler.isHidden(holder.name, false)) {
+                            iter.remove();
+                        }
+                    }
+                }
+                
                 for (final Resource child : parentResource.getChildren()) {
                     final String rsrcName = child.getName();
                     ResourceHolder holder = null;
+                    // check if is this an overlaid resource (i.e. has the 
resource with the same name already be exposed through the underlying resource)
                     for (final ResourceHolder current : candidates) {
                         if (current.name.equals(rsrcName)) {
                             holder = current;
@@ -287,9 +322,13 @@ public class MergingResourceProvider extends 
ResourceProvider<Void> {
                         }
                     }
                     if (holder == null) {
+                        // remove the hidden child resources from the local 
resource
+                        if (handler != null && handler.isHidden(rsrcName, 
true)) {
+                            continue; // skip this child
+                        }
                         holder = new ResourceHolder(rsrcName);
                         candidates.add(holder);
-                    }
+                    } 
                     holder.resources.add(child);
 
                     // Check if children need reordering
@@ -314,15 +353,7 @@ public class MergingResourceProvider extends 
ResourceProvider<Void> {
                         candidates.remove(candidates.size() - 1);
                     }
                 }
-                if (handler != null) {
-                    final Iterator<ResourceHolder> iter = 
candidates.iterator();
-                    while (iter.hasNext()) {
-                        final ResourceHolder holder = iter.next();
-                        if (handler.isHidden(holder.name)) {
-                            iter.remove();
-                        }
-                    }
-                }
+                
             }
             final List<Resource> children = new ArrayList<Resource>();
             for (final ResourceHolder holder : candidates) {
diff --git 
a/src/test/java/org/apache/sling/resourcemerger/impl/CommonMergedResourceProviderTest.java
 
b/src/test/java/org/apache/sling/resourcemerger/impl/CommonMergedResourceProviderTest.java
new file mode 100644
index 0000000..28403e4
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/resourcemerger/impl/CommonMergedResourceProviderTest.java
@@ -0,0 +1,241 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections4.iterators.IteratorIterable;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.ModifiableValueMap;
+import org.apache.sling.api.resource.NonExistingResource;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.hamcrest.ResourceMatchers;
+import org.apache.sling.resourcemerger.spi.MergedResourcePicker2;
+import org.apache.sling.spi.resource.provider.ResolveContext;
+import org.apache.sling.spi.resource.provider.ResourceContext;
+import org.apache.sling.testing.resourceresolver.MockHelper;
+import org.apache.sling.testing.resourceresolver.MockResourceResolverFactory;
+import org.hamcrest.Matchers;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests common merging behaviour (independent of actual picker implementation)
+ *
+ */
+public class CommonMergedResourceProviderTest {
+
+    private ResourceResolver resolver;
+
+    private MergingResourceProvider provider;
+
+    private Resource base;
+    private Resource overlay;
+
+    private ResolveContext<Void> ctx;
+
+    /**
+     * A very simple resource picker which will just merge two different 
resources (base and overlay) directly on the mount point.
+     * Supports also merging of arbitrary child resources below the mount 
point.
+     */
+    private final class SimpleMergedResourcePicker implements 
MergedResourcePicker2 {
+
+        private final List<Resource> rootResourcesToMerge;
+
+        public SimpleMergedResourcePicker() {
+            rootResourcesToMerge = new ArrayList<Resource>();
+            rootResourcesToMerge.add(base);
+            rootResourcesToMerge.add(overlay);
+        }
+
+        @Override
+        public List<Resource> pickResources(ResourceResolver resolver, String 
relativePath, Resource relatedResource) {
+            // merging in the root path is always successfull
+            if (relativePath.isEmpty()) {
+                return rootResourcesToMerge;
+            } else {
+                List<Resource> resourcesToMerge = new ArrayList<Resource>();
+                // if deeper merging is wanted, check in both locations if the 
relative path is available at all
+                Resource resourceToPick = base.getChild(relativePath);
+                if (resourceToPick != null) {
+                    resourcesToMerge.add(resourceToPick); 
+                } else {
+                    resourcesToMerge.add(new NonExistingResource(resolver, 
base.getPath() + "/" + relativePath));
+                }
+                resourceToPick = overlay.getChild(relativePath);
+                if (resourceToPick != null) {
+                    resourcesToMerge.add(resourceToPick); 
+                } else {
+                    resourcesToMerge.add(new NonExistingResource(resolver, 
overlay.getPath() + "/" + relativePath));
+                }
+                return resourcesToMerge;
+            }
+        }
+    }
+
+    @Before
+    public void setup() throws LoginException, PersistenceException {
+        final ResourceResolverFactory factory = new 
MockResourceResolverFactory();
+        this.resolver = factory.getResourceResolver(null);
+        this.ctx = new BasicResolveContext<Void>(resolver);
+        MockHelper.create(this.resolver)
+        .resource("/apps").resource("base")
+        .resource("/apps/overlay").commit();
+        
+        base = this.resolver.getResource("/apps/base");
+        overlay = this.resolver.getResource("/apps/overlay");
+        
+        this.provider = new CRUDMergingResourceProvider("/merged", new 
SimpleMergedResourcePicker(), false);
+    }
+
+    @Test
+    public void testHideChildren() throws PersistenceException {
+        // create new child nodes below base and overlay
+        MockHelper.create(this.resolver)
+            .resource("/apps/base/child1").p("property1", "frombase")
+            .resource("/apps/base/child2").p("property1", "frombase")
+            .resource("/apps/overlay/child1").p("property1", "fromoverlay")
+            .resource("/apps/overlay/child3").p("property1", "fromoverlay")
+            .commit();
+        
+        ModifiableValueMap properties = 
overlay.adaptTo(ModifiableValueMap.class);
+        properties.put(MergedResourceConstants.PN_HIDE_CHILDREN, "*");
+        resolver.commit();
+        
+        Resource mergedResource = this.provider.getResource(ctx, "/merged", 
ResourceContext.EMPTY_CONTEXT, null);
+        
+        // convert the iterator returned by list children into an iterable (to 
be able to perform some tests)
+        IteratorIterable<Resource> iterable = new 
IteratorIterable<Resource>(provider.listChildren(ctx, mergedResource), true);
+        
+        // all overlay resource are still exposed, because hiding children by 
wildcard only hides children from underlying resources
+        Assert.assertThat(iterable, Matchers.containsInAnyOrder(
+                ResourceMatchers.resourceWithNameAndProps("child1", 
Collections.singletonMap("property1", (Object)"fromoverlay")),
+                ResourceMatchers.resourceWithNameAndProps("child3", 
Collections.singletonMap("property1", (Object)"fromoverlay"))
+        ));
+        
+        // now hide by explicit value
+        properties.put(MergedResourceConstants.PN_HIDE_CHILDREN, "child1");
+        resolver.commit();
+        
+        // child1 is no longer exposed from overlay, because hiding children 
by name hides children from underlying as well as from local resources, child2 
is exposed from base
+        iterable = new IteratorIterable<Resource>(provider.listChildren(ctx, 
mergedResource), true);
+        Assert.assertThat(iterable, Matchers.containsInAnyOrder(
+                ResourceMatchers.resourceWithName("child2"),
+                ResourceMatchers.resourceWithName("child3")));
+        
+        // now hide by negated value (hide all underlying children except for 
the one with name child2)
+        properties.put(MergedResourceConstants.PN_HIDE_CHILDREN, new 
String[]{"!child2", "*", "child3"});
+        resolver.commit();
+        
+        iterable = new IteratorIterable<Resource>(provider.listChildren(ctx, 
mergedResource), true);
+        Assert.assertThat(iterable, Matchers.containsInAnyOrder(
+                ResourceMatchers.resourceWithName("child2"), 
+                ResourceMatchers.resourceWithNameAndProps("child1", 
Collections.singletonMap("property1", (Object)"fromoverlay"))
+        ));
+    }
+
+    @Test
+    public void testHideChildrenWithResourceNamesStartingWithExclamationMark() 
throws PersistenceException {
+        // create new child nodes below base and overlay
+        MockHelper.create(this.resolver)
+            .resource("/apps/base/!child1").p("property1", "frombase")
+            .resource("/apps/overlay/!child1").p("property1", "fromoverlay")
+            .resource("/apps/overlay/!child3").p("property1", "fromoverlay")
+            .commit();
+        
+        ModifiableValueMap properties = 
overlay.adaptTo(ModifiableValueMap.class);
+        properties.put(MergedResourceConstants.PN_HIDE_CHILDREN, "!!child3"); 
// escape the resource name with another exclamation mark
+        resolver.commit();
+        
+        Resource mergedResource = this.provider.getResource(ctx, "/merged", 
ResourceContext.EMPTY_CONTEXT, null);
+        
+        // convert the iterator returned by list children into an iterable (to 
be able to perform some tests)
+        IteratorIterable<Resource> iterable = new 
IteratorIterable<Resource>(provider.listChildren(ctx, mergedResource), true);
+        
+        // the resource named "!child3" should be hidden
+        Assert.assertThat(iterable, 
Matchers.contains(ResourceMatchers.resourceWithNameAndProps("!child1", 
Collections.singletonMap("property1", (Object)"fromoverlay"))));
+    }
+
+    @Test
+    public void testHideChildrenBeingSetOnParent() throws PersistenceException 
{
+        // create new child nodes below base and overlay
+        MockHelper.create(this.resolver)
+            .resource("/apps/base/child").p("property1", 
"frombase").resource("grandchild").p("property1", "frombase")
+            .resource("/apps/base/child2").p("property1", "frombase")
+            .resource("/apps/overlay/child").p("property1", "fromoverlay")
+            .commit();
+        
+        ModifiableValueMap properties = 
overlay.adaptTo(ModifiableValueMap.class);
+        properties.put(MergedResourceConstants.PN_HIDE_CHILDREN, "*");
+        resolver.commit();
+        
+        Resource mergedResource = this.provider.getResource(ctx, "/merged", 
ResourceContext.EMPTY_CONTEXT, null);
+        
+        // the child was hidden on the parent (but only for the underlying 
resource), the local child from the overlay is still exposed
+        Assert.assertThat(provider.getResource(ctx, "/merged/child", 
ResourceContext.EMPTY_CONTEXT, mergedResource), 
ResourceMatchers.resourceWithNameAndProps("child", 
Collections.singletonMap("property1", (Object)"fromoverlay")));
+    }
+
+    @Test
+    public void testHideProperties() {
+        ModifiableValueMap properties = base.adaptTo(ModifiableValueMap.class);
+        properties.put("property1", "frombase");
+        properties.put("property2", "frombase");
+        properties.put(MergedResourceConstants.PN_HIDE_CHILDREN, "some invalid 
resource");
+        
+        // hide with wildcard
+        ModifiableValueMap overlayProperties = 
overlay.adaptTo(ModifiableValueMap.class);
+        overlayProperties.put(MergedResourceConstants.PN_HIDE_PROPERTIES, "*");
+        Map<String, Object> expectedProperties = new HashMap<String, Object>();
+        expectedProperties.put("property1", "fromoverlay");
+        expectedProperties.put("property3", "fromoverlay");
+        overlayProperties.putAll(expectedProperties);
+        this.provider = new CRUDMergingResourceProvider("/merged", new 
SimpleMergedResourcePicker(), false);
+        
+        Resource mergedResource = this.provider.getResource(ctx, "/merged", 
ResourceContext.EMPTY_CONTEXT, null);
+        // property1 is still exposed from overlay, because hiding properties 
by wildcard only hides children from underlying resources
+        Assert.assertThat(mergedResource, 
ResourceMatchers.resourceWithProps(expectedProperties));
+        // all properties from underlying resource are hidden!
+        Assert.assertThat(mergedResource, 
Matchers.not(ResourceMatchers.resourceWithProps(properties)));
+        // make sure no special properties are exposed
+        
Assert.assertFalse(mergedResource.getValueMap().containsKey(MergedResourceConstants.PN_HIDE_CHILDREN));
+        
Assert.assertFalse(mergedResource.getValueMap().containsKey(MergedResourceConstants.PN_HIDE_PROPERTIES));
+        
+        // hide by value
+        overlayProperties.put(MergedResourceConstants.PN_HIDE_PROPERTIES, new 
String[]{"property1"});
+        mergedResource = this.provider.getResource(ctx, "/merged", 
ResourceContext.EMPTY_CONTEXT, null);
+        expectedProperties.put("property2", "frombase");
+        expectedProperties.remove("property1");
+        // property2 and property 3 are still exposed
+        Assert.assertThat(mergedResource, 
ResourceMatchers.resourceWithProps(expectedProperties));
+        // property1 is no longer exposed from overlay nor base, because 
hiding properties by name also hides local properties
+        Assert.assertThat(mergedResource, 
Matchers.not(ResourceMatchers.resourceWithProps(Collections.singletonMap("property1",
 (Object)"fromoverlay"))));
+        
+        // make sure no special properties are exposed
+        
Assert.assertFalse(mergedResource.getValueMap().containsKey(MergedResourceConstants.PN_HIDE_CHILDREN));
+        
Assert.assertFalse(mergedResource.getValueMap().containsKey(MergedResourceConstants.PN_HIDE_PROPERTIES));
+    }
+}
diff --git 
a/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTest.java
 
b/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTestForMergingPicker.java
similarity index 98%
rename from 
src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTest.java
rename to 
src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTestForMergingPicker.java
index e22fd1f..f6de9ec 100644
--- 
a/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTest.java
+++ 
b/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTestForMergingPicker.java
@@ -44,7 +44,7 @@ import 
org.apache.sling.testing.resourceresolver.MockResourceResolverFactoryOpti
 import org.junit.Before;
 import org.junit.Test;
 
-public class MergedResourceProviderTest {
+public class MergedResourceProviderTestForMergingPicker {
 
     private ResourceResolver resolver;
 
@@ -169,7 +169,11 @@ public class MergedResourceProviderTest {
         final Resource rsrcA3 = this.provider.getResource(ctx, "/merged/a/3", 
ResourceContext.EMPTY_CONTEXT, null);
         final ValueMap vm = rsrcA3.adaptTo(ValueMap.class);
         assertNotNull(vm);
-        assertEquals(0, vm.size());
+        // only the properties from the underlying resource should have been 
cleared (i.e. the ones from /libs)
+        assertEquals(3, vm.size());
+        assertEquals("2", vm.get("e"));
+        assertEquals("x", vm.get("b"));
+        assertEquals("1", vm.get("d"));
     }
 
     @Test public void testHideProperties() {
diff --git 
a/src/test/java/org/apache/sling/resourcemerger/impl/OverridingResourceProviderTest.java
 
b/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTestForOverridingPicker.java
similarity index 99%
rename from 
src/test/java/org/apache/sling/resourcemerger/impl/OverridingResourceProviderTest.java
rename to 
src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTestForOverridingPicker.java
index 1ac9157..489ac01 100644
--- 
a/src/test/java/org/apache/sling/resourcemerger/impl/OverridingResourceProviderTest.java
+++ 
b/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTestForOverridingPicker.java
@@ -40,7 +40,7 @@ import 
org.apache.sling.testing.resourceresolver.MockResourceResolverFactoryOpti
 import org.junit.Before;
 import org.junit.Test;
 
-public class OverridingResourceProviderTest {
+public class MergedResourceProviderTestForOverridingPicker {
 
     private static final String SUPER_TYPE = "sling:resourceSuperType";
 

-- 
To stop receiving notification emails like this one, please contact
"[email protected]" <[email protected]>.

Reply via email to