You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 09:59:29 UTC

[sling-org-apache-sling-resourcemerger] 12/23: SLING-3909 : Merged ResourceProviders should be optionally modifiable

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

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

commit b355a9589e61256905e59c02c0ae9b5bf020b5e4
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Sat Sep 13 13:35:37 2014 +0000

    SLING-3909 : Merged ResourceProviders should be optionally modifiable
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/resourcemerger@1624735 13f79535-47bb-0310-9956-ffa450edef68
---
 .../resourcemerger/impl/CRUDMergedResource.java    | 105 ++++++++++++++++++++-
 .../impl/MergedResourceProviderTest.java           |  52 ++++++++++
 2 files changed, 154 insertions(+), 3 deletions(-)

diff --git a/src/main/java/org/apache/sling/resourcemerger/impl/CRUDMergedResource.java b/src/main/java/org/apache/sling/resourcemerger/impl/CRUDMergedResource.java
index f662c02..756a722 100644
--- a/src/main/java/org/apache/sling/resourcemerger/impl/CRUDMergedResource.java
+++ b/src/main/java/org/apache/sling/resourcemerger/impl/CRUDMergedResource.java
@@ -18,8 +18,12 @@
  */
 package org.apache.sling.resourcemerger.impl;
 
+import java.util.Collection;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import org.apache.sling.api.resource.ModifiableValueMap;
 import org.apache.sling.api.resource.PersistenceException;
@@ -27,6 +31,8 @@ import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceUtil;
 import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.wrappers.DeepReadValueMapDecorator;
+import org.apache.sling.api.wrappers.ValueMapDecorator;
 import org.apache.sling.resourcemerger.spi.MergedResourcePicker;
 
 /**
@@ -75,14 +81,107 @@ public class CRUDMergedResource extends MergedResource {
                 final Resource copyResource = this.getResourceResolver().getResource(paths[paths.length - 1]);
                 try {
                     final Resource newResource = ResourceUtil.getOrCreateResource(this.getResourceResolver(), highestRsrc.getPath(), copyResource.getResourceType(), null, false);
-                    return (AdapterType)newResource.adaptTo(ModifiableValueMap.class);
+                    final ModifiableValueMap target = newResource.adaptTo(ModifiableValueMap.class);
+                    if ( target != null ) {
+                        return (AdapterType)new ModifiableProperties(this, target);
+                    }
                 } catch ( final PersistenceException pe) {
                     // we ignore this for now
-                    return null;
                 }
+                return super.adaptTo(type);
+            }
+            final ModifiableValueMap target = highestRsrc.adaptTo(ModifiableValueMap.class);
+            if ( target != null ) {
+                return (AdapterType)new ModifiableProperties(this, target);
             }
-            return (AdapterType)highestRsrc.adaptTo(ModifiableValueMap.class);
         }
         return super.adaptTo(type);
     }
+
+    private static final class ModifiableProperties implements ModifiableValueMap {
+
+        private final ModifiableValueMap targetMap;
+
+        private final ValueMap properties;
+
+        public ModifiableProperties(final Resource rsrc, final ModifiableValueMap targetMap) {
+            this.properties = new DeepReadValueMapDecorator(rsrc, new ValueMapDecorator(new HashMap<String, Object>(rsrc.getValueMap())));
+            this.targetMap = targetMap;
+        }
+
+        public <T> T get(final String name, final Class<T> type) {
+            return properties.get(name, type);
+        }
+
+        public <T> T get(final String name, final T defaultValue) {
+            return properties.get(name, defaultValue);
+        }
+
+        public int size() {
+            return properties.size();
+        }
+
+        public boolean isEmpty() {
+            return properties.isEmpty();
+        }
+
+        public boolean containsKey(final Object key) {
+            return properties.containsKey(key);
+        }
+
+        public boolean containsValue(final Object value) {
+            return properties.containsValue(value);
+        }
+
+        public Object get(final Object key) {
+            return properties.get(key);
+        }
+
+        public Object put(final String key, final Object value) {
+            final Object result = this.properties.get(key);
+            this.targetMap.put(key, value);
+            return result;
+        }
+
+        public Object remove(final Object key) {
+            final Object result = this.properties.get(key);
+            if ( this.targetMap.remove(key) == null ) {
+                final String[] hiddenProps = this.targetMap.get(MergedResourceConstants.PN_HIDE_PROPERTIES, String[].class);
+                final String[] newHiddenProps;
+                if ( hiddenProps == null || hiddenProps.length == 0 ) {
+                    newHiddenProps = new String[] {key.toString()};
+                } else {
+                    newHiddenProps = new String[hiddenProps.length + 1];
+                    System.arraycopy(hiddenProps, 0, newHiddenProps, 0, hiddenProps.length);
+                    newHiddenProps[hiddenProps.length] = key.toString();
+                }
+                this.targetMap.put(MergedResourceConstants.PN_HIDE_PROPERTIES, newHiddenProps);
+            }
+            return result;
+        }
+
+        public void putAll(final Map<? extends String, ? extends Object> m) {
+            if ( m != null ) {
+                for(final Map.Entry<? extends String, ? extends Object> entry : m.entrySet()) {
+                    this.put(entry.getKey(), entry.getValue());
+                }
+            }
+        }
+
+        public void clear() {
+            // not supported
+        }
+
+        public Set<String> keySet() {
+            return this.properties.keySet();
+        }
+
+        public Collection<Object> values() {
+            return this.properties.values();
+        }
+
+        public Set<Entry<String, Object>> entrySet() {
+            return this.properties.entrySet();
+        }
+    }
 }
diff --git a/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTest.java b/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTest.java
index cded41b..30fe6e4 100644
--- a/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTest.java
+++ b/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderTest.java
@@ -28,6 +28,7 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 
+import org.apache.sling.api.resource.ModifiableValueMap;
 import org.apache.sling.api.resource.PersistenceException;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
@@ -66,6 +67,7 @@ public class MergedResourceProviderTest {
                                             .resource(".X")
                                         .resource("/libs")
                                           .resource("deleteTest")
+                                          .resource(".mvmTest").p("a", "1").p("b", "2")
                                           .resource(".a")
                                             .resource("1").p("a", "5").p("c", "2")
                                             .resource(".2").p(ResourceResolver.PROPERTY_RESOURCE_TYPE, "libs")
@@ -228,4 +230,54 @@ public class MergedResourceProviderTest {
             this.resolver.revert();
         }
     }
+
+    @Test public void testModifiableValueMap() throws PersistenceException {
+        final String path = "/merged/mvmTest";
+        try {
+            assertNotNull(this.resolver.getResource("/libs/mvmTest"));
+            assertNull(this.resolver.getResource("/apps/mvmTest"));
+
+            final Resource rsrc = this.provider.getResource(this.resolver, path);
+            assertNotNull(rsrc);
+            final ValueMap beforeVM = rsrc.getValueMap();
+            assertEquals("1", beforeVM.get("a"));
+            assertEquals("2", beforeVM.get("b"));
+
+            final ModifiableValueMap mvm = rsrc.adaptTo(ModifiableValueMap.class);
+            assertNotNull(mvm);
+            assertEquals("1", mvm.get("a"));
+            assertEquals("2", mvm.get("b"));
+
+            mvm.put("c", "3");
+            mvm.remove("a");
+
+            assertNotNull(this.resolver.getResource("/libs/mvmTest"));
+            assertNotNull(this.resolver.getResource("/apps/mvmTest"));
+
+            final Resource rsrc2 = this.provider.getResource(this.resolver, path);
+            assertNotNull(rsrc2);
+            final ValueMap afterVM = rsrc2.getValueMap();
+            assertNull(afterVM.get("a"));
+            assertEquals("2", afterVM.get("b"));
+            assertEquals("3", afterVM.get("c"));
+
+            final Resource rsrcL = this.resolver.getResource("/libs/mvmTest");
+            assertEquals("1", rsrcL.getValueMap().get("a"));
+            assertEquals("2", rsrcL.getValueMap().get("b"));
+            assertNull(rsrcL.getValueMap().get("c"));
+
+            final Resource rsrcA = this.resolver.getResource("/apps/mvmTest");
+            assertNull(rsrcA.getValueMap().get("a"));
+            assertNull(rsrcA.getValueMap().get("b"));
+            assertEquals("3", rsrcA.getValueMap().get("c"));
+            final String[] hidden = rsrcA.getValueMap().get(MergedResourceConstants.PN_HIDE_PROPERTIES, String[].class);
+            assertNotNull(hidden);
+            assertEquals(1, hidden.length);
+            assertEquals("a", hidden[0]);
+
+        } finally {
+            this.resolver.revert();
+        }
+
+    }
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.