You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ss...@apache.org on 2016/09/19 15:39:18 UTC

svn commit: r1761468 [3/4] - in /sling/trunk/contrib/extensions/contextaware-config: api/ api/src/main/java/org/apache/sling/contextaware/config/ api/src/main/java/org/apache/sling/contextaware/config/resource/spi/ api/src/main/java/org/apache/sling/co...

Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/resource/impl/def/WebConsolePlugin.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/resource/impl/def/WebConsolePlugin.java?rev=1761468&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/resource/impl/def/WebConsolePlugin.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/resource/impl/def/WebConsolePlugin.java Mon Sep 19 15:39:17 2016
@@ -0,0 +1,287 @@
+/*
+ * 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.contextaware.config.resource.impl.def;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.felix.webconsole.AbstractWebConsolePlugin;
+import org.apache.felix.webconsole.WebConsoleConstants;
+import org.apache.sling.api.resource.LoginException;
+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.contextaware.config.resource.impl.ConfigurationResourceResolverImpl;
+import org.apache.sling.contextaware.config.resource.spi.ConfigurationResourceResolvingStrategy;
+import org.apache.sling.xss.XSSAPI;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
+
+// TODO: this web console plugin is currently quite broken and needs to be refactored and moved to another package
+@Component(service=Servlet.class,
+           property={"org.osgi.framework.Constants.SERVICE_DESCRIPTION=Apache Sling Web Console Plugin for configurations",
+                   WebConsoleConstants.PLUGIN_LABEL + "=" + WebConsolePlugin.LABEL,
+                   WebConsoleConstants.PLUGIN_TITLE + "=" + WebConsolePlugin.TITLE})
+@SuppressWarnings("serial")
+public class WebConsolePlugin extends AbstractWebConsolePlugin {
+
+    public static final String LABEL = "configresolver";
+    public static final String TITLE = "Config Resolver";
+
+    @Reference(policyOption = ReferencePolicyOption.GREEDY)
+    private ResourceResolverFactory resolverFactory;
+
+    @Reference(policyOption = ReferencePolicyOption.GREEDY)
+    private ConfigurationResourceResolvingStrategy configResolver;
+
+    @Reference(policyOption = ReferencePolicyOption.GREEDY)
+    private XSSAPI xssAPI;
+
+    @Override
+    public String getLabel() {
+        return LABEL;
+    }
+
+    @Override
+    public String getTitle() {
+        return TITLE;
+    }
+
+    @Override
+    protected void renderContent(HttpServletRequest request, HttpServletResponse response)
+        throws ServletException, IOException {
+
+        final PrintWriter pw = response.getWriter();
+
+        info(pw, "Configurations are managed in the resource tree. Use this tool to test configuration resolutions.");
+
+        printConfiguration(pw);
+
+        pw.println("<br/>");
+
+        printResolutionTestTool(request, pw);
+    }
+
+    private void printConfiguration(final PrintWriter pw) {
+        final DefaultConfigurationResourceResolvingStrategy configResolverImpl = (DefaultConfigurationResourceResolvingStrategy)configResolver;
+        tableStart(pw, "Configuration", 2);
+        pw.println("<tr>");
+        pw.println("<td style='width:20%'>Allowed paths</td>");
+        pw.print("<td>");
+        pw.print(xssAPI.encodeForHTML(Arrays.toString(configResolverImpl.getConfiguration().allowedPaths())));
+        pw.println("</td>");
+        pw.println("</tr>");
+        pw.println("<tr>");
+        pw.println("<td style='width:20%'>Fallback paths</td>");
+        pw.print("<td>");
+        pw.print(xssAPI.encodeForHTML(Arrays.toString(configResolverImpl.getConfiguration().fallbackPaths())));
+        pw.println("</td>");
+        pw.println("</tr>");
+        pw.println("<tr>");
+        pw.println("<td></td>");
+        pw.println("<td>");
+        pw.print("<form method='get' action='${appRoot}/confMgr/");
+        pw.print(ConfigurationResourceResolverImpl.class.getName());
+        pw.println("'>");
+        pw.println("<input type='submit' value='Configure'/>");
+        pw.println("</form>");
+        pw.println("</td>");
+        pw.println("</tr>");
+        tableEnd(pw);
+    }
+
+    private String getParameter(final HttpServletRequest request, final String name, final String defaultValue) {
+        String value = request.getParameter(name);
+        if ( value != null && !value.trim().isEmpty() ) {
+            return value.trim();
+        }
+        return defaultValue;
+    }
+
+    private void printResolutionTestTool(HttpServletRequest request, PrintWriter pw) {
+        final String path = this.getParameter(request, "path", null);
+        final String item = this.getParameter(request, "item", ".");
+        final String user = this.getParameter(request, "user", null);
+
+        ResourceResolver resolver = null;
+        try {
+            Resource content = null;
+            if (path != null) {
+                resolver = getResolver(user);
+                if (resolver != null) {
+                    content = resolver.getResource(path);
+                }
+            }
+
+            pw.println("<form method='get'>");
+
+            tableStart(pw, "Test Configuration Resolution", 2);
+            pw.println("<td style='width:20%'>Content Path</td>");
+            pw.print("<td><input name='path' value='");
+            pw.print(xssAPI.encodeForHTMLAttr(StringUtils.defaultString(path)));
+            pw.println("' style='width:100%'/>");
+            if (resolver != null && content == null) {
+                pw.println("<div>");
+                pw.println("<span class='ui-icon ui-icon-alert' style='float:left'></span>");
+                pw.println("<span style='float:left'>Path does not exist.</span>");
+                pw.println("</div>");
+            }
+            pw.println("</td>");
+
+            tableRows(pw);
+            pw.println("<td>Item</td>");
+            pw.print("<td><input name='item' value='");
+            pw.print(xssAPI.encodeForHTMLAttr(item));
+            pw.println("' style='width:100%'/></td>");
+            tableRows(pw);
+
+            pw.println("<td>User</td>");
+            pw.println("<td><input name='user' value='");
+            pw.print(xssAPI.encodeForHTMLAttr(StringUtils.defaultString(user)));
+            pw.println("' style='width:50%'/>");
+            if (path != null && resolver == null) {
+                pw.println("<div>");
+                pw.println("<span class='ui-icon ui-icon-alert' style='float:left'></span>");
+                pw.println("<span style='float:left'>User does not exist.</span>");
+                pw.println("</div>");
+            }
+            pw.println("</td>");
+            tableRows(pw);
+
+            pw.println("<td></td>");
+            pw.println("<td><input type='submit' value='Resolve'/></td>");
+            tableEnd(pw);
+
+            pw.println("</form>");
+
+            pw.println("<br/>");
+
+            if (content != null) {
+
+                // TODO: use sensible bucket name or make it configurable
+                final Resource confRsrc = configResolver.getResource(content, "sling:configs", item);
+
+                tableStart(pw, "Resolved", 2);
+                pw.println("<td style='width:20%'>Code</td>");
+                pw.println("<td>");
+                pw.print("<code>resolve(\"");
+                pw.print(xssAPI.encodeForHTML(content.getPath()));
+                pw.print("\", \"");
+                pw.print(xssAPI.encodeForHTML(item));
+                pw.println("\")</code>");
+                pw.println("<br/>&nbsp;");
+                pw.println("</td>");
+                tableRows(pw);
+
+                pw.println("<td style='width:20%'>Item</td>");
+                if (confRsrc != null) {
+                    pw.print("<td>");
+                    pw.print(xssAPI.encodeForHTML(confRsrc.getPath()));
+                    pw.println("<br/>&nbsp;</td>");
+                } else {
+                    pw.println("<td>");
+                    pw.println("<div>");
+                    pw.println("<span class='ui-icon ui-icon-alert' style='float:left'></span>");
+                    pw.println("<span style='float:left'>No matching item found.</span>");
+                    pw.println("</div>");
+                    pw.println("<br/>&nbsp;</td>");
+                }
+                tableRows(pw);
+
+                pw.println("<td>Config paths</td>");
+
+                pw.println("<td>");
+                Iterator<String> paths = ((DefaultConfigurationResourceResolvingStrategy)configResolver).getResolvePaths(content);
+                while (paths.hasNext()) {
+                    String p = paths.next();
+                    if (confRsrc != null && confRsrc.getPath().startsWith(p + "/")) {
+                        pw.print("<b>");
+                        pw.print(xssAPI.encodeForHTML(p));
+                        pw.println("</b>");
+                    } else {
+                        pw.println(xssAPI.encodeForHTML(p));
+                    }
+                    pw.println("<br/>");
+                }
+                pw.println("</td>");
+
+                tableEnd(pw);
+            }
+
+        } finally {
+            if (resolver != null && user != null) {
+                resolver.close();
+            }
+        }
+    }
+
+    private void info(PrintWriter pw, String text) {
+        pw.print("<p class='statline ui-state-highlight'>");
+        pw.print(xssAPI.encodeForHTML(text));
+        pw.println("</p>");
+    }
+
+    private void tableStart(PrintWriter pw, String title, int colspan) {
+        pw.println("<table class='nicetable ui-widget'>");
+        pw.println("<thead class='ui-widget-header'>");
+        pw.println("<tr>");
+        pw.print("<th colspan=");
+        pw.print(String.valueOf(colspan));
+        pw.print(">");
+        pw.print(xssAPI.encodeForHTML(title));
+        pw.println("</th>");
+        pw.println("</tr>");
+        pw.println("</thead>");
+        pw.println("<tbody class='ui-widget-content'>");
+        pw.println("<tr>");
+    }
+
+    private void tableEnd(PrintWriter pw) {
+        pw.println("</tr>");
+        pw.println("</tbody>");
+        pw.println("</table>");
+    }
+
+    private void tableRows(PrintWriter pw) {
+        pw.println("</tr>");
+        pw.println("<tr>");
+    }
+
+    private ResourceResolver getResolver(final String user) {
+        ResourceResolver requestResolver = resolverFactory.getThreadResourceResolver();
+        if ( user == null ) {
+            return requestResolver;
+        }
+        try {
+            return requestResolver.clone(Collections.singletonMap(ResourceResolverFactory.USER_IMPERSONATION, (Object)user));
+        } catch (final LoginException e) {
+            return null;
+        }
+    }
+}

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/resource/impl/def/WebConsolePlugin.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/resource/impl/def/WebConsolePlugin.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Mon Sep 19 15:39:17 2016
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/resource/impl/def/WebConsolePlugin.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationBuilderAdapterFactoryTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationBuilderAdapterFactoryTest.java?rev=1761468&r1=1761467&r2=1761468&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationBuilderAdapterFactoryTest.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationBuilderAdapterFactoryTest.java Mon Sep 19 15:39:17 2016
@@ -23,7 +23,6 @@ import static org.junit.Assert.assertEqu
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.contextaware.config.ConfigurationBuilder;
 import org.apache.sling.contextaware.config.example.SimpleConfig;
-import org.apache.sling.contextaware.config.resource.impl.ConfigurationResourceResolverImpl;
 import org.apache.sling.testing.mock.sling.junit.SlingContext;
 import org.junit.Before;
 import org.junit.Rule;
@@ -38,8 +37,7 @@ public class ConfigurationBuilderAdapter
     
     @Before
     public void setUp() {
-        context.registerInjectActivateService(new ConfigurationResourceResolverImpl());
-        context.registerInjectActivateService(new ConfigurationResolverImpl());
+        ConfigurationTestUtils.registerConfigurationResolver(context);
         context.registerInjectActivateService(new ConfigurationBuilderAdapterFactory());
 
         // config resource

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationProxyTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationProxyTest.java?rev=1761468&r1=1761467&r2=1761468&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationProxyTest.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationProxyTest.java Mon Sep 19 15:39:17 2016
@@ -34,6 +34,9 @@ import static org.junit.Assert.assertFal
 import static org.junit.Assert.assertNull;
 
 import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
 
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.contextaware.config.ConfigurationResolveException;
@@ -43,6 +46,7 @@ import org.apache.sling.contextaware.con
 import org.apache.sling.contextaware.config.example.NestedConfig;
 import org.apache.sling.contextaware.config.example.SimpleConfig;
 import org.apache.sling.contextaware.config.example.SpecialNamesConfig;
+import org.apache.sling.contextaware.config.impl.ConfigurationProxy.ChildResolver;
 import org.apache.sling.testing.mock.sling.junit.SlingContext;
 import org.junit.Rule;
 import org.junit.Test;
@@ -54,7 +58,7 @@ public class ConfigurationProxyTest {
     
     @Test
     public void testNonExistingConfig_AllTypes() {
-        AllTypesConfig cfg = ConfigurationProxy.get(null, AllTypesConfig.class);
+        AllTypesConfig cfg = get(null, AllTypesConfig.class);
 
         assertNull(cfg.stringParam());
         assertEquals(STRING_DEFAULT, cfg.stringParamWithDefault());
@@ -81,7 +85,7 @@ public class ConfigurationProxyTest {
 
     @Test
     public void testNonExistingConfig_Nested() {
-        NestedConfig cfg = ConfigurationProxy.get(null, NestedConfig.class);
+        NestedConfig cfg = get(null, NestedConfig.class);
 
         assertNull(cfg.stringParam());
         
@@ -107,7 +111,7 @@ public class ConfigurationProxyTest {
                 "doubleArrayParam", new double[] {DOUBLE_DEFAULT_2},
                 "boolArrayParam", new boolean[] {BOOL_DEFAULT_2,BOOL_DEFAULT})
                 .getCurrentParent();
-        AllTypesConfig cfg = ConfigurationProxy.get(resource, AllTypesConfig.class);
+        AllTypesConfig cfg = get(resource, AllTypesConfig.class);
 
         assertEquals("configValue2", cfg.stringParam());
         assertEquals(STRING_DEFAULT, cfg.stringParamWithDefault());
@@ -137,7 +141,7 @@ public class ConfigurationProxyTest {
         Resource resource = context.build()
                 .resource("/test",  "stringParam", "configValue2", "int_Param", 222, "bool.Param", true)
                 .getCurrentParent();
-        SpecialNamesConfig cfg = ConfigurationProxy.get(resource, SpecialNamesConfig.class);
+        SpecialNamesConfig cfg = get(resource, SpecialNamesConfig.class);
 
         assertEquals("configValue2", cfg.$stringParam());
         assertEquals(222, cfg.int__Param());
@@ -154,7 +158,7 @@ public class ConfigurationProxyTest {
 
         Resource resource = context.resourceResolver().getResource("/test");
         
-        NestedConfig cfg = ConfigurationProxy.get(resource, NestedConfig.class);
+        NestedConfig cfg = get(resource, NestedConfig.class);
 
         assertEquals("v1", cfg.stringParam());
         
@@ -173,61 +177,90 @@ public class ConfigurationProxyTest {
     @Test(expected=ConfigurationResolveException.class)
     public void testInvalidClassConversion() {
         // test with class not supported for configuration mapping
-        ConfigurationProxy.get(null, Rectangle2D.class);
+        get(null, Rectangle2D.class);
     }
 
     @Test(expected=ConfigurationResolveException.class)
     public void testIllegalTypes_Class() {
-        IllegalTypesConfig cfg = ConfigurationProxy.get(null, IllegalTypesConfig.class);
+        IllegalTypesConfig cfg = get(null, IllegalTypesConfig.class);
         cfg.clazz();
     }
     
     @Test(expected=ConfigurationResolveException.class)
     public void testIllegalTypes_Byte() {
-        IllegalTypesConfig cfg = ConfigurationProxy.get(null, IllegalTypesConfig.class);
+        IllegalTypesConfig cfg = get(null, IllegalTypesConfig.class);
         cfg.byteSingle();
     }
     
     @Test(expected=ConfigurationResolveException.class)
     public void testIllegalTypes_ByteArray() {
-        IllegalTypesConfig cfg = ConfigurationProxy.get(null, IllegalTypesConfig.class);
+        IllegalTypesConfig cfg = get(null, IllegalTypesConfig.class);
         cfg.byteArray();
     }
     
     @Test(expected=ConfigurationResolveException.class)
     public void testIllegalTypes_Short() {
-        IllegalTypesConfig cfg = ConfigurationProxy.get(null, IllegalTypesConfig.class);
+        IllegalTypesConfig cfg = get(null, IllegalTypesConfig.class);
         cfg.shortSingle();
     }
     
     @Test(expected=ConfigurationResolveException.class)
     public void testIllegalTypes_ShortArray() {
-        IllegalTypesConfig cfg = ConfigurationProxy.get(null, IllegalTypesConfig.class);
+        IllegalTypesConfig cfg = get(null, IllegalTypesConfig.class);
         cfg.shortArray();
     }
     
     @Test(expected=ConfigurationResolveException.class)
     public void testIllegalTypes_Float() {
-        IllegalTypesConfig cfg = ConfigurationProxy.get(null, IllegalTypesConfig.class);
+        IllegalTypesConfig cfg = get(null, IllegalTypesConfig.class);
         cfg.floatSingle();
     }
     
     @Test(expected=ConfigurationResolveException.class)
     public void testIllegalTypes_FloatArray() {
-        IllegalTypesConfig cfg = ConfigurationProxy.get(null, IllegalTypesConfig.class);
+        IllegalTypesConfig cfg = get(null, IllegalTypesConfig.class);
         cfg.floatArray();
     }
     
     @Test(expected=ConfigurationResolveException.class)
     public void testIllegalTypes_Char() {
-        IllegalTypesConfig cfg = ConfigurationProxy.get(null, IllegalTypesConfig.class);
+        IllegalTypesConfig cfg = get(null, IllegalTypesConfig.class);
         cfg.charSingle();
     }
     
     @Test(expected=ConfigurationResolveException.class)
     public void testIllegalTypes_CharArray() {
-        IllegalTypesConfig cfg = ConfigurationProxy.get(null, IllegalTypesConfig.class);
+        IllegalTypesConfig cfg = get(null, IllegalTypesConfig.class);
         cfg.charArray();
     }
     
+    private <T> T get(Resource resource, Class<T> clazz) {
+        return ConfigurationProxy.get(resource, clazz, childResolver(resource));
+    }
+    
+    // simulate simple child resolver without involving ConfigurationResolver implementation
+    private ChildResolver childResolver(final Resource resource) {
+        return new ChildResolver() {
+            @Override
+            public <T> T getChild(String configName, Class<T> clazz) {
+                Resource child = resource!=null ? resource.getChild(configName) : null;
+                return ConfigurationProxy.get(child, clazz, childResolver(child));
+            }
+            @Override
+            public <T> Collection<T> getChildren(String configName, Class<T> clazz) {
+                List<T> collection = new ArrayList<>();
+                Resource childParent = resource!=null ? resource.getChild(configName) : null;
+                if (childParent != null) {
+                    for (Resource child : childParent.getChildren()) {
+                        T result = ConfigurationProxy.get(child, clazz, childResolver(child));
+                        if (result != null) {
+                            collection.add(result);
+                        }
+                    }
+                }
+                return collection;
+            }
+        };
+    }
+    
 }

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverAdaptableTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverAdaptableTest.java?rev=1761468&r1=1761467&r2=1761468&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverAdaptableTest.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverAdaptableTest.java Mon Sep 19 15:39:17 2016
@@ -30,7 +30,6 @@ import org.apache.sling.contextaware.con
 import org.apache.sling.contextaware.config.ConfigurationResolveException;
 import org.apache.sling.contextaware.config.ConfigurationResolver;
 import org.apache.sling.contextaware.config.example.SimpleSlingModel;
-import org.apache.sling.contextaware.config.resource.impl.ConfigurationResourceResolverImpl;
 import org.apache.sling.testing.mock.sling.junit.SlingContext;
 import org.junit.Before;
 import org.junit.Rule;
@@ -51,8 +50,7 @@ public class ConfigurationResolverAdapta
 
     @Before
     public void setUp() {
-        context.registerInjectActivateService(new ConfigurationResourceResolverImpl());
-        underTest = context.registerInjectActivateService(new ConfigurationResolverImpl());
+        underTest = ConfigurationTestUtils.registerConfigurationResolver(context);
 
         context.addModelsForPackage("org.apache.sling.contextaware.config.example");
         

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverAnnotationClassTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverAnnotationClassTest.java?rev=1761468&r1=1761467&r2=1761468&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverAnnotationClassTest.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverAnnotationClassTest.java Mon Sep 19 15:39:17 2016
@@ -33,7 +33,6 @@ import org.apache.sling.contextaware.con
 import org.apache.sling.contextaware.config.example.ListConfig;
 import org.apache.sling.contextaware.config.example.NestedConfig;
 import org.apache.sling.contextaware.config.example.SimpleConfig;
-import org.apache.sling.contextaware.config.resource.impl.ConfigurationResourceResolverImpl;
 import org.apache.sling.testing.mock.sling.junit.SlingContext;
 import org.junit.Before;
 import org.junit.Rule;
@@ -54,8 +53,7 @@ public class ConfigurationResolverAnnota
 
     @Before
     public void setUp() {
-        context.registerInjectActivateService(new ConfigurationResourceResolverImpl());
-        underTest = context.registerInjectActivateService(new ConfigurationResolverImpl());
+        underTest = ConfigurationTestUtils.registerConfigurationResolver(context);
 
         // config resources
         context.build().resource("/conf/content/site2/sling:configs/org.apache.sling.contextaware.config.example.SimpleConfig",

Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverCustomPersistenceTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverCustomPersistenceTest.java?rev=1761468&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverCustomPersistenceTest.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverCustomPersistenceTest.java Mon Sep 19 15:39:17 2016
@@ -0,0 +1,193 @@
+/*
+ * 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.contextaware.config.impl;
+
+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 java.awt.geom.Rectangle2D;
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.contextaware.config.ConfigurationResolveException;
+import org.apache.sling.contextaware.config.ConfigurationResolver;
+import org.apache.sling.contextaware.config.example.ListConfig;
+import org.apache.sling.contextaware.config.example.NestedConfig;
+import org.apache.sling.contextaware.config.example.SimpleConfig;
+import org.apache.sling.contextaware.config.management.impl.CustomConfigurationPersistenceStrategy;
+import org.apache.sling.contextaware.config.spi.ConfigurationPersistenceStrategy;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.osgi.framework.Constants;
+
+/**
+ * Test {@link ConfigurationResolver} with annotation classes for reading the config.
+ */
+public class ConfigurationResolverCustomPersistenceTest {
+
+    @Rule
+    public SlingContext context = new SlingContext();
+
+    private ConfigurationResolver underTest;
+
+    private Resource site1Page1;
+    private Resource site2Page1;
+
+    @Before
+    public void setUp() {
+        underTest = ConfigurationTestUtils.registerConfigurationResolver(context);
+
+        // custom strategy which redirects all config resources to a jcr:content subnode
+        context.registerService(ConfigurationPersistenceStrategy.class,
+                new CustomConfigurationPersistenceStrategy(), Constants.SERVICE_RANKING, 2000);
+        
+        // config resources
+        context.build().resource("/conf/content/site2/sling:configs/org.apache.sling.contextaware.config.example.SimpleConfig/jcr:content",
+                "stringParam", "configValue1",
+                "intParam", 111,
+                "boolParam", true);
+
+        context.build().resource("/conf/content/site2/sling:configs/sampleName/jcr:content",
+                "stringParam", "configValue1.1",
+                "intParam", 1111,
+                "boolParam", true);
+
+        context.build().resource("/conf/content/site2/sling:configs/org.apache.sling.contextaware.config.example.NestedConfig")
+            .siblingsMode()
+            .resource("jcr:content", "stringParam", "configValue3")
+            .resource("subConfig/jcr:content", "stringParam", "configValue4", "intParam", 444, "boolParam", true)
+            .hierarchyMode()
+            .resource("subListConfig")
+            .siblingsMode()
+                .resource("1/jcr:content", "stringParam", "configValue2.1")
+                .resource("2/jcr:content", "stringParam", "configValue2.2")
+                .resource("3/jcr:content", "stringParam", "configValue2.3");
+
+        context.build().resource("/conf/content/site2/sling:configs/org.apache.sling.contextaware.config.example.ListConfig")
+            .siblingsMode()
+            .resource("1/jcr:content", "stringParam", "configValue1.1")
+            .resource("2/jcr:content", "stringParam", "configValue1.2")
+            .resource("3/jcr:content", "stringParam", "configValue1.3");
+
+        // content resources
+        context.build().resource("/content/site1", "sling:config-ref", "/conf/content/site1")
+            .resource("/content/site2", "sling:config-ref", "/conf/content/site2");
+        site1Page1 = context.create().resource("/content/site1/page1");
+        site2Page1 = context.create().resource("/content/site2/page1");
+    }
+
+    @Test
+    public void testNonExistingConfig_Simple() {
+        SimpleConfig cfg = underTest.get(site1Page1).as(SimpleConfig.class);
+
+        assertNull(cfg.stringParam());
+        assertEquals(5, cfg.intParam());
+        assertEquals(false, cfg.boolParam());
+    }
+
+    @Test
+    public void testNonExistingConfig_List() {
+        Collection<ListConfig> cfgList = underTest.get(site1Page1).asCollection(ListConfig.class);
+        assertTrue(cfgList.isEmpty());
+    }
+
+    @Test
+    public void testNonExistingConfig_Nested() {
+        NestedConfig cfg = underTest.get(site1Page1).as(NestedConfig.class);
+
+        assertNull(cfg.stringParam());
+        assertNotNull(cfg.subConfig());
+        assertNotNull(cfg.subListConfig());
+    }
+
+
+    @Test
+    public void testConfig_Simple() {
+        SimpleConfig cfg = underTest.get(site2Page1).as(SimpleConfig.class);
+
+        assertEquals("configValue1", cfg.stringParam());
+        assertEquals(111, cfg.intParam());
+        assertEquals(true, cfg.boolParam());
+    }
+
+    @Test
+    public void testConfig_SimpleWithName() {
+        SimpleConfig cfg = underTest.get(site2Page1).name("sampleName").as(SimpleConfig.class);
+
+        assertEquals("configValue1.1", cfg.stringParam());
+        assertEquals(1111, cfg.intParam());
+        assertEquals(true, cfg.boolParam());
+    }
+
+    @Test
+    public void testConfig_List() {
+        Collection<ListConfig> cfgList = underTest.get(site2Page1).asCollection(ListConfig.class);
+
+        assertEquals(3, cfgList.size());
+        Iterator<ListConfig> cfgIterator = cfgList.iterator();
+        assertEquals("configValue1.1", cfgIterator.next().stringParam());
+        assertEquals("configValue1.2", cfgIterator.next().stringParam());
+        assertEquals("configValue1.3", cfgIterator.next().stringParam());
+    }
+
+    @Test
+    public void testConfig_Nested() {
+        NestedConfig cfg = underTest.get(site2Page1).as(NestedConfig.class);
+
+        assertEquals("configValue3", cfg.stringParam());
+        
+        SimpleConfig subConfig = cfg.subConfig();
+        assertEquals("configValue4", subConfig.stringParam());
+        assertEquals(444, subConfig.intParam());
+        assertEquals(true, subConfig.boolParam());
+        
+        ListConfig[] listConfig = cfg.subListConfig();
+        assertEquals(3, listConfig.length);
+        assertEquals("configValue2.1", listConfig[0].stringParam());
+        assertEquals("configValue2.2", listConfig[1].stringParam());
+        assertEquals("configValue2.3", listConfig[2].stringParam());
+    }
+
+    @Test(expected=ConfigurationResolveException.class)
+    public void testInvalidClassConversion() {
+        // test with class not supported for configuration mapping
+        underTest.get(site2Page1).as(Rectangle2D.class);
+    }
+
+    @Test
+    public void testNonExistingContentResource_Simple() {
+        SimpleConfig cfg = underTest.get(null).as(SimpleConfig.class);
+
+        assertNull(cfg.stringParam());
+        assertEquals(5, cfg.intParam());
+        assertEquals(false, cfg.boolParam());
+    }
+
+    @Test
+    public void testNonExistingContentResource_List() {
+        Collection<ListConfig> cfgList = underTest.get(null).asCollection(ListConfig.class);
+        assertTrue(cfgList.isEmpty());
+    }
+
+}

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverCustomPersistenceTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverCustomPersistenceTest.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Mon Sep 19 15:39:17 2016
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverCustomPersistenceTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverValueMapTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverValueMapTest.java?rev=1761468&r1=1761467&r2=1761468&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverValueMapTest.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverValueMapTest.java Mon Sep 19 15:39:17 2016
@@ -29,7 +29,6 @@ import org.apache.sling.api.resource.Res
 import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.contextaware.config.ConfigurationResolveException;
 import org.apache.sling.contextaware.config.ConfigurationResolver;
-import org.apache.sling.contextaware.config.resource.impl.ConfigurationResourceResolverImpl;
 import org.apache.sling.testing.mock.sling.junit.SlingContext;
 import org.junit.Before;
 import org.junit.Rule;
@@ -50,8 +49,7 @@ public class ConfigurationResolverValueM
 
     @Before
     public void setUp() {
-        context.registerInjectActivateService(new ConfigurationResourceResolverImpl());
-        underTest = context.registerInjectActivateService(new ConfigurationResolverImpl());
+        underTest = ConfigurationTestUtils.registerConfigurationResolver(context);
 
         // config resources
         context.build().resource("/conf/content/site2/sling:configs/sampleName", 

Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationTestUtils.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationTestUtils.java?rev=1761468&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationTestUtils.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationTestUtils.java Mon Sep 19 15:39:17 2016
@@ -0,0 +1,44 @@
+/*
+ * 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.contextaware.config.impl;
+
+import org.apache.sling.contextaware.config.ConfigurationResolver;
+import org.apache.sling.contextaware.config.impl.def.DefaultConfigurationPersistenceStrategy;
+import org.apache.sling.contextaware.config.management.impl.ConfigurationPersistenceStrategyMultiplexer;
+import org.apache.sling.contextaware.config.resource.impl.ConfigurationResourceTestUtils;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+
+public final class ConfigurationTestUtils {
+    
+    private ConfigurationTestUtils() {
+        // static methods only
+    }
+
+    /**
+     * Register all services for {@link ConfigurationResolver}.
+     * @param context Sling context
+     */
+    public static ConfigurationResolver registerConfigurationResolver(SlingContext context) {
+        ConfigurationResourceTestUtils.registerConfigurationResourceResolver(context);
+        context.registerInjectActivateService(new DefaultConfigurationPersistenceStrategy());
+        context.registerInjectActivateService(new ConfigurationPersistenceStrategyMultiplexer());
+        return context.registerInjectActivateService(new ConfigurationResolverImpl());
+    }
+    
+}

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationTestUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationTestUtils.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Mon Sep 19 15:39:17 2016
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationTestUtils.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/def/DefaultConfigurationPersistenceStrategyTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/def/DefaultConfigurationPersistenceStrategyTest.java?rev=1761468&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/def/DefaultConfigurationPersistenceStrategyTest.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/def/DefaultConfigurationPersistenceStrategyTest.java Mon Sep 19 15:39:17 2016
@@ -0,0 +1,115 @@
+/*
+ * 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.contextaware.config.impl.def;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.contextaware.config.spi.ConfigurationPersistenceStrategy;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+
+public class DefaultConfigurationPersistenceStrategyTest {
+
+    @Rule
+    public SlingContext context = new SlingContext();
+    
+    @Test
+    public void testGetResource() {
+        ConfigurationPersistenceStrategy underTest = context.registerInjectActivateService(new DefaultConfigurationPersistenceStrategy());
+        
+        Resource resource = context.create().resource("/conf/test");
+        Resource result = underTest.getResource(resource);
+        assertSame(resource, result);
+    }
+
+    @Test
+    public void testPersist() throws Exception {
+        ConfigurationPersistenceStrategy underTest = context.registerInjectActivateService(new DefaultConfigurationPersistenceStrategy());
+        
+        // store config data
+        assertTrue(underTest.persist(context.resourceResolver(), "/conf/test",
+                ImmutableMap.<String,Object>of("prop1", "value1", "prop2", 5)));
+        context.resourceResolver().commit();
+        
+        ValueMap props = context.resourceResolver().getResource("/conf/test").getValueMap();
+        assertEquals("value1", props.get("prop1", String.class));
+        assertEquals((Integer)5, props.get("prop2", Integer.class));
+
+        // remove config data
+        assertTrue(underTest.persist(context.resourceResolver(), "/conf/test", ImmutableMap.<String,Object>of()));
+        context.resourceResolver().commit();
+
+        props = context.resourceResolver().getResource("/conf/test").getValueMap();
+        assertNull(props.get("prop1", String.class));
+        assertNull(props.get("prop2", Integer.class));
+        
+    }
+
+    @Test
+    public void testPersistCollection() throws Exception {
+        ConfigurationPersistenceStrategy underTest = context.registerInjectActivateService(new DefaultConfigurationPersistenceStrategy());
+        
+        // store new config collection items
+        assertTrue(underTest.persistCollection(context.resourceResolver(), "/conf/test", ImmutableList.<Map<String,Object>>of(
+                ImmutableMap.<String,Object>of("prop1", "value1"),
+                ImmutableMap.<String,Object>of("prop2", 5)
+        )));
+        context.resourceResolver().commit();
+        
+        Resource resource = context.resourceResolver().getResource("/conf/test");
+        assertEquals(2, ImmutableList.copyOf(resource.getChildren()).size());
+        ValueMap props0 = context.resourceResolver().getResource("/conf/test/0").getValueMap();
+        assertEquals("value1", props0.get("prop1", String.class));
+        ValueMap props1 = context.resourceResolver().getResource("/conf/test/1").getValueMap();
+        assertEquals((Integer)5, props1.get("prop2", Integer.class));
+
+        // remove config collection items
+        assertTrue(underTest.persistCollection(context.resourceResolver(), "/conf/test", ImmutableList.<Map<String,Object>>of()));
+        context.resourceResolver().commit();
+
+        resource = context.resourceResolver().getResource("/conf/test");
+        assertEquals(0, ImmutableList.copyOf(resource.getChildren()).size());
+    }
+
+    @Test
+    public void testDisabled() {
+        ConfigurationPersistenceStrategy underTest = context.registerInjectActivateService(new DefaultConfigurationPersistenceStrategy(),
+                "enabled", false);
+        
+        Resource resource = context.create().resource("/conf/test");
+        assertNull(underTest.getResource(resource));
+
+        assertFalse(underTest.persist(context.resourceResolver(), "/conf/test", ImmutableMap.<String,Object>of()));
+        assertFalse(underTest.persistCollection(context.resourceResolver(), "/conf/test", ImmutableList.<Map<String,Object>>of()));
+    }
+
+}

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/def/DefaultConfigurationPersistenceStrategyTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/def/DefaultConfigurationPersistenceStrategyTest.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Mon Sep 19 15:39:17 2016
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/def/DefaultConfigurationPersistenceStrategyTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/metadata/AnnotationClassParserTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/metadata/AnnotationClassParserTest.java?rev=1761468&r1=1761467&r2=1761468&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/metadata/AnnotationClassParserTest.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/metadata/AnnotationClassParserTest.java Mon Sep 19 15:39:17 2016
@@ -80,7 +80,7 @@ public class AnnotationClassParserTest {
         assertEquals("This is a configuration example with additional metadata.", metadata.getDescription());
         assertEquals(ImmutableMap.of("param1", "value1", "param2", "123"), metadata.getProperties());
         
-        Collection<PropertyMetadata<?>> propertyMetadataList = metadata.getPropertyMetadata();
+        Collection<PropertyMetadata<?>> propertyMetadataList = metadata.getPropertyMetadata().values();
         assertEquals(3, propertyMetadataList.size());
         
         for (PropertyMetadata<?> propertyMetadata : propertyMetadataList) {

Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/metadata/ConfigurationMetadataProviderMultiplexerTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/metadata/ConfigurationMetadataProviderMultiplexerTest.java?rev=1761468&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/metadata/ConfigurationMetadataProviderMultiplexerTest.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/metadata/ConfigurationMetadataProviderMultiplexerTest.java Mon Sep 19 15:39:17 2016
@@ -0,0 +1,106 @@
+/*
+ * 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.contextaware.config.impl.metadata;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.sling.contextaware.config.spi.ConfigurationMetadataProvider;
+import org.apache.sling.contextaware.config.spi.metadata.ConfigurationMetadata;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableSortedSet;
+
+public class ConfigurationMetadataProviderMultiplexerTest {
+
+    @Rule
+    public SlingContext context = new SlingContext();
+    
+    private ConfigurationMetadataProviderMultiplexer underTest;
+
+    @Before
+    public void setUp() {
+        underTest = context.registerInjectActivateService(new ConfigurationMetadataProviderMultiplexer());
+    }
+    
+    @Test
+    public void testWithNoProvider() {
+        SortedSet<String> configNames = underTest.getConfigurationNames();
+        assertTrue(configNames.isEmpty());
+        
+        ConfigurationMetadata configMetadata = underTest.getConfigurationMetadata("test1");
+        assertNull(configMetadata);
+    }
+
+    @Test
+    public void testWithOneProvider() {
+        registerConfigurationMetadataProvider("test1", "test2");
+
+        SortedSet<String> configNames = underTest.getConfigurationNames();
+        assertEquals(ImmutableSortedSet.of("test1", "test2"), configNames);
+        
+        ConfigurationMetadata configMetadata = underTest.getConfigurationMetadata("test1");
+        assertEquals("test1", configMetadata.getName());
+
+        configMetadata = underTest.getConfigurationMetadata("test2");
+        assertEquals("test2", configMetadata.getName());
+    }
+    
+    @Test
+    public void testWithTwoProviders() {
+        registerConfigurationMetadataProvider("test1");
+        registerConfigurationMetadataProvider("test2");
+
+        SortedSet<String> configNames = underTest.getConfigurationNames();
+        assertEquals(ImmutableSortedSet.of("test1", "test2"), configNames);
+        
+        ConfigurationMetadata configMetadata = underTest.getConfigurationMetadata("test1");
+        assertEquals("test1", configMetadata.getName());
+
+        configMetadata = underTest.getConfigurationMetadata("test2");
+        assertEquals("test2", configMetadata.getName());
+    }
+    
+    private void registerConfigurationMetadataProvider(String... names) {
+        final Map<String,ConfigurationMetadata> metadata = new HashMap<>();
+        for (String name : names) {
+            metadata.put(name, new ConfigurationMetadata(name));
+        }
+        context.registerService(ConfigurationMetadataProvider.class, new ConfigurationMetadataProvider() {
+            @Override
+            public SortedSet<String> getConfigurationNames() {
+                return new TreeSet<>(metadata.keySet());
+            }
+            @Override
+            public ConfigurationMetadata getConfigurationMetadata(String configName) {
+                return metadata.get(configName);
+            }
+        });
+    }
+
+}

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/metadata/ConfigurationMetadataProviderMultiplexerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/metadata/ConfigurationMetadataProviderMultiplexerTest.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Mon Sep 19 15:39:17 2016
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/metadata/ConfigurationMetadataProviderMultiplexerTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationDataImplTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationDataImplTest.java?rev=1761468&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationDataImplTest.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationDataImplTest.java Mon Sep 19 15:39:17 2016
@@ -0,0 +1,143 @@
+/*
+ * 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.contextaware.config.management.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.contextaware.config.management.ConfigurationData;
+import org.apache.sling.contextaware.config.management.ValueInfo;
+import org.apache.sling.contextaware.config.spi.metadata.ConfigurationMetadata;
+import org.apache.sling.contextaware.config.spi.metadata.PropertyMetadata;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+public class ConfigurationDataImplTest {
+    
+    @Rule
+    public SlingContext context = new SlingContext();
+    
+    private Resource configResource;
+    private ConfigurationMetadata configMetadata;
+    
+    
+    @Before
+    public void setUp() {
+        configResource = context.create().resource("/conf/test",
+                "prop1", "value1",
+                "prop4", true);
+        configMetadata = new ConfigurationMetadata("testName");
+        configMetadata.setPropertyMetadata(ImmutableMap.<String,PropertyMetadata<?>>of(
+                "prop1", new PropertyMetadata<>("prop1", "defValue"),
+                "prop2", new PropertyMetadata<>("prop2", String.class),
+                "prop3", new PropertyMetadata<>("prop3", 5)));
+    }
+
+    @Test
+    public void testWithResourceMetadata() {
+        ConfigurationData underTest = new ConfigurationDataImpl(configResource, configMetadata);
+        
+        assertEquals(ImmutableSet.of("prop1", "prop2", "prop3", "prop4"), underTest.getPropertyNames());
+        
+        ValueMap values = underTest.getValues();
+        assertEquals("value1", values.get("prop1", String.class));
+        assertNull(values.get("prop2", String.class));
+        assertNull(values.get("prop3", Integer.class));
+        assertEquals(true, values.get("prop4", Boolean.class));
+
+        ValueMap effectiveValues = underTest.getEffectiveValues();
+        assertEquals("value1", effectiveValues.get("prop1", String.class));
+        assertNull(effectiveValues.get("prop2", String.class));
+        assertEquals((Integer)5, effectiveValues.get("prop3", Integer.class));
+        assertEquals(true, effectiveValues.get("prop4", Boolean.class));
+        
+        ValueInfo<?> prop1 = underTest.getValueInfo("prop1");
+        assertEquals("prop1", prop1.getPropertyMetadata().getName());
+        assertEquals("value1", prop1.getValue());
+        assertEquals("value1", prop1.getEffectiveValue());
+
+        ValueInfo<?> prop3 = underTest.getValueInfo("prop3");
+        assertEquals("prop3", prop3.getPropertyMetadata().getName());
+        assertNull(prop3.getValue());
+        assertEquals((Integer)5, prop3.getEffectiveValue());
+
+        ValueInfo<?> prop4 = underTest.getValueInfo("prop4");
+        assertNull("prop4", prop4.getPropertyMetadata());
+        assertEquals(true, prop4.getValue());
+        assertEquals(true, prop4.getEffectiveValue());
+    }
+
+    @Test
+    public void testWithResourceOnly() {
+        ConfigurationData underTest = new ConfigurationDataImpl(configResource, null);
+        
+        assertEquals(ImmutableSet.of("prop1", "prop4"), underTest.getPropertyNames());
+        
+        ValueMap values = underTest.getValues();
+        assertEquals("value1", values.get("prop1", String.class));
+        assertEquals(true, values.get("prop4", Boolean.class));
+
+        ValueMap effectiveValues = underTest.getEffectiveValues();
+        assertEquals("value1", effectiveValues.get("prop1", String.class));
+        assertEquals(true, effectiveValues.get("prop4", Boolean.class));
+        
+        ValueInfo<?> prop1 = underTest.getValueInfo("prop1");
+        assertNull(prop1.getPropertyMetadata());
+        assertEquals("value1", prop1.getValue());
+        assertEquals("value1", prop1.getEffectiveValue());
+
+        ValueInfo<?> prop4 = underTest.getValueInfo("prop4");
+        assertNull("prop4", prop4.getPropertyMetadata());
+        assertEquals(true, prop4.getValue());
+        assertEquals(true, prop4.getEffectiveValue());
+    }
+
+    @Test
+    public void testMetadataOnly() {
+        ConfigurationData underTest = new ConfigurationDataImpl(configMetadata);
+        
+        assertEquals(ImmutableSet.of("prop1", "prop2", "prop3"), underTest.getPropertyNames());
+        
+        ValueMap values = underTest.getValues();
+        assertTrue(values.isEmpty());
+
+        ValueMap effectiveValues = underTest.getEffectiveValues();
+        assertEquals("defValue", effectiveValues.get("prop1", String.class));
+        assertEquals((Integer)5, effectiveValues.get("prop3", Integer.class));
+        
+        ValueInfo<?> prop1 = underTest.getValueInfo("prop1");
+        assertEquals("prop1", prop1.getPropertyMetadata().getName());
+        assertNull(prop1.getValue());
+        assertEquals("defValue", prop1.getEffectiveValue());
+
+        ValueInfo<?> prop3 = underTest.getValueInfo("prop3");
+        assertEquals("prop3", prop3.getPropertyMetadata().getName());
+        assertNull(prop3.getValue());
+        assertEquals((Integer)5, prop3.getEffectiveValue());
+    }
+
+}

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationDataImplTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationDataImplTest.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Mon Sep 19 15:39:17 2016
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationDataImplTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationManagerImplCustomPersistenceTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationManagerImplCustomPersistenceTest.java?rev=1761468&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationManagerImplCustomPersistenceTest.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationManagerImplCustomPersistenceTest.java Mon Sep 19 15:39:17 2016
@@ -0,0 +1,42 @@
+/*
+ * 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.contextaware.config.management.impl;
+
+import org.apache.sling.contextaware.config.spi.ConfigurationPersistenceStrategy;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.osgi.framework.Constants;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ConfigurationManagerImplCustomPersistenceTest extends ConfigurationManagerImplTest {
+    
+    @Before
+    public void setUpCustomPersistence() {
+        // custom strategy which redirects all config resources to a jcr:content subnode
+        context.registerService(ConfigurationPersistenceStrategy.class,
+                new CustomConfigurationPersistenceStrategy(), Constants.SERVICE_RANKING, 2000);
+    }
+
+    @Override
+    protected String getConfigPropertiesPath(String path) {
+        return path + "/jcr:content";
+    }
+
+}

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationManagerImplCustomPersistenceTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationManagerImplCustomPersistenceTest.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Mon Sep 19 15:39:17 2016
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationManagerImplCustomPersistenceTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationManagerImplTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationManagerImplTest.java?rev=1761468&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationManagerImplTest.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationManagerImplTest.java Mon Sep 19 15:39:17 2016
@@ -0,0 +1,259 @@
+/*
+ * 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.contextaware.config.management.impl;
+
+import static org.apache.sling.contextaware.config.impl.ConfigurationNameConstants.CONFIGS_PARENT_NAME;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.contextaware.config.impl.def.DefaultConfigurationPersistenceStrategy;
+import org.apache.sling.contextaware.config.impl.metadata.ConfigurationMetadataProviderMultiplexer;
+import org.apache.sling.contextaware.config.management.ConfigurationData;
+import org.apache.sling.contextaware.config.management.ConfigurationManager;
+import org.apache.sling.contextaware.config.resource.ConfigurationResourceResolver;
+import org.apache.sling.contextaware.config.resource.impl.ConfigurationResourceResolvingStrategyMultiplexer;
+import org.apache.sling.contextaware.config.resource.spi.ConfigurationResourceResolvingStrategy;
+import org.apache.sling.contextaware.config.spi.ConfigurationMetadataProvider;
+import org.apache.sling.contextaware.config.spi.metadata.ConfigurationMetadata;
+import org.apache.sling.contextaware.config.spi.metadata.PropertyMetadata;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ConfigurationManagerImplTest {
+    
+    @Rule
+    public SlingContext context = new SlingContext();
+
+    @Mock
+    private ConfigurationResourceResolver configurationResourceResolver;
+    @Mock
+    private ConfigurationResourceResolvingStrategy configurationResourceResolvingStrategy;
+    @Mock
+    private ConfigurationMetadataProvider configurationMetadataProvider;
+    
+    private ConfigurationManager underTest;
+    
+    private Resource contextResource;
+    protected Resource configResource;
+    protected Resource configResourceItem1;
+    protected Resource configResourceItem2;
+    private ConfigurationMetadata configMetadata;
+    
+    private static final String CONFIG_NAME = "testConfigName";
+    
+    @Before
+    public void setUp() {
+        context.registerService(ConfigurationResourceResolver.class, configurationResourceResolver);
+        context.registerService(ConfigurationResourceResolvingStrategy.class, configurationResourceResolvingStrategy);
+        context.registerService(ConfigurationMetadataProvider.class, configurationMetadataProvider);
+        context.registerInjectActivateService(new ConfigurationResourceResolvingStrategyMultiplexer());
+        context.registerInjectActivateService(new ConfigurationMetadataProviderMultiplexer());
+        context.registerInjectActivateService(new DefaultConfigurationPersistenceStrategy());
+        context.registerInjectActivateService(new ConfigurationPersistenceStrategyMultiplexer());
+        underTest = context.registerInjectActivateService(new ConfigurationManagerImpl());
+        
+        contextResource = context.create().resource("/content/test");
+        
+        context.create().resource(getConfigPropertiesPath("/conf/test"),
+                "prop1", "value1",
+                "prop4", true);
+        context.create().resource(getConfigPropertiesPath("/conf/item/1"),
+                "prop1", "value1");
+        context.create().resource(getConfigPropertiesPath("/conf/item/2"),
+                "prop4", true);
+
+        configResource = context.resourceResolver().getResource("/conf/test");
+        configResourceItem1 = context.resourceResolver().getResource("/conf/item/1");
+        configResourceItem2 = context.resourceResolver().getResource("/conf/item/2");
+        
+        configMetadata = new ConfigurationMetadata(CONFIG_NAME);
+        configMetadata.setPropertyMetadata(ImmutableMap.<String,PropertyMetadata<?>>of(
+                "prop1", new PropertyMetadata<>("prop1", "defValue"),
+                "prop2", new PropertyMetadata<>("prop2", String.class),
+                "prop3", new PropertyMetadata<>("prop3", 5)));
+
+        when(configurationResourceResolver.getResourceCollection(any(Resource.class), anyString(), anyString()))
+                .thenReturn(ImmutableList.<Resource>of());
+    }
+    
+    protected String getConfigPropertiesPath(String path) {
+        return path;
+    }
+    
+    @Test
+    public void testGet() {
+        when(configurationMetadataProvider.getConfigurationMetadata(CONFIG_NAME)).thenReturn(configMetadata);
+        when(configurationResourceResolver.getResource(contextResource, CONFIGS_PARENT_NAME, CONFIG_NAME)).thenReturn(configResource);
+
+        ConfigurationData configData = underTest.get(contextResource, CONFIG_NAME);
+        assertNotNull(configData);
+
+        assertEquals(ImmutableSet.of("prop1", "prop2", "prop3", "prop4"), configData.getPropertyNames());
+        assertEquals("value1", configData.getValues().get("prop1", String.class));
+        assertEquals((Integer)5, configData.getEffectiveValues().get("prop3", 0));
+    }
+
+    @Test
+    public void testGet_NoConfigResource() {
+        when(configurationMetadataProvider.getConfigurationMetadata(CONFIG_NAME)).thenReturn(configMetadata);
+
+        ConfigurationData configData = underTest.get(contextResource, CONFIG_NAME);
+        assertNotNull(configData);
+
+        assertEquals(ImmutableSet.of("prop1", "prop2", "prop3"), configData.getPropertyNames());
+        assertNull(configData.getValues().get("prop1", String.class));
+        assertEquals((Integer)5, configData.getEffectiveValues().get("prop3", 0));
+    }
+
+    @Test
+    public void testGet_NoConfigMetadata() {
+        when(configurationResourceResolver.getResource(contextResource, CONFIGS_PARENT_NAME, CONFIG_NAME)).thenReturn(configResource);
+
+        ConfigurationData configData = underTest.get(contextResource, CONFIG_NAME);
+        assertNotNull(configData);
+
+        assertEquals(ImmutableSet.of("prop1", "prop4"), configData.getPropertyNames());
+        assertEquals("value1", configData.getValues().get("prop1", String.class));
+        assertEquals((Integer)0, configData.getEffectiveValues().get("prop3", 0));
+    }
+
+    @Test
+    public void testGet_NoConfigResource_NoConfigMetadata() {
+        ConfigurationData configData = underTest.get(contextResource, CONFIG_NAME);
+        assertNull(configData);
+    }
+
+    @Test
+    public void testGetCollection() {
+        when(configurationMetadataProvider.getConfigurationMetadata(CONFIG_NAME)).thenReturn(configMetadata);
+        when(configurationResourceResolver.getResourceCollection(contextResource, CONFIGS_PARENT_NAME, CONFIG_NAME))
+            .thenReturn(ImmutableList.of(configResourceItem1, configResourceItem2));
+        
+        List<ConfigurationData> configDatas = ImmutableList.copyOf(underTest.getCollection(contextResource, CONFIG_NAME));
+        assertEquals(2, configDatas.size());
+        
+        ConfigurationData configData1 = configDatas.get(0);
+        assertEquals(ImmutableSet.of("prop1", "prop2", "prop3"), configData1.getPropertyNames());
+        assertEquals("value1", configData1.getValues().get("prop1", String.class));
+        assertEquals((Integer)5, configData1.getEffectiveValues().get("prop3", 0));
+
+        ConfigurationData configData2 = configDatas.get(1);
+        assertEquals(ImmutableSet.of("prop1", "prop2", "prop3", "prop4"), configData2.getPropertyNames());
+        assertNull(configData2.getValues().get("prop1", String.class));
+        assertEquals((Integer)5, configData2.getEffectiveValues().get("prop3", 0));
+    }
+
+    @Test
+    public void testGetCollection_NoConfigResources() {
+        when(configurationMetadataProvider.getConfigurationMetadata(CONFIG_NAME)).thenReturn(configMetadata);
+        
+        List<ConfigurationData> configDatas = ImmutableList.copyOf(underTest.getCollection(contextResource, CONFIG_NAME));
+        assertEquals(0, configDatas.size());
+    }
+
+    @Test
+    public void testGetCollection_NoConfigMetadata() {
+        when(configurationResourceResolver.getResourceCollection(contextResource, CONFIGS_PARENT_NAME, CONFIG_NAME))
+            .thenReturn(ImmutableList.of(configResourceItem1, configResourceItem2));
+        
+        List<ConfigurationData> configDatas = ImmutableList.copyOf(underTest.getCollection(contextResource, CONFIG_NAME));
+        assertEquals(2, configDatas.size());
+        
+        ConfigurationData configData1 = configDatas.get(0);
+        assertEquals(ImmutableSet.of("prop1"), configData1.getPropertyNames());
+        assertEquals("value1", configData1.getValues().get("prop1", String.class));
+        assertEquals((Integer)0, configData1.getEffectiveValues().get("prop3", 0));
+
+        ConfigurationData configData2 = configDatas.get(1);
+        assertEquals(ImmutableSet.of("prop4"), configData2.getPropertyNames());
+        assertNull(configData2.getValues().get("prop1", String.class));
+        assertEquals((Integer)0, configData2.getEffectiveValues().get("prop3", 0));
+    }
+
+    @Test
+    public void testGetCollection_NoConfigResources_NoConfigMetadata() {
+        List<ConfigurationData> configDatas = ImmutableList.copyOf(underTest.getCollection(contextResource, CONFIG_NAME));
+        assertEquals(0, configDatas.size());
+    }
+
+    @Test
+    public void testPersist() throws Exception {
+        when(configurationResourceResolvingStrategy.getResourcePath(contextResource, CONFIGS_PARENT_NAME, CONFIG_NAME))
+            .thenReturn("/conf/new");
+        
+        underTest.persist(contextResource, CONFIG_NAME,
+                ImmutableMap.<String, Object>of("prop1", "value1"));
+        context.resourceResolver().commit();
+
+        ValueMap props = context.resourceResolver().getResource(getConfigPropertiesPath("/conf/new")).getValueMap();
+        assertEquals("value1", props.get("prop1"));
+    }
+
+    @Test
+    public void testPersistCollection() throws Exception {
+        when(configurationResourceResolvingStrategy.getResourceCollectionParentPath(contextResource, CONFIGS_PARENT_NAME, CONFIG_NAME))
+            .thenReturn("/conf/newcol");
+
+        underTest.persistCollection(contextResource, CONFIG_NAME, ImmutableList.<Map<String,Object>>of(
+                ImmutableMap.<String, Object>of("prop1", "value1"),
+                ImmutableMap.<String, Object>of("prop2", 5)
+        ));
+        context.resourceResolver().commit();
+
+        ValueMap props0 = context.resourceResolver().getResource(getConfigPropertiesPath("/conf/newcol/0")).getValueMap();
+        assertEquals("value1", props0.get("prop1"));
+        ValueMap props1 = context.resourceResolver().getResource(getConfigPropertiesPath("/conf/newcol/1")).getValueMap();
+        assertEquals((Integer)5, props1.get("prop2"));
+    }
+
+    @Test
+    public void testNewCollectionItem() {
+        when(configurationMetadataProvider.getConfigurationMetadata(CONFIG_NAME)).thenReturn(configMetadata);
+        
+        ConfigurationData newItem = underTest.newCollectionItem(CONFIG_NAME);
+        assertNotNull(newItem);
+        assertEquals((Integer)5, newItem.getEffectiveValues().get("prop3", 0));
+    }
+
+    @Test
+    public void testNewCollectionItem_NoConfigMetadata() {
+        ConfigurationData newItem = underTest.newCollectionItem(CONFIG_NAME);
+        assertNull(newItem);
+    }
+
+}

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationManagerImplTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationManagerImplTest.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Mon Sep 19 15:39:17 2016
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationManagerImplTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationPersistenceStrategyMultiplexerTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationPersistenceStrategyMultiplexerTest.java?rev=1761468&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationPersistenceStrategyMultiplexerTest.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationPersistenceStrategyMultiplexerTest.java Mon Sep 19 15:39:17 2016
@@ -0,0 +1,123 @@
+/*
+ * 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.contextaware.config.management.impl;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.contextaware.config.impl.def.DefaultConfigurationPersistenceStrategy;
+import org.apache.sling.contextaware.config.spi.ConfigurationPersistenceStrategy;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.osgi.framework.Constants;
+
+import com.google.common.collect.ImmutableList;
+
+public class ConfigurationPersistenceStrategyMultiplexerTest {
+
+    @Rule
+    public SlingContext context = new SlingContext();
+    
+    private ConfigurationPersistenceStrategyMultiplexer underTest;
+    
+    private Resource resource1;
+    private Resource resource2;
+    
+    @Before
+    public void setUp() {
+        underTest = context.registerInjectActivateService(new ConfigurationPersistenceStrategyMultiplexer());
+        resource1 = context.create().resource("/conf/test1");
+        resource2 = context.create().resource("/conf/test2");
+    }
+    
+    @Test
+    public void testWithNoStrategies() {
+        assertNull(underTest.getResource(resource1));
+        assertFalse(underTest.persist(context.resourceResolver(), "/conf/test1", resource1.getValueMap()));
+        assertFalse(underTest.persistCollection(context.resourceResolver(), "/conf/testCol", 
+                ImmutableList.<Map<String,Object>>of(resource1.getValueMap(), resource2.getValueMap())));
+    }
+
+    @Test
+    public void testWithDefaultStrategy() {
+        context.registerInjectActivateService(new DefaultConfigurationPersistenceStrategy());
+
+        Resource result = underTest.getResource(resource1);
+        assertSame(resource1, result);
+        assertTrue(underTest.persist(context.resourceResolver(), "/conf/test1", resource1.getValueMap()));
+        assertTrue(underTest.persistCollection(context.resourceResolver(), "/conf/testCol", 
+                ImmutableList.<Map<String,Object>>of(resource1.getValueMap(), resource2.getValueMap())));
+    }
+    
+    @Test
+    public void testMultipleStrategies() {
+        
+        // strategy 1
+        context.registerService(ConfigurationPersistenceStrategy.class, new ConfigurationPersistenceStrategy() {
+            @Override
+            public Resource getResource(Resource resource) {
+                return resource2;
+            }
+            @Override
+            public boolean persist(ResourceResolver resourceResolver, String configResourcePath, Map<String,Object> properties) {
+                return true;
+            }
+            @Override
+            public boolean persistCollection(ResourceResolver resourceResolver, String configResourceCollectionParentPath,
+                    Collection<Map<String,Object>> propertiesCollection) {
+                return false;
+            }
+        }, Constants.SERVICE_RANKING, 2000);
+        
+        // strategy 2
+        context.registerService(ConfigurationPersistenceStrategy.class, new ConfigurationPersistenceStrategy() {
+            @Override
+            public Resource getResource(Resource resource) {
+                return resource1;
+            }
+            @Override
+            public boolean persist(ResourceResolver resourceResolver, String configResourcePath, Map<String,Object> properties) {
+                return false;
+            }
+            @Override
+            public boolean persistCollection(ResourceResolver resourceResolver, String configResourceCollectionParentPath,
+                    Collection<Map<String,Object>> propertiesCollection) {
+                return true;
+            }
+
+        }, Constants.SERVICE_RANKING, 1000);
+        
+        Resource result = underTest.getResource(resource1);
+        assertSame(resource2, result);
+        assertTrue(underTest.persist(context.resourceResolver(), "/conf/test1", resource1.getValueMap()));
+        assertTrue(underTest.persistCollection(context.resourceResolver(), "/conf/testCol", 
+                ImmutableList.<Map<String,Object>>of(resource1.getValueMap(), resource2.getValueMap())));
+    }
+    
+
+}

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationPersistenceStrategyMultiplexerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationPersistenceStrategyMultiplexerTest.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Mon Sep 19 15:39:17 2016
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationPersistenceStrategyMultiplexerTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain