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 [1/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...

Author: sseifert
Date: Mon Sep 19 15:39:17 2016
New Revision: 1761468

URL: http://svn.apache.org/viewvc?rev=1761468&view=rev
Log:
SLING-6023 Summary: Context-Aware Config: Add pluggable context paths strategies
SLING-6026 Summary: Context-Aware Config: Pluggable configuration persistence

Added:
    sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/
    sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/ConfigurationResourceResolvingStrategy.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/ContextPathStrategy.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/package-info.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/ConfigurationPersistenceException.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/ConfigurationPersistenceStrategy.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationNameConstants.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/def/
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/def/DefaultConfigurationPersistenceStrategy.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/metadata/ConfigurationMetadataProviderMultiplexer.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/ConfigurationData.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/ConfigurationManager.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/ValueInfo.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/impl/
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/impl/ConfigurationDataImpl.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/impl/ConfigurationManagerImpl.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/impl/ConfigurationPersistenceStrategyMultiplexer.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/impl/ValueInfoImpl.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/package-info.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/resource/impl/ConfigurationResourceResolvingStrategyMultiplexer.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/resource/impl/ContextPathStrategyMultiplexer.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/resource/impl/def/
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/resource/impl/def/DefaultConfigurationResourceResolvingStrategy.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/resource/impl/def/DefaultContextPathStrategy.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/resource/impl/def/WebConsolePlugin.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverCustomPersistenceTest.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationTestUtils.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/def/
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/def/DefaultConfigurationPersistenceStrategyTest.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/metadata/ConfigurationMetadataProviderMultiplexerTest.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationDataImplTest.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationManagerImplCustomPersistenceTest.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationManagerImplTest.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ConfigurationPersistenceStrategyMultiplexerTest.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/CustomConfigurationPersistenceStrategy.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/management/impl/ValueInfoImplTest.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/resource/impl/ConfigurationResourceResolvingStrategyMultiplexerTest.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/resource/impl/ConfigurationResourceTestUtils.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/resource/impl/ContextPathStrategyMultiplexerTest.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/resource/impl/def/
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/resource/impl/def/DefaultConfigurationResourceResolvingStrategyHierarchyTest.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/resource/impl/def/DefaultConfigurationResourceResolvingStrategyTest.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/resource/impl/def/DefaultContextPathStrategyTest.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/integration-tests/src/test/java/org/apache/sling/contextaware/config/it/ConfigurationManagerIT.java   (with props)
    sling/trunk/contrib/extensions/contextaware-config/integration-tests/src/test/java/org/apache/sling/contextaware/config/it/TestUtils.java   (with props)
Removed:
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/resource/impl/WebConsolePlugin.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/resource/impl/ConfigurationResourceResolverImplHierarchyTest.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/resource/impl/TestUtils.java
Modified:
    sling/trunk/contrib/extensions/contextaware-config/api/pom.xml
    sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/ConfigurationBuilder.java
    sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/metadata/AbstractMetadata.java
    sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/metadata/ConfigurationMetadata.java
    sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/metadata/PropertyMetadata.java
    sling/trunk/contrib/extensions/contextaware-config/api/src/test/java/org/apache/sling/contextaware/config/spi/metadata/PropertyMetadataTest.java
    sling/trunk/contrib/extensions/contextaware-config/impl/pom.xml
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationBuilderImpl.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationProxy.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverImpl.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/metadata/AnnotationClassParser.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/resource/impl/ConfigurationResourceResolverImpl.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationBuilderAdapterFactoryTest.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationProxyTest.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverAdaptableTest.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverAnnotationClassTest.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverValueMapTest.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/impl/metadata/AnnotationClassParserTest.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/contextaware/config/resource/impl/ConfigurationResourceResolverImplTest.java
    sling/trunk/contrib/extensions/contextaware-config/integration-tests/src/test/java/org/apache/sling/contextaware/config/it/AdaptToConfigClassIT.java
    sling/trunk/contrib/extensions/contextaware-config/integration-tests/src/test/java/org/apache/sling/contextaware/config/it/ConfigurationResolverConfigClassIT.java
    sling/trunk/contrib/extensions/contextaware-config/integration-tests/src/test/java/org/apache/sling/contextaware/config/it/ConfigurationResolverValueMapIT.java
    sling/trunk/contrib/extensions/contextaware-config/integration-tests/src/test/java/org/apache/sling/contextaware/config/it/example/SimpleConfig.java

Modified: sling/trunk/contrib/extensions/contextaware-config/api/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/api/pom.xml?rev=1761468&r1=1761467&r2=1761468&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/api/pom.xml (original)
+++ sling/trunk/contrib/extensions/contextaware-config/api/pom.xml Mon Sep 19 15:39:17 2016
@@ -67,9 +67,27 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>3.3.2</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.testing.osgi-mock</artifactId>
+            <version>2.0.5-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.testing.sling-mock</artifactId>
-            <version>1.7.0</version>
+            <version>1.7.1-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.osgi</artifactId>
+            <version>2.4.0</version>
             <scope>test</scope>
         </dependency>
         <dependency>

Modified: sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/ConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/ConfigurationBuilder.java?rev=1761468&r1=1761467&r2=1761468&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/ConfigurationBuilder.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/ConfigurationBuilder.java Mon Sep 19 15:39:17 2016
@@ -44,6 +44,7 @@ public interface ConfigurationBuilder {
      * Configuration name is optional - if not given via {@link #name(String)} method it is derived
      * from the annotation interface class name.
      * @param clazz Annotation interface class
+     * @param <T> Annotation class type
      * @return Configuration object. Contains only the default values if content resource or configuration cannot be found.
      */
     @Nonnull <T> T as(@Nonnull Class<T> clazz);
@@ -53,6 +54,7 @@ public interface ConfigurationBuilder {
      * Configuration name is optional - if not given via {@link #name(String)} method it is derived
      * from the annotation interface class name.
      * @param clazz Annotation interface class
+     * @param <T> Annotation class type
      * @return Collection of configuration objects. Is empty if content resource or configuration cannot be found.
      */
     @Nonnull <T> Collection<T> asCollection(@Nonnull Class<T> clazz);
@@ -65,21 +67,22 @@ public interface ConfigurationBuilder {
 
     /**
      * Get collection of configuration resources with their properties mapped to the given annotation class.
-     * @param clazz Annotation interface class
      * @return Collection of value map. Is empty if content resource or configuration cannot be found.
      */
     @Nonnull Collection<ValueMap> asValueMapCollection();
 
     /**
      * Get configuration as singleton configuration resource and adapt it to the given class.
-     * @param clazz Class that can be adapted from a {@link Resource}
+     * @param clazz Class that can be adapted from a {@link org.apache.sling.api.resource.Resource}
+     * @param <T> Annotation class type
      * @return Object instance or null if content resource or configuration cannot be found or if the adaption was not possible.
      */
     <T> T asAdaptable(@Nonnull Class<T> clazz);
 
     /**
      * Get collection of configuration resources and adapt them to the given class.
-     * @param clazz Class that can be adapted from a {@link Resource}
+     * @param clazz Class that can be adapted from a {@link org.apache.sling.api.resource.Resource}
+     * @param <T> Annotation class type
      * @return Collection of object instances. Is empty if content resource or configuration cannot be found or if the adaption was not possible.
      */
     @Nonnull <T> Collection<T> asAdaptableCollection(@Nonnull Class<T> clazz);

Added: sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/ConfigurationResourceResolvingStrategy.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/ConfigurationResourceResolvingStrategy.java?rev=1761468&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/ConfigurationResourceResolvingStrategy.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/ConfigurationResourceResolvingStrategy.java Mon Sep 19 15:39:17 2016
@@ -0,0 +1,84 @@
+/*
+ * 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.spi;
+
+import java.util.Collection;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
+import org.apache.sling.api.resource.Resource;
+import org.osgi.annotation.versioning.ConsumerType;
+
+/**
+ * Defines how and where the configuration resources are looked up.
+ * This SPI allows application to define their own configuration storage and inheritance strategies.
+ */
+@ConsumerType
+public interface ConfigurationResourceResolvingStrategy {
+
+    /**
+     * Get a context-aware singleton configuration resource defined by the given configuration name.
+     * @param resource Context resource to fetch configuration for
+     * @param bucketName Configuration "bucket" name. Each high-level configuration resolver should store 
+     *     it's configuration data grouped in a child resource of the configuration resource. This is what
+     *     we call a "bucket", and the resource name is specified with this parameter.
+     * @param configName Configuration name or relative path.
+     * @return Configuration resource or {@code null}.
+     */
+    @CheckForNull Resource getResource(@Nonnull Resource resource, @Nonnull String bucketName, @Nonnull String configName);
+
+    /**
+     * Get a collection of context-aware configuration resources defined by the given configuration name.
+     * @param resource Context resource to fetch configuration for
+     * @param bucketName Configuration "bucket" name. Each high-level configuration resolver should store 
+     *     it's configuration data grouped in a child resource of the configuration resource. This is what
+     *     we call a "bucket", and the resource name is specified with this parameter.
+     * @param configName Configuration name or relative path.
+     * @return Collection of configuration resources, the collection might be empty.
+     */
+    @Nonnull Collection<Resource> getResourceCollection(@Nonnull Resource resource, @Nonnull String bucketName, @Nonnull String configName);
+    
+    /**
+     * Get the configuration resource path for storing configuration data for the given context resource and configuration name.
+     * This path is used when no configuration resource exists yet, but new configuration data should be stored.
+     * So usually the returned path does not yet exist (and perhaps not even it's parents). 
+     * @param resource Context resource to fetch configuration for
+     * @param bucketName Configuration "bucket" name. Each high-level configuration resolver should store 
+     *     it's configuration data grouped in a child resource of the configuration resource. This is what
+     *     we call a "bucket", and the resource name is specified with this parameter.
+     * @param configName Configuration name or relative path.
+     * @return Resource path, or null if no matching configuration resource path can be determined
+     */
+    @CheckForNull String getResourcePath(@Nonnull Resource resource, @Nonnull String bucketName, @Nonnull String configName);
+
+    /**
+     * Get the configuration resource collection parent path for storing configuration data for the given context resource and configuration name.
+     * This path is used when no configuration resource collection exists yet, but new configuration data should be stored.
+     * So usually the returned path does not yet exist (and perhaps not even it's parents). 
+     * @param resource Context resource to fetch configuration for
+     * @param bucketName Configuration "bucket" name. Each high-level configuration resolver should store 
+     *     it's configuration data grouped in a child resource of the configuration resource. This is what
+     *     we call a "bucket", and the resource name is specified with this parameter.
+     * @param configName Configuration name or relative path.
+     * @return Resource path, or null if no matching configuration resource path can be determined
+     */
+    @CheckForNull String getResourceCollectionParentPath(@Nonnull Resource resource, @Nonnull String bucketName, @Nonnull String configName);
+    
+}

Propchange: sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/ConfigurationResourceResolvingStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/ConfigurationResourceResolvingStrategy.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/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/ConfigurationResourceResolvingStrategy.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/ContextPathStrategy.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/ContextPathStrategy.java?rev=1761468&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/ContextPathStrategy.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/ContextPathStrategy.java Mon Sep 19 15:39:17 2016
@@ -0,0 +1,46 @@
+/*
+ * 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.spi;
+
+import java.util.Iterator;
+
+import javax.annotation.Nonnull;
+
+import org.apache.sling.api.resource.Resource;
+import org.osgi.annotation.versioning.ConsumerType;
+
+/**
+ * Allows application to define a strategy to find context paths for content paths.
+ * A context paths is the root path of a "configuration context", which is a subtree in the resource hierarchy.
+ * Each context may have it's own context-aware configuration attached to.0
+ * If multiple context path strategy implementations are defined the results of them are merged.
+ */
+@ConsumerType
+public interface ContextPathStrategy {
+
+    /**
+     * Finds context paths for the given resource.
+     * @param resource Context resource
+     * @return Root resource for each context found (in order of closest matching first).
+     *      Only one of the parent resources or the resource itself may be included in the result.
+     *      If none are found an empty list is returned.
+     */
+    @Nonnull Iterator<Resource> findContextResources(@Nonnull Resource resource);
+
+}

Propchange: sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/ContextPathStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/ContextPathStrategy.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/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/ContextPathStrategy.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/package-info.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/package-info.java?rev=1761468&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/package-info.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/package-info.java Mon Sep 19 15:39:17 2016
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+/**
+ * SPI for applications hooking into the configuration resource infrastructure for parameterizing and customizing.
+ */
+@org.osgi.annotation.versioning.Version("1.0.0")
+package org.apache.sling.contextaware.config.resource.spi;

Propchange: sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/package-info.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/package-info.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/api/src/main/java/org/apache/sling/contextaware/config/resource/spi/package-info.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/ConfigurationPersistenceException.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/ConfigurationPersistenceException.java?rev=1761468&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/ConfigurationPersistenceException.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/ConfigurationPersistenceException.java Mon Sep 19 15:39:17 2016
@@ -0,0 +1,38 @@
+/*
+ * 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.spi;
+
+import org.osgi.annotation.versioning.ProviderType;
+
+/**
+ * Is thrown when configuration cannot be persisted.
+ */
+@ProviderType
+public final class ConfigurationPersistenceException extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+
+    public ConfigurationPersistenceException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public ConfigurationPersistenceException(String message) {
+        super(message);
+    }
+
+}

Propchange: sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/ConfigurationPersistenceException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/ConfigurationPersistenceException.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/api/src/main/java/org/apache/sling/contextaware/config/spi/ConfigurationPersistenceException.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/ConfigurationPersistenceStrategy.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/ConfigurationPersistenceStrategy.java?rev=1761468&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/ConfigurationPersistenceStrategy.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/ConfigurationPersistenceStrategy.java Mon Sep 19 15:39:17 2016
@@ -0,0 +1,67 @@
+/*
+ * 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.spi;
+
+import java.util.Collection;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.osgi.annotation.versioning.ConsumerType;
+
+/**
+ * Defines how configuration data is stored in the configuration resource.
+ * This SPI allows application to define their own content structure and node types to be used for configuration data storage.
+ */
+@ConsumerType
+public interface ConfigurationPersistenceStrategy {
+
+    /**
+     * Allows the strategy to transform the given configuration resource according to it's persistent strategies,
+     * e.g. fetching the data from a child resource instead of the given resource. 
+     * @param resource Configuration resource
+     * @return Transformed configuration resource. If null is returned this strategy does not support the given configuration resource.
+     */
+    Resource getResource(@Nonnull Resource resource);
+    
+    /**
+     * Stores configuration data for a singleton configuration resource.
+     * The changes are written using the given resource resolver. They are not committed, this is left to the caller.
+     * @param resourceResolver Resource resolver
+     * @param configResourcePath Path to store configuration data to. The resource (and it's parents) may not exist and may have to be created. 
+     * @param properties Configuration properties
+     * @return true if the data was persisted. false if persisting the data was not accepted by this persistence strategy (but in case of error throw an exception).
+     */
+    boolean persist(@Nonnull ResourceResolver resourceResolver,
+            @Nonnull String configResourcePath, @Nonnull Map<String,Object> properties);
+    
+    /**
+     * Stores configuration data for a configuration resource collection.
+     * The changes are written using the given resource resolver. They are not committed, this is left to the caller.
+     * @param resourceResolver Resource resolver
+     * @param configResourceCollectionParentPath Parent path to store configuration collection data to. The resource (and it's parents) may not exist and may have to be created. 
+     * @param propertiesCollection Configuration properties
+     * @return true if the data was persisted. false if persisting the data was not accepted by this persistence strategy (but in case of error throw an exception).
+     */
+    boolean persistCollection(@Nonnull ResourceResolver resourceResolver,
+            @Nonnull String configResourceCollectionParentPath, @Nonnull Collection<Map<String,Object>> propertiesCollection);
+    
+}

Propchange: sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/ConfigurationPersistenceStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/ConfigurationPersistenceStrategy.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/api/src/main/java/org/apache/sling/contextaware/config/spi/ConfigurationPersistenceStrategy.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/metadata/AbstractMetadata.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/metadata/AbstractMetadata.java?rev=1761468&r1=1761467&r2=1761468&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/metadata/AbstractMetadata.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/metadata/AbstractMetadata.java Mon Sep 19 15:39:17 2016
@@ -22,12 +22,9 @@ import java.util.Map;
 
 import javax.annotation.Nonnull;
 
-import org.osgi.annotation.versioning.ProviderType;
-
 /**
  * Common properties for configuration and properties.
  */
-@ProviderType
 abstract class AbstractMetadata {
 
     private final String name;

Modified: sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/metadata/ConfigurationMetadata.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/metadata/ConfigurationMetadata.java?rev=1761468&r1=1761467&r2=1761468&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/metadata/ConfigurationMetadata.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/metadata/ConfigurationMetadata.java Mon Sep 19 15:39:17 2016
@@ -18,8 +18,7 @@
  */
 package org.apache.sling.contextaware.config.spi.metadata;
 
-import java.util.Collection;
-import java.util.List;
+import java.util.Map;
 
 import javax.annotation.Nonnull;
 
@@ -32,7 +31,7 @@ import org.osgi.annotation.versioning.Pr
 public final class ConfigurationMetadata extends AbstractMetadata {
 
     private boolean isList;
-    private List<PropertyMetadata<?>> propertyMetadata;
+    private Map<String,PropertyMetadata<?>> propertyMetadata;
 
     /**
      * @param name Configuration name
@@ -65,14 +64,14 @@ public final class ConfigurationMetadata
     /**
      * @return Configuration properties
      */
-    public Collection<PropertyMetadata<?>> getPropertyMetadata() {
+    public Map<String,PropertyMetadata<?>> getPropertyMetadata() {
         return this.propertyMetadata;
     }
 
     /**
      * @param propertyMetadata Configuration properties
      */
-    public void setPropertyMetadata(List<PropertyMetadata<?>> propertyMetadata) {
+    public void setPropertyMetadata(Map<String,PropertyMetadata<?>> propertyMetadata) {
         this.propertyMetadata = propertyMetadata;
     }
 

Modified: sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/metadata/PropertyMetadata.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/metadata/PropertyMetadata.java?rev=1761468&r1=1761467&r2=1761468&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/metadata/PropertyMetadata.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/api/src/main/java/org/apache/sling/contextaware/config/spi/metadata/PropertyMetadata.java Mon Sep 19 15:39:17 2016
@@ -25,6 +25,7 @@ import java.util.Set;
 
 import javax.annotation.Nonnull;
 
+import org.apache.commons.lang3.ClassUtils;
 import org.osgi.annotation.versioning.ProviderType;
 
 /**
@@ -34,6 +35,7 @@ import org.osgi.annotation.versioning.Pr
 @ProviderType
 public final class PropertyMetadata<T> extends AbstractMetadata {
 
+    // these are all types supported for fields of annotation classes (plus class which indicates nested configurations)
     private static final Class<?>[] SUPPORTED_TYPES_ARRAY = {
         String.class,
         int.class,
@@ -51,14 +53,40 @@ public final class PropertyMetadata<T> e
     private final Class<T> type;
     private T defaultValue;
 
+    /**
+     * @param name Property name
+     * @param type Property type
+     */
+    @SuppressWarnings("unchecked")
     public PropertyMetadata(@Nonnull String name, @Nonnull Class<T> type) {
         super(name);
-        if (type == null || !isSupportedType(type)) {
-            throw new IllegalArgumentException("Parameter '" + name + "': Invalid type " + type);
+        Class<T> convertedType = (Class<T>)typeToPrimitive(type);
+        if (!isSupportedType(convertedType)) {
+            throw new IllegalArgumentException("Invalid type for property '" + name + "': " + type);
         }
-        this.type = type;
+        this.type = convertedType;
+    }
+
+    /**
+     * @param name Property name
+     * @param defaultValue Default value (also defines property type)
+     */
+    @SuppressWarnings("unchecked")
+    public PropertyMetadata(@Nonnull String name, @Nonnull T defaultValue) {
+        this(name, (Class<T>)defaultValue.getClass());
+        this.defaultValue = defaultValue;
     }
     
+    private static Class<?> typeToPrimitive(Class<?> clazz) {
+        if (clazz != String.class && !clazz.isPrimitive()) {
+            Class<?> type = ClassUtils.wrapperToPrimitive(clazz);
+            if (type != null) {
+                return type;
+            }
+        }
+        return clazz;
+    }
+
     private static boolean isSupportedType(Class<?> paramType) {
         if (paramType.isArray()) {
             return isSupportedType(paramType.getComponentType());

Modified: sling/trunk/contrib/extensions/contextaware-config/api/src/test/java/org/apache/sling/contextaware/config/spi/metadata/PropertyMetadataTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/api/src/test/java/org/apache/sling/contextaware/config/spi/metadata/PropertyMetadataTest.java?rev=1761468&r1=1761467&r2=1761468&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/api/src/test/java/org/apache/sling/contextaware/config/spi/metadata/PropertyMetadataTest.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/api/src/test/java/org/apache/sling/contextaware/config/spi/metadata/PropertyMetadataTest.java Mon Sep 19 15:39:17 2016
@@ -76,4 +76,15 @@ public class PropertyMetadataTest {
         new PropertyMetadata<>(null, Object.class);
     }
 
+    @Test
+    public void testDefaultValueConstructor() {
+        PropertyMetadata<String> stringProp = new PropertyMetadata<>("name1", "defValue");
+        assertEquals("defValue", stringProp.getDefaultValue());
+        assertEquals(String.class, stringProp.getType());
+        
+        PropertyMetadata<Integer> intProp = new PropertyMetadata<>("name1", 5);
+        assertEquals((Integer)5, intProp.getDefaultValue());
+        assertEquals(int.class, intProp.getType());
+    }
+    
 }

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/pom.xml?rev=1761468&r1=1761467&r2=1761468&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/pom.xml (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/pom.xml Mon Sep 19 15:39:17 2016
@@ -60,6 +60,10 @@
                 <configuration>
                     <!-- Export SCR metadata to classpath to have them available in unit tests -->
                     <exportScr>true</exportScr>
+                    <instructions>
+                        <!-- embed the commons.osgi bundle as described in http://njbartlett.name/2014/05/26/static-linking.html -->
+                        <Conditional-Package>org.apache.sling.commons.osgi</Conditional-Package>
+                    </instructions>
                 </configuration>
             </plugin>
         </plugins>
@@ -100,12 +104,24 @@
             <scope>compile</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.osgi</artifactId>
+            <version>2.4.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
             <version>3.3.2</version>
             <scope>compile</scope>
         </dependency>
         <dependency>
+            <groupId>commons-collections</groupId>
+            <artifactId>commons-collections</artifactId>
+            <version>3.2.1</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.webconsole</artifactId>
             <version>3.0.0</version>

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationBuilderImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationBuilderImpl.java?rev=1761468&r1=1761467&r2=1761468&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationBuilderImpl.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationBuilderImpl.java Mon Sep 19 15:39:17 2016
@@ -18,6 +18,8 @@
  */
 package org.apache.sling.contextaware.config.impl;
 
+import static org.apache.sling.contextaware.config.impl.ConfigurationNameConstants.CONFIGS_PARENT_NAME;
+
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -28,22 +30,29 @@ import org.apache.sling.api.resource.Res
 import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.contextaware.config.ConfigurationBuilder;
 import org.apache.sling.contextaware.config.ConfigurationResolveException;
+import org.apache.sling.contextaware.config.ConfigurationResolver;
+import org.apache.sling.contextaware.config.impl.ConfigurationProxy.ChildResolver;
 import org.apache.sling.contextaware.config.impl.metadata.AnnotationClassParser;
 import org.apache.sling.contextaware.config.resource.ConfigurationResourceResolver;
+import org.apache.sling.contextaware.config.spi.ConfigurationPersistenceStrategy;
 
 class ConfigurationBuilderImpl implements ConfigurationBuilder {
 
-    private static final String CONFIGS_PARENT_NAME = "sling:configs";
-
     private final Resource contentResource;
+    private final ConfigurationResolver configurationResolver;
     private final ConfigurationResourceResolver configurationResourceResolver;
+    private final ConfigurationPersistenceStrategy configurationPersistenceStrategy;
 
     private String configName;
 
     public ConfigurationBuilderImpl(final Resource resource,
-            final ConfigurationResourceResolver configurationResourceResolver) {
+            final ConfigurationResolver configurationResolver,
+            final ConfigurationResourceResolver configurationResourceResolver,
+            final ConfigurationPersistenceStrategy configurationPersistenceStrategy) {
         this.contentResource = resource;
+        this.configurationResolver = configurationResolver;
         this.configurationResourceResolver = configurationResourceResolver;
+        this.configurationPersistenceStrategy = configurationPersistenceStrategy;
     }
 
     @Override
@@ -82,7 +91,7 @@ class ConfigurationBuilderImpl implement
      * @param <T> Target class
      */
     private interface Converter<T> {
-        T convert(Resource resource, Class<T> clazz);
+        T convert(Resource resource, Class<T> clazz, String name);
     }
 
     /**
@@ -98,7 +107,7 @@ class ConfigurationBuilderImpl implement
             validateConfigurationName(name);
             configResource = this.configurationResourceResolver.getResource(this.contentResource, CONFIGS_PARENT_NAME, name);
         }
-        return converter.convert(configResource, clazz);
+        return convert(configResource, clazz, converter, name);
     }
 
     /**
@@ -112,17 +121,26 @@ class ConfigurationBuilderImpl implement
         if (this.contentResource != null) {
            validateConfigurationName(name);
            final Collection<T> result = new ArrayList<>();
-           for(final Resource rsrc : this.configurationResourceResolver.getResourceCollection(this.contentResource, CONFIGS_PARENT_NAME, name)) {
-               final T obj = converter.convert(rsrc, clazz);
-               if ( obj != null ) {
+           for (final Resource rsrc : this.configurationResourceResolver.getResourceCollection(this.contentResource, CONFIGS_PARENT_NAME, name)) {
+               final T obj = convert(rsrc, clazz, converter, name + "/" + rsrc.getName());
+               if (obj != null) {
                    result.add(obj);
                }
            }
            return result;
-        } else {
+        }
+        else {
             return Collections.emptyList();
         }
     }
+    
+    private <T> T convert(Resource resource, Class<T> clazz, Converter<T> converter, String name) {
+        Resource configResource = null;
+        if (resource != null) {
+            configResource = configurationPersistenceStrategy.getResource(resource);
+        }
+        return converter.convert(configResource, clazz, name);
+    }
 
     // --- Annotation class support ---
 
@@ -148,10 +166,23 @@ class ConfigurationBuilderImpl implement
         }
     }
 
-    private static class AnnotationConverter<T> implements Converter<T> {
+    private class AnnotationConverter<T> implements Converter<T> {
         @Override
-        public T convert(Resource resource, Class<T> clazz) {
-            return ConfigurationProxy.get(resource, clazz);
+        public T convert(final Resource resource, final Class<T> clazz, final String name) {
+            return ConfigurationProxy.get(resource, clazz, new ChildResolver() {
+                private ConfigurationBuilder getConfiguration(String configName) {
+                    String childName = name + "/" + configName;
+                    return configurationResolver.get(contentResource).name(childName);
+                }
+                @Override
+                public <C> C getChild(String configName, Class<C> clazz) {
+                    return getConfiguration(configName).as(clazz);
+                }
+                @Override
+                public <C> Collection<C> getChildren(String configName, Class<C> clazz) {
+                    return getConfiguration(configName).asCollection(clazz);
+                }
+            });
         }
     }
     
@@ -169,7 +200,7 @@ class ConfigurationBuilderImpl implement
 
     private static class ValueMapConverter implements Converter<ValueMap> {
         @Override
-        public ValueMap convert(Resource resource, Class<ValueMap> clazz) {
+        public ValueMap convert(Resource resource, Class<ValueMap> clazz, String name) {
             return ResourceUtil.getValueMap(resource);
         }
     }
@@ -188,7 +219,7 @@ class ConfigurationBuilderImpl implement
 
     private static class AdaptableConverter<T> implements Converter<T> {
         @Override
-        public T convert(Resource resource, Class<T> clazz) {
+        public T convert(Resource resource, Class<T> clazz, String name) {
             if (resource == null || clazz == ConfigurationBuilder.class) {
                 return null;
             }

Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationNameConstants.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationNameConstants.java?rev=1761468&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationNameConstants.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationNameConstants.java Mon Sep 19 15:39:17 2016
@@ -0,0 +1,32 @@
+/*
+ * 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;
+
+public final class ConfigurationNameConstants {
+    
+    private ConfigurationNameConstants() {
+        // constants only
+    }
+
+    /**
+     * Node name for configuration data.
+     */
+    public static final String CONFIGS_PARENT_NAME = "sling:configs";
+        
+}

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

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationNameConstants.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/impl/ConfigurationNameConstants.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationProxy.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationProxy.java?rev=1761468&r1=1761467&r2=1761468&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationProxy.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationProxy.java Mon Sep 19 15:39:17 2016
@@ -22,9 +22,8 @@ import java.lang.reflect.Array;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
-import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
 import javax.annotation.Nonnull;
@@ -52,10 +51,11 @@ final class ConfigurationProxy {
      * Get dynamic proxy for given resources's properties mapped to given annotation class.
      * @param resource Resource
      * @param clazz Annotation class
+     * @param childResolver This is used to resolve nested configuration objects relative to the current configuration resource
      * @return Dynamic proxy object
      */
     @SuppressWarnings("unchecked")
-    public @Nonnull static <T> T get(@Nullable Resource resource, @Nonnull Class<T> clazz) {
+    public @Nonnull static <T> T get(@Nullable Resource resource, @Nonnull Class<T> clazz, ChildResolver childResolver) {
 
         // only annotation interface classes are supported
         if (!AnnotationClassParser.isContextAwareConfig(clazz)) {
@@ -66,7 +66,15 @@ final class ConfigurationProxy {
         // wrap in caching invocation handler so client code can call all methods multiple times
         // without having to worry about performance
         return (T)Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] { clazz },
-                new CachingInvocationHandler(new DynamicProxyInvocationHandler(resource)));
+                new CachingInvocationHandler(new DynamicProxyInvocationHandler(resource, childResolver)));
+    }
+    
+    /**
+     * Resolves nested configurations.
+     */
+    public static interface ChildResolver {
+        <T> T getChild(String configName, Class<T> clazz);
+        <T> Collection<T> getChildren(String configName, Class<T> clazz);        
     }
 
     /**
@@ -75,9 +83,11 @@ final class ConfigurationProxy {
     static class DynamicProxyInvocationHandler implements InvocationHandler {
 
         private final Resource resource;
+        private final ChildResolver childResolver;
 
-        private DynamicProxyInvocationHandler(Resource resource) {
+        private DynamicProxyInvocationHandler(Resource resource, ChildResolver childResolver) {
             this.resource = resource;
+            this.childResolver = childResolver;
         }
 
         @Override
@@ -92,19 +102,12 @@ final class ConfigurationProxy {
                 componentType = targetType.getComponentType();
             }
             if (AnnotationClassParser.isContextAwareConfig(componentType)) {
-                Resource childResource = resource != null ? resource.getChild(propName) : null;
                 if (isArray) {
-                    List<Object> listItems = new ArrayList<>();
-                    if ( childResource != null ) {
-                        Iterable<Resource> listItemResources = childResource.getChildren();
-                        for (Resource listItemResource : listItemResources) {
-                            listItems.add(get(listItemResource, componentType));
-                        }
-                    }
+                    Collection<?> listItems = childResolver.getChildren(propName, componentType);
                     return listItems.toArray((Object[])Array.newInstance(componentType, listItems.size()));
                 }
                 else {
-                    return ConfigurationProxy.get(childResource, componentType);
+                    return childResolver.getChild(propName, componentType);
                 }
             }
 
@@ -139,15 +142,15 @@ final class ConfigurationProxy {
 
         }
 
-    }
-
-    /**
-     * Ensures the given type is support for reading configuration parameters.
-     * @param type Type
-     * @return true if type is supported
-     */
-    static boolean isValidType(Class<?> type) {
-        return PropertyMetadata.SUPPORTED_TYPES.contains(type);
+        /**
+         * Ensures the given type is support for reading configuration parameters.
+         * @param type Type
+         * @return true if type is supported
+         */
+        private boolean isValidType(Class<?> type) {
+            return PropertyMetadata.SUPPORTED_TYPES.contains(type);
+        }
+        
     }
 
     /**

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverImpl.java?rev=1761468&r1=1761467&r2=1761468&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverImpl.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/ConfigurationResolverImpl.java Mon Sep 19 15:39:17 2016
@@ -21,20 +21,24 @@ package org.apache.sling.contextaware.co
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.contextaware.config.ConfigurationBuilder;
 import org.apache.sling.contextaware.config.ConfigurationResolver;
+import org.apache.sling.contextaware.config.management.impl.ConfigurationPersistenceStrategyMultiplexer;
 import org.apache.sling.contextaware.config.resource.ConfigurationResourceResolver;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.component.annotations.ReferencePolicyOption;
 
 @Component(service=ConfigurationResolver.class, immediate=true)
 public class ConfigurationResolverImpl implements ConfigurationResolver {
 
-    @Reference(policyOption = ReferencePolicyOption.GREEDY)
+    @Reference
     private ConfigurationResourceResolver configurationResourceResolver;
 
+    @Reference
+    private ConfigurationPersistenceStrategyMultiplexer configurationResourcePersistenceStrategy;
+    
     @Override
     public ConfigurationBuilder get(Resource resource) {
-        return new ConfigurationBuilderImpl(resource, configurationResourceResolver);
+        return new ConfigurationBuilderImpl(resource, this,
+                configurationResourceResolver, configurationResourcePersistenceStrategy);
     }
 
 }

Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/def/DefaultConfigurationPersistenceStrategy.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/def/DefaultConfigurationPersistenceStrategy.java?rev=1761468&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/def/DefaultConfigurationPersistenceStrategy.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/def/DefaultConfigurationPersistenceStrategy.java Mon Sep 19 15:39:17 2016
@@ -0,0 +1,135 @@
+/*
+ * 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 java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+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;
+import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.contextaware.config.spi.ConfigurationPersistenceException;
+import org.apache.sling.contextaware.config.spi.ConfigurationPersistenceStrategy;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.Designate;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+
+/**
+ * The default persistence strategy is quite simple: directly use the configuration resources.
+ * All existing properties are removed when new properties are stored in a singleton config resource.
+ * All existing child resources are removed when a new configs are stored for collection config resources. 
+ */
+@Component(service = ConfigurationPersistenceStrategy.class)
+@Designate(ocd=DefaultConfigurationPersistenceStrategy.Config.class)
+public class DefaultConfigurationPersistenceStrategy implements ConfigurationPersistenceStrategy {
+
+    @ObjectClassDefinition(name="Apache Sling Context-Aware Default Configuration Resource Persistence Strategy",
+            description="Directly uses configuration resources for storing configuration data.")
+    static @interface Config {
+        
+        @AttributeDefinition(name="Enabled",
+                      description = "Enable this configuration resource persistence strategy.")
+        boolean enabled() default true;
+
+    }
+
+    private volatile Config config;
+    
+    @Activate
+    private void activate(ComponentContext componentContext, Config config) {
+        this.config = config; 
+    }
+        
+    @Override
+    public Resource getResource(Resource resource) {
+        if (!config.enabled()) {
+            return null;
+        }
+        return resource;
+    }
+
+    @Override
+    public boolean persist(ResourceResolver resourceResolver, String configResourcePath, Map<String,Object> properties) {
+        if (!config.enabled()) {
+            return false;
+        }
+        getOrCreateResource(resourceResolver, configResourcePath, properties);
+        return true;
+    }
+
+    @Override
+    public boolean persistCollection(ResourceResolver resourceResolver, String configResourceCollectionParentPath,
+            Collection<Map<String,Object>> propertiesCollection) {
+        if (!config.enabled()) {
+            return false;
+        }
+        Resource configResourceParent = getOrCreateResource(resourceResolver, configResourceCollectionParentPath, ValueMap.EMPTY);
+        deleteChildren(configResourceParent);
+        int index = 0;
+        for (Map<String,Object> properties : propertiesCollection) {
+            String path = configResourceParent.getPath() + "/" + (index++);
+            getOrCreateResource(resourceResolver, path, properties);
+        }
+        return true;
+    }
+    
+    private Resource getOrCreateResource(ResourceResolver resourceResolver, String path, Map<String,Object> properties) {
+        try {
+            Resource resource = ResourceUtil.getOrCreateResource(resourceResolver, path, (String)null, (String)null, false);
+            replaceProperties(resource, properties);
+            return resource;
+        }
+        catch (PersistenceException ex) {
+            throw new ConfigurationPersistenceException("Unable to persist configuration to " + path, ex);
+        }
+    }
+
+    private void deleteChildren(Resource resource) {
+        ResourceResolver resourceResolver = resource.getResourceResolver();
+        try {
+            for (Resource child : resource.getChildren()) {
+                resourceResolver.delete(child);
+            }
+        }
+        catch (PersistenceException ex) {
+            throw new ConfigurationPersistenceException("Unable to remove children from " + resource.getPath(), ex);
+        }
+    }
+    
+    private void replaceProperties(Resource resource, Map<String,Object> properties) {
+        ModifiableValueMap modValueMap = resource.adaptTo(ModifiableValueMap.class);
+        // remove all existing properties that do not have jcr: or sling: namespace
+        for (String propertyName : new HashSet<>(modValueMap.keySet())) {
+            if (StringUtils.startsWith(propertyName, "jcr:") || StringUtils.startsWith(propertyName, "sling:")) {
+                continue;
+            }
+            modValueMap.remove(propertyName);
+        }
+        modValueMap.putAll(properties);
+    }
+
+}

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

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/def/DefaultConfigurationPersistenceStrategy.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/impl/def/DefaultConfigurationPersistenceStrategy.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/metadata/AnnotationClassParser.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/metadata/AnnotationClassParser.java?rev=1761468&r1=1761467&r2=1761468&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/metadata/AnnotationClassParser.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/metadata/AnnotationClassParser.java Mon Sep 19 15:39:17 2016
@@ -19,10 +19,8 @@
 package org.apache.sling.contextaware.config.impl.metadata;
 
 import java.lang.reflect.Method;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -84,7 +82,7 @@ public final class AnnotationClassParser
     /**
      * Implements the method name mapping as defined in OSGi R6 Compendium specification,
      * Chapter 112. Declarative Services Specification, Chapter 112.8.2.1. Component Property Mapping.
-     * @param Method
+     * @param methodName Method name
      * @return Mapped property name
      */
     public static String getPropertyName(String methodName) {
@@ -129,10 +127,11 @@ public final class AnnotationClassParser
         configMetadata.setProperties(propsArrayToMap(configAnnotation.property()));
 
         // property metadata
-        List<PropertyMetadata<?>> propertyMetadataList = new ArrayList<>();
+        Map<String,PropertyMetadata<?>> propertyMetadataList = new HashMap<>();
         Method[] propertyMethods = clazz.getDeclaredMethods();
         for (Method propertyMethod : propertyMethods) {
-            propertyMetadataList.add(buildPropertyMetadata(propertyMethod, propertyMethod.getReturnType()));
+            PropertyMetadata<?> propertyMetadata = buildPropertyMetadata(propertyMethod, propertyMethod.getReturnType());
+            propertyMetadataList.put(propertyMetadata.getName(), propertyMetadata);
         }
         configMetadata.setPropertyMetadata(propertyMetadataList);
         

Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/metadata/ConfigurationMetadataProviderMultiplexer.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/metadata/ConfigurationMetadataProviderMultiplexer.java?rev=1761468&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/metadata/ConfigurationMetadataProviderMultiplexer.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/metadata/ConfigurationMetadataProviderMultiplexer.java Mon Sep 19 15:39:17 2016
@@ -0,0 +1,84 @@
+/*
+ * 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 java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.sling.commons.osgi.Order;
+import org.apache.sling.commons.osgi.RankedServices;
+import org.apache.sling.contextaware.config.spi.ConfigurationMetadataProvider;
+import org.apache.sling.contextaware.config.spi.metadata.ConfigurationMetadata;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
+
+/**
+ * Detects all {@link ConfigurationMetadataProvider} implementations in the container
+ * and consolidates their result based on service ranking.
+ */
+@Component(service = ConfigurationMetadataProviderMultiplexer.class,
+reference={
+        @Reference(name="configurationMetadataProvider", service=ConfigurationMetadataProvider.class,
+                bind="bindConfigurationMetadataProvider", unbind="unbindConfigurationMetadataProvider",
+                cardinality=ReferenceCardinality.MULTIPLE,
+                policy=ReferencePolicy.DYNAMIC, policyOption=ReferencePolicyOption.GREEDY)
+})
+public class ConfigurationMetadataProviderMultiplexer implements ConfigurationMetadataProvider {
+    
+    private RankedServices<ConfigurationMetadataProvider> items = new RankedServices<>(Order.DESCENDING);
+        
+    protected void bindConfigurationMetadataProvider(ConfigurationMetadataProvider configurationMetadataProvider, Map<String, Object> props) {
+        items.bind(configurationMetadataProvider, props);
+    }
+    
+    protected void unbindConfigurationMetadataProvider(ConfigurationMetadataProvider configurationMetadataProvider, Map<String, Object> props) {
+        items.unbind(configurationMetadataProvider, props);
+    }
+
+    /**
+     * Merge configuration names from all providers.
+     */
+    @Override
+    public SortedSet<String> getConfigurationNames() {
+        SortedSet<String> configNames = new TreeSet<>();
+        for (ConfigurationMetadataProvider item : items) {
+            configNames.addAll(item.getConfigurationNames());
+        }
+        return configNames;
+    }
+
+    /**
+     * Get configuration metadata from first provider (ranking priority) that has an answer.
+     */
+    @Override
+    public ConfigurationMetadata getConfigurationMetadata(String configName) {
+        for (ConfigurationMetadataProvider item : items) {
+            ConfigurationMetadata configMetadata = item.getConfigurationMetadata(configName);
+            if (configMetadata != null) {
+                return configMetadata;
+            }
+        }
+        return null;
+    }
+
+}

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

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/impl/metadata/ConfigurationMetadataProviderMultiplexer.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/impl/metadata/ConfigurationMetadataProviderMultiplexer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/ConfigurationData.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/ConfigurationData.java?rev=1761468&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/ConfigurationData.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/ConfigurationData.java Mon Sep 19 15:39:17 2016
@@ -0,0 +1,60 @@
+/*
+ * 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;
+
+import java.util.Set;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
+import org.apache.sling.api.resource.ValueMap;
+import org.osgi.annotation.versioning.ProviderType;
+
+/**
+ * Provides access to the configuration data and metadata for a given context path.
+ */
+@ProviderType
+public interface ConfigurationData {
+
+    /**
+     * List of property names defined in configuration metadata or values are defined for.
+     * @return Property names
+     */
+    @Nonnull Set<String> getPropertyNames();
+
+    /**
+     * Configuration values stored for the given context path. No inherited values. No default values.
+     * @return Values
+     */
+    @Nonnull ValueMap getValues();
+
+    /**
+     * Configuration values stored for the given context path merged with inherited values and default values.
+     * @return Values
+     */
+    @Nonnull ValueMap getEffectiveValues();
+
+    /**
+     * Get detailed metadata information about the property value.
+     * @param propertyName Property name
+     * @return Value information. Null if neither property metadata nor an existing value exists.
+     */
+    @CheckForNull ValueInfo<?> getValueInfo(String propertyName);
+    
+}

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

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/ConfigurationData.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/management/ConfigurationData.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/ConfigurationManager.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/ConfigurationManager.java?rev=1761468&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/ConfigurationManager.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/ConfigurationManager.java Mon Sep 19 15:39:17 2016
@@ -0,0 +1,77 @@
+/*
+ * 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;
+
+import java.util.Collection;
+import java.util.Map;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
+import org.apache.sling.api.resource.Resource;
+import org.osgi.annotation.versioning.ProviderType;
+
+/**
+ * Manages reading and writing configurations e.g. for Editor GUIs.
+ * It manages only configurations handled by {@link org.apache.sling.contextaware.config.ConfigurationResolver},
+ * no low-level configuration resources managed by {@link org.apache.sling.contextaware.config.resource.ConfigurationResourceResolver}.
+ */
+@ProviderType
+public interface ConfigurationManager {
+
+    /**
+     * Get configuration data for the given context resource and configuration name.
+     * @param resource Context resource
+     * @param configName Configuration name
+     * @return Configuration data. Is null when no configuration resource found and no configuration metadata exists.
+     */
+    @CheckForNull ConfigurationData get(@Nonnull Resource resource, @Nonnull String configName);
+
+    /**
+     * Get configuration data collection for the given context resource and configuration name.
+     * @param resource Context resource
+     * @param configName Configuration name
+     * @return Configuration data collection. Is empty when no configuration resources found.
+     */
+    @Nonnull Collection<ConfigurationData> getCollection(@Nonnull Resource resource, @Nonnull String configName);
+    
+    /**
+     * Write configuration to repository data using the inner-most context path as reference.
+     * @param resource Context resource
+     * @param configName Configuration name
+     * @param values Values to be stored. All existing properties are erased and replaced with the new ones.
+     */
+    void persist(@Nonnull Resource resource, @Nonnull String configName, @Nonnull Map<String,Object> values);
+
+    /**
+     * Write configuration data collection using the inner-most context path as reference.
+     * @param resource Context resource
+     * @param configName Configuration name
+     * @param values Value collection to be stored. All existing collection entries on this context path level are erased and replaced with the new ones.
+     */
+    void persistCollection(@Nonnull Resource resource, @Nonnull String configName, @Nonnull Collection<Map<String,Object>> values);
+    
+    /**
+     * Creates a new empty configuration data item for a configuration data collection for the given configuration name.
+     * @param configName Configuration name
+     * @return Configuration data. Is null when no configuration metadata exists.
+     */
+    @CheckForNull ConfigurationData newCollectionItem(@Nonnull String configName);
+    
+}

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

Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/contextaware/config/management/ConfigurationManager.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/management/ConfigurationManager.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain