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/11/17 18:03:45 UTC

svn commit: r1770253 - in /sling/trunk/contrib/extensions/contextaware-config/impl/src: main/java/org/apache/sling/caconfig/management/ main/java/org/apache/sling/caconfig/management/impl/ test/java/org/apache/sling/caconfig/management/impl/

Author: sseifert
Date: Thu Nov 17 18:03:45 2016
New Revision: 1770253

URL: http://svn.apache.org/viewvc?rev=1770253&view=rev
Log:
SLING-6137 Context-Aware Config: Configuration Manager - Support resource collection and property inheritance

Modified:
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/ConfigurationData.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/ValueInfo.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/impl/ConfigurationDataImpl.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/impl/ConfigurationManagerImpl.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/impl/ValueInfoImpl.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/package-info.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/management/impl/ConfigurationDataImplTest.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/management/impl/ConfigurationManagerImplTest.java
    sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/management/impl/ValueInfoImplTest.java

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/ConfigurationData.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/ConfigurationData.java?rev=1770253&r1=1770252&r2=1770253&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/ConfigurationData.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/ConfigurationData.java Thu Nov 17 18:03:45 2016
@@ -31,15 +31,25 @@ import org.osgi.annotation.versioning.Pr
  */
 @ProviderType
 public interface ConfigurationData {
+    
+    /**
+     * Path of the configuration resource. The resource may not exist, in this case
+     * inherited or default values may be returned.
+     * If the configuration data is saved, this path is used.
+     * @return Configuration resource path or null if it cannot be determined
+     */
+    @CheckForNull String getResourcePath();
 
     /**
-     * List of property names defined in configuration metadata or values are defined for.
+     * List of effective 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.
+     * The properties of the resource identified by {@link #getResourcePath()} are returned.
+     * If this resources does not exist, the map is empty.
      * @return Values
      */
     @Nonnull ValueMap getValues();

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/ValueInfo.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/ValueInfo.java?rev=1770253&r1=1770252&r2=1770253&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/ValueInfo.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/ValueInfo.java Thu Nov 17 18:03:45 2016
@@ -19,6 +19,7 @@
 package org.apache.sling.caconfig.management;
 
 import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
 
 import org.apache.sling.caconfig.spi.metadata.PropertyMetadata;
 import org.osgi.annotation.versioning.ProviderType;
@@ -31,6 +32,12 @@ import org.osgi.annotation.versioning.Pr
 public interface ValueInfo<T> {
 
     /**
+     * Property name.
+     * @return Property name.
+     */
+    @Nonnull String getName();
+    
+    /**
      * Property metadata.
      * @return Property metadata. Null if no metadata exists.
      */
@@ -62,8 +69,7 @@ public interface ValueInfo<T> {
     /**
      * @return true if the value is not defined for the current context path but inherited from upper levels.
      */
-    // for future use
-    //boolean isInherited();
+    boolean isInherited();
     
     /**
      * @return true if the value is overridden by an configuration override provider.

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/impl/ConfigurationDataImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/impl/ConfigurationDataImpl.java?rev=1770253&r1=1770252&r2=1770253&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/impl/ConfigurationDataImpl.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/impl/ConfigurationDataImpl.java Thu Nov 17 18:03:45 2016
@@ -20,10 +20,14 @@ package org.apache.sling.caconfig.manage
 
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.commons.collections.IteratorUtils;
 import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceUtil;
 import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.api.wrappers.ValueMapDecorator;
 import org.apache.sling.caconfig.management.ConfigurationData;
@@ -33,22 +37,32 @@ import org.apache.sling.caconfig.spi.met
 
 final class ConfigurationDataImpl implements ConfigurationData {
     
-    private final ValueMap properties;
-    private final String configSourcePath;
     private final ConfigurationMetadata configMetadata;
+    private final Resource resolvedConfigurationResource;
+    private final Resource writebackConfigurationResource;
+    private final List<Resource> configurationResourceInheritanceChain;
     
-    public ConfigurationDataImpl(Resource configResource, ConfigurationMetadata configMetadata) {
-        this(configResource.getValueMap(), configResource.getPath(), configMetadata);
+    @SuppressWarnings("unchecked")
+    public ConfigurationDataImpl(ConfigurationMetadata configMetadata,
+            Resource resolvedConfigurationResource, Resource writebackConfigurationResource,
+            Iterator<Resource> configurationResourceInheritanceChain) {
+        this.configMetadata = configMetadata;
+        this.resolvedConfigurationResource = resolvedConfigurationResource;
+        this.writebackConfigurationResource = writebackConfigurationResource;
+        this.configurationResourceInheritanceChain = configurationResourceInheritanceChain != null
+                ? IteratorUtils.toList(configurationResourceInheritanceChain) : null;
     }
 
     public ConfigurationDataImpl(ConfigurationMetadata configMetadata) {
-        this(ValueMap.EMPTY, null, configMetadata);
+        this(configMetadata, null, null, null);
     }
 
-    private ConfigurationDataImpl(ValueMap propertes, String configSourcePath, ConfigurationMetadata configMetadata) {
-        this.properties = propertes;
-        this.configSourcePath = configSourcePath;
-        this.configMetadata = configMetadata;
+    @Override
+    public String getResourcePath() {
+        if (writebackConfigurationResource != null) {
+            return writebackConfigurationResource.getPath();
+        }
+        return null;
     }
 
     @Override
@@ -57,13 +71,18 @@ final class ConfigurationDataImpl implem
         if (configMetadata != null) {
             propertyNames.addAll(configMetadata.getPropertyMetadata().keySet());
         }
-        propertyNames.addAll(properties.keySet());
+        if (resolvedConfigurationResource != null) {
+            propertyNames.addAll(ResourceUtil.getValueMap(resolvedConfigurationResource).keySet());
+        }
         return propertyNames;
     }
 
     @Override
     public ValueMap getValues() {
-        return properties;
+        if (writebackConfigurationResource != null) {
+            return ResourceUtil.getValueMap(writebackConfigurationResource);
+        }
+        return ValueMap.EMPTY;
     }
 
     @Override
@@ -76,7 +95,9 @@ final class ConfigurationDataImpl implem
                 }
             }
         }
-        props.putAll(properties);
+        if (resolvedConfigurationResource != null) {
+            props.putAll(ResourceUtil.getValueMap(resolvedConfigurationResource));
+        }
         return new ValueMapDecorator(props);
     }
 
@@ -85,13 +106,18 @@ final class ConfigurationDataImpl implem
     public ValueInfo<?> getValueInfo(String propertyName) {
         PropertyMetadata propertyMetadata = configMetadata != null ? configMetadata.getPropertyMetadata().get(propertyName) : null;
         Object value;
+        ValueMap properties = ResourceUtil.getValueMap(resolvedConfigurationResource);
         if (propertyMetadata != null) {
             value = properties.get(propertyName, propertyMetadata.getType());
         }
         else {
             value = properties.get(propertyName);
         }
-        return new ValueInfoImpl(value, configSourcePath, propertyMetadata);
+        return new ValueInfoImpl(propertyName, value,
+                propertyMetadata,
+                resolvedConfigurationResource,
+                writebackConfigurationResource,
+                configurationResourceInheritanceChain);
     }
 
 }

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/impl/ConfigurationManagerImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/impl/ConfigurationManagerImpl.java?rev=1770253&r1=1770252&r2=1770253&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/impl/ConfigurationManagerImpl.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/impl/ConfigurationManagerImpl.java Thu Nov 17 18:03:45 2016
@@ -22,14 +22,19 @@ import static org.apache.sling.caconfig.
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.collections.IteratorUtils;
+import org.apache.commons.collections.ResettableIterator;
+import org.apache.commons.collections.Transformer;
+import org.apache.commons.collections.iterators.ListIteratorWrapper;
 import org.apache.sling.api.resource.Resource;
+import org.apache.sling.caconfig.impl.ConfigurationInheritanceStrategyMultiplexer;
 import org.apache.sling.caconfig.impl.metadata.ConfigurationMetadataProviderMultiplexer;
 import org.apache.sling.caconfig.management.ConfigurationData;
 import org.apache.sling.caconfig.management.ConfigurationManager;
-import org.apache.sling.caconfig.resource.ConfigurationResourceResolver;
 import org.apache.sling.caconfig.resource.impl.ConfigurationResourceResolvingStrategyMultiplexer;
 import org.apache.sling.caconfig.spi.ConfigurationPersistenceException;
 import org.apache.sling.caconfig.spi.metadata.ConfigurationMetadata;
@@ -40,20 +45,35 @@ import org.osgi.service.component.annota
 public class ConfigurationManagerImpl implements ConfigurationManager {
     
     @Reference
-    private ConfigurationResourceResolver configurationResourceResolver;
-    @Reference
     private ConfigurationResourceResolvingStrategyMultiplexer configurationResourceResolvingStrategy;
     @Reference
     private ConfigurationMetadataProviderMultiplexer configurationMetadataProvider;
     @Reference
     private ConfigurationPersistenceStrategyMultiplexer configurationPersistenceStrategy;
+    @Reference
+    private ConfigurationInheritanceStrategyMultiplexer configurationInheritanceStrategy;
 
+    @SuppressWarnings("unchecked")
     @Override
     public ConfigurationData get(Resource resource, String configName) {
         ConfigurationMetadata configMetadata = configurationMetadataProvider.getConfigurationMetadata(configName);
-        Resource configResource = configurationResourceResolver.getResource(resource, CONFIGS_PARENT_NAME, configName);
+        Iterator<Resource> configResourceInheritanceChain = configurationResourceResolvingStrategy
+                .getResourceInheritanceChain(resource, CONFIGS_PARENT_NAME, configName);
+        ResettableIterator resettableConfigResourceInheritanceChain = new ListIteratorWrapper(configResourceInheritanceChain);
+        Resource configResource = applyPersistenceAndInheritance(resettableConfigResourceInheritanceChain);
         if (configResource != null) {
-            return new ConfigurationDataImpl(configurationPersistenceStrategy.getResource(configResource), configMetadata);
+            // get writeback resource for "reverse inheritance detection"
+            Resource writebackConfigResource = null;
+            String writebackConfigResourcePath = configurationResourceResolvingStrategy.getResourcePath(resource, CONFIGS_PARENT_NAME, configName);
+            if (writebackConfigResourcePath != null) {
+                writebackConfigResource = configResource.getResourceResolver().getResource(writebackConfigResourcePath);
+                if (writebackConfigResource != null) {
+                    writebackConfigResource = configurationPersistenceStrategy.getResource(writebackConfigResource);
+                }
+            }
+            resettableConfigResourceInheritanceChain.reset();
+            return new ConfigurationDataImpl(configMetadata, configResource, writebackConfigResource,
+                    applyPersistence(resettableConfigResourceInheritanceChain));
         }
         if (configMetadata != null) {
             // if no config resource found but config metadata exist return empty config data with default values
@@ -62,16 +82,63 @@ public class ConfigurationManagerImpl im
         return null;
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     public Collection<ConfigurationData> getCollection(Resource resource, String configName) {
         ConfigurationMetadata configMetadata = configurationMetadataProvider.getConfigurationMetadata(configName);
-        Collection<Resource> configResources = configurationResourceResolver.getResourceCollection(resource, CONFIGS_PARENT_NAME, configName);
+        String writebackConfigResourceCollectionParentPath = configurationResourceResolvingStrategy.getResourceCollectionParentPath(resource, CONFIGS_PARENT_NAME, configName);
         List<ConfigurationData> configData = new ArrayList<>();
-        for (Resource configResource : configResources) {
-            configData.add(new ConfigurationDataImpl(configurationPersistenceStrategy.getResource(configResource), configMetadata));
+
+        Collection<Iterator<Resource>> configResourceInheritanceChains = configurationResourceResolvingStrategy
+                .getResourceCollectionInheritanceChain(resource, CONFIGS_PARENT_NAME, configName);
+        for (Iterator<Resource> configResourceInheritanceChain : configResourceInheritanceChains) {
+            ResettableIterator resettableConfigResourceInheritanceChain = new ListIteratorWrapper(configResourceInheritanceChain);
+            Resource configResource = applyPersistenceAndInheritance(resettableConfigResourceInheritanceChain);
+            if (configResource != null) {
+                // get writeback resource for "reverse inheritance detection"
+                Resource writebackConfigResource = null;
+                if (writebackConfigResourceCollectionParentPath != null) {
+                    resettableConfigResourceInheritanceChain.reset();
+                    Resource untransformedConfigResource = (Resource)resettableConfigResourceInheritanceChain.next();
+                    writebackConfigResource = configResource.getResourceResolver().getResource(
+                            writebackConfigResourceCollectionParentPath + "/" + untransformedConfigResource.getName());
+                    if (writebackConfigResource != null) {
+                        writebackConfigResource = configurationPersistenceStrategy.getResource(writebackConfigResource);
+                    }
+                }
+                resettableConfigResourceInheritanceChain.reset();
+                configData.add(new ConfigurationDataImpl(configMetadata, configResource, writebackConfigResource,
+                        applyPersistence(resettableConfigResourceInheritanceChain)));
+            }
         }
         return configData;
     }
+    
+    @SuppressWarnings("unchecked")
+    private Iterator<Resource> applyPersistence(Iterator<Resource> configResourceInheritanceChain) {
+        if (configResourceInheritanceChain == null) {
+            return null;
+        }
+        return IteratorUtils.transformedIterator(configResourceInheritanceChain,
+                new Transformer() {
+                    @Override
+                    public Object transform(Object input) {
+                        return configurationPersistenceStrategy.getResource((Resource)input);
+                    }
+                });
+    }
+
+    private Resource applyPersistenceAndInheritance(Iterator<Resource> configResourceInheritanceChain) {
+        if (configResourceInheritanceChain == null) {
+            return null;
+        }
+        
+        // apply configuration persistence transformation
+        Iterator<Resource> transformedConfigResources = applyPersistence(configResourceInheritanceChain);
+        
+        // apply resource inheritance
+        return configurationInheritanceStrategy.getResource(transformedConfigResources);
+    }
 
     @Override
     public void persist(Resource resource, String configName, Map<String,Object> values) {

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/impl/ValueInfoImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/impl/ValueInfoImpl.java?rev=1770253&r1=1770252&r2=1770253&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/impl/ValueInfoImpl.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/impl/ValueInfoImpl.java Thu Nov 17 18:03:45 2016
@@ -18,24 +18,42 @@
  */
 package org.apache.sling.caconfig.management.impl;
 
+import java.util.Iterator;
+import java.util.List;
+
 import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.api.resource.Resource;
 import org.apache.sling.caconfig.management.ValueInfo;
 import org.apache.sling.caconfig.spi.metadata.PropertyMetadata;
 
 final class ValueInfoImpl<T> implements ValueInfo<T> {
     
+    private final String name;
     private final T value;
     private final T defaultValue;
-    private final String configSourcePath;
     private final PropertyMetadata<T> propertyMetadata;
+    private final Resource resolvedConfigurationResource;
+    private final Resource writebackConfigurationResource;
+    private final List<Resource> configurationResourceInheritanceChain;
     
-    public ValueInfoImpl(T value, String configSourcePath, PropertyMetadata<T> propertyMetadata) {
+    public ValueInfoImpl(String name, T value, PropertyMetadata<T> propertyMetadata,
+            Resource resolvedConfigurationResource, Resource writebackConfigurationResource,
+            List<Resource> configurationResourceInheritanceChain) {
+        this.name = name;
         this.value = value;
         this.defaultValue = propertyMetadata != null ? propertyMetadata.getDefaultValue() : null;
-        this.configSourcePath = configSourcePath;
         this.propertyMetadata = propertyMetadata;
+        this.resolvedConfigurationResource = resolvedConfigurationResource;
+        this.writebackConfigurationResource = writebackConfigurationResource;
+        this.configurationResourceInheritanceChain = configurationResourceInheritanceChain;
     }
-
+    
+    @Override
+    public String getName() {
+        return name;
+    }
+ 
     @Override
     public PropertyMetadata<T> getPropertyMetadata() {
         return propertyMetadata;
@@ -53,7 +71,13 @@ final class ValueInfoImpl<T> implements
 
     @Override
     public String getConfigSourcePath() {
-        return configSourcePath;
+        if (value != null && resolvedConfigurationResource != null) {
+            Resource resource = getResourceFromInheritanceChain();
+            if (resource != null) {
+                return resource.getPath();
+            }
+        }
+        return null;
     }
 
     @Override
@@ -61,4 +85,47 @@ final class ValueInfoImpl<T> implements
         return value == null && defaultValue != null;
     }
 
+    @Override
+    public boolean isInherited() {
+        if (isDefault() || value == null) {
+            return false;
+        }
+        else if (resolvedConfigurationResource == null) {
+            return false;
+        }
+        else if (writebackConfigurationResource == null) {
+            return true;
+        }
+        else if (!StringUtils.equals(resolvedConfigurationResource.getPath(), writebackConfigurationResource.getPath())) {
+            return true;
+        }
+        else {
+            Resource inheritanceSource = getResourceFromInheritanceChain();
+            if (inheritanceSource != null) {
+                return !StringUtils.equals(resolvedConfigurationResource.getPath(), inheritanceSource.getPath());
+            }
+            else {
+                return false;
+            }
+        }
+    }
+    
+    private Resource getResourceFromInheritanceChain() {
+        if (configurationResourceInheritanceChain == null) {
+            return null;
+        }
+        return getResourceFromInheritanceChain(configurationResourceInheritanceChain.iterator());
+    }
+
+    private Resource getResourceFromInheritanceChain(Iterator<Resource> inheritanceChain) {
+        if (!inheritanceChain.hasNext()) {
+            return null;
+        }
+        Resource resource = inheritanceChain.next();
+        Object valueFromResource = resource.getValueMap().get(name, value.getClass());
+        if (valueFromResource != null) {
+            return resource;
+        }
+        return getResourceFromInheritanceChain(inheritanceChain);
+    }
 }

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/package-info.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/package-info.java?rev=1770253&r1=1770252&r2=1770253&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/package-info.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/management/package-info.java Thu Nov 17 18:03:45 2016
@@ -21,5 +21,5 @@
  * This API is only indented for advanced use cases like writing a configuration editor,
  * not for "normal" applications just reading configuration.
  */
-@org.osgi.annotation.versioning.Version("1.0.0")
+@org.osgi.annotation.versioning.Version("1.1.0")
 package org.apache.sling.caconfig.management;

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/management/impl/ConfigurationDataImplTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/management/impl/ConfigurationDataImplTest.java?rev=1770253&r1=1770252&r2=1770253&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/management/impl/ConfigurationDataImplTest.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/management/impl/ConfigurationDataImplTest.java Thu Nov 17 18:03:45 2016
@@ -44,7 +44,6 @@ public class ConfigurationDataImplTest {
     private Resource configResource;
     private ConfigurationMetadata configMetadata;
     
-    
     @Before
     public void setUp() {
         configResource = context.create().resource("/conf/test",
@@ -59,8 +58,9 @@ public class ConfigurationDataImplTest {
 
     @Test
     public void testWithResourceMetadata() {
-        ConfigurationData underTest = new ConfigurationDataImpl(configResource, configMetadata);
+        ConfigurationData underTest = new ConfigurationDataImpl(configMetadata, configResource, configResource, null);
         
+        assertEquals(configResource.getPath(), underTest.getResourcePath());
         assertEquals(ImmutableSet.of("prop1", "prop2", "prop3", "prop4"), underTest.getPropertyNames());
         
         ValueMap values = underTest.getValues();
@@ -93,7 +93,7 @@ public class ConfigurationDataImplTest {
 
     @Test
     public void testWithResourceOnly() {
-        ConfigurationData underTest = new ConfigurationDataImpl(configResource, null);
+        ConfigurationData underTest = new ConfigurationDataImpl(null, configResource, configResource, null);
         
         assertEquals(ImmutableSet.of("prop1", "prop4"), underTest.getPropertyNames());
         

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/management/impl/ConfigurationManagerImplTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/management/impl/ConfigurationManagerImplTest.java?rev=1770253&r1=1770252&r2=1770253&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/management/impl/ConfigurationManagerImplTest.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/management/impl/ConfigurationManagerImplTest.java Thu Nov 17 18:03:45 2016
@@ -19,11 +19,14 @@
 package org.apache.sling.caconfig.management.impl;
 
 import static org.apache.sling.caconfig.impl.ConfigurationNameConstants.CONFIGS_PARENT_NAME;
+import static org.apache.sling.caconfig.impl.def.ConfigurationDefNameConstants.PROPERTY_CONFIG_PROPERTY_INHERIT;
+import static org.apache.sling.caconfig.resource.impl.def.ConfigurationResourceNameConstants.PROPERTY_CONFIG_COLLECTION_INHERIT;
+import static org.apache.sling.caconfig.resource.impl.def.ConfigurationResourceNameConstants.PROPERTY_CONFIG_REF;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 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.junit.Assert.assertTrue;
 import static org.mockito.Mockito.when;
 
 import java.util.List;
@@ -31,13 +34,10 @@ import java.util.Map;
 
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ValueMap;
-import org.apache.sling.caconfig.impl.def.DefaultConfigurationPersistenceStrategy;
+import org.apache.sling.caconfig.impl.ConfigurationTestUtils;
 import org.apache.sling.caconfig.impl.metadata.ConfigurationMetadataProviderMultiplexer;
 import org.apache.sling.caconfig.management.ConfigurationData;
 import org.apache.sling.caconfig.management.ConfigurationManager;
-import org.apache.sling.caconfig.resource.ConfigurationResourceResolver;
-import org.apache.sling.caconfig.resource.impl.ConfigurationResourceResolvingStrategyMultiplexer;
-import org.apache.sling.caconfig.resource.spi.ConfigurationResourceResolvingStrategy;
 import org.apache.sling.caconfig.spi.ConfigurationMetadataProvider;
 import org.apache.sling.caconfig.spi.metadata.ConfigurationMetadata;
 import org.apache.sling.caconfig.spi.metadata.PropertyMetadata;
@@ -60,55 +60,74 @@ public class ConfigurationManagerImplTes
     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 Resource contextResourceLevel2;
+    private Resource contextResourceLevel3;
+    private Resource contextResourceNoConfig;
     private ConfigurationMetadata configMetadata;
     
-    private static final String CONFIG_NAME = "testConfigName";
-    
+    private static final String CONFIG_NAME = "testConfig";
+    private static final String CONFIG_COL_NAME = "testConfigCol";
+   
     @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());
+        ConfigurationTestUtils.registerConfigurationResolver(context);
         underTest = context.registerInjectActivateService(new ConfigurationManagerImpl());
         
-        contextResource = context.create().resource("/content/test");
+        contextResource = context.create().resource("/content/test",
+                PROPERTY_CONFIG_REF, "/conf/test");
+        contextResourceLevel2 = context.create().resource("/content/test/level2",
+                PROPERTY_CONFIG_REF, "/conf/test/level2");
+        contextResourceLevel3 = context.create().resource("/content/test/level2/level3",
+                PROPERTY_CONFIG_REF, "/conf/test/level2/level3");
+        contextResourceNoConfig = context.create().resource("/content/testNoConfig",
+                PROPERTY_CONFIG_REF, "/conf/testNoConfig");
         
-        context.create().resource(getConfigPropertiesPath("/conf/test"),
+        context.create().resource(getConfigPropertiesPath("/conf/test/" + CONFIGS_PARENT_NAME + "/" + CONFIG_NAME),
                 "prop1", "value1",
                 "prop4", true);
-        context.create().resource(getConfigPropertiesPath("/conf/item/1"),
+        context.create().resource(getConfigPropertiesPath("/conf/test/" + CONFIGS_PARENT_NAME + "/" + CONFIG_COL_NAME + "/1"),
                 "prop1", "value1");
-        context.create().resource(getConfigPropertiesPath("/conf/item/2"),
+        context.create().resource(getConfigPropertiesPath("/conf/test/" + CONFIGS_PARENT_NAME + "/" + CONFIG_COL_NAME + "/2"),
                 "prop4", true);
-
-        configResource = context.resourceResolver().getResource("/conf/test");
-        configResourceItem1 = context.resourceResolver().getResource("/conf/item/1");
-        configResourceItem2 = context.resourceResolver().getResource("/conf/item/2");
         
+        // test fixture with resource collection inheritance on level 2
+        context.create().resource("/conf/test/level2/" + CONFIGS_PARENT_NAME + "/" + CONFIG_COL_NAME,
+                PROPERTY_CONFIG_COLLECTION_INHERIT, true);
+        context.create().resource(getConfigPropertiesPath("/conf/test/level2/" + CONFIGS_PARENT_NAME + "/" + CONFIG_COL_NAME + "/1"),
+                "prop1", "value1_level2");
+        
+        // test fixture with property inheritance and resource collection inheritance on level 3
+        context.create().resource(getConfigPropertiesPath("/conf/test/level2/level3/" + CONFIGS_PARENT_NAME + "/" + CONFIG_NAME),
+                "prop4", false,
+                "prop5", "value5_level3",
+                PROPERTY_CONFIG_PROPERTY_INHERIT, true);
+        context.create().resource("/conf/test/level2/level3/" + CONFIGS_PARENT_NAME + "/" + CONFIG_COL_NAME,
+                PROPERTY_CONFIG_COLLECTION_INHERIT, true);
+        context.create().resource(getConfigPropertiesPath("/conf/test/level2/level3/" + CONFIGS_PARENT_NAME + "/" + CONFIG_COL_NAME + "/1"),
+                "prop4", false,
+                "prop5", "value5_level3",
+                PROPERTY_CONFIG_PROPERTY_INHERIT, true);
+
         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(configurationMetadataProvider.getConfigurationMetadata(CONFIG_NAME)).thenReturn(configMetadata);
 
-        when(configurationResourceResolver.getResourceCollection(any(Resource.class), anyString(), anyString()))
-                .thenReturn(ImmutableList.<Resource>of());
+        configMetadata = new ConfigurationMetadata(CONFIG_COL_NAME);
+        configMetadata.setPropertyMetadata(ImmutableMap.<String,PropertyMetadata<?>>of(
+                "prop1", new PropertyMetadata<>("prop1", "defValue"),
+                "prop2", new PropertyMetadata<>("prop2", String.class),
+                "prop3", new PropertyMetadata<>("prop3", 5)));
+        when(configurationMetadataProvider.getConfigurationMetadata(CONFIG_COL_NAME)).thenReturn(configMetadata);
     }
     
     protected String getConfigPropertiesPath(String path) {
@@ -117,32 +136,82 @@ public class ConfigurationManagerImplTes
     
     @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));
+
+        assertFalse(configData.getValueInfo("prop1").isInherited());
+        assertFalse(configData.getValueInfo("prop3").isInherited());
     }
 
     @Test
-    public void testGet_NoConfigResource() {
-        when(configurationMetadataProvider.getConfigurationMetadata(CONFIG_NAME)).thenReturn(configMetadata);
+    public void testGet_WithResourceInheritance() {
+        ConfigurationData configData = underTest.get(contextResourceLevel2, CONFIG_NAME);
+        assertNotNull(configData);
 
-        ConfigurationData configData = underTest.get(contextResource, CONFIG_NAME);
+        assertEquals(ImmutableSet.of("prop1", "prop2", "prop3", "prop4"), configData.getPropertyNames());
+        assertNull(configData.getValues().get("prop1", String.class));
+        assertEquals("value1", configData.getEffectiveValues().get("prop1", String.class));
+        assertEquals((Integer)5, configData.getEffectiveValues().get("prop3", 0));
+
+        String configPath = getConfigPropertiesPath("/conf/test/" + CONFIGS_PARENT_NAME + "/" + CONFIG_NAME);
+        assertEquals(configPath, configData.getValueInfo("prop1").getConfigSourcePath());
+        assertTrue(configData.getValueInfo("prop1").isInherited());
+        assertFalse(configData.getValueInfo("prop3").isInherited());
+        assertNull(configData.getValueInfo("prop3").getConfigSourcePath());
+    }
+
+    @Test
+    public void testGet_WithPropertyInheritance() {
+        ConfigurationData configData = underTest.get(contextResourceLevel3, CONFIG_NAME);
+        assertNotNull(configData);
+
+        assertTrue(configData.getPropertyNames().containsAll(ImmutableSet.of("prop1", "prop2", "prop3", "prop4", "prop5")));
+        assertNull(configData.getValues().get("prop1", String.class));
+        assertNull(configData.getValues().get("prop2", String.class));
+        assertNull(configData.getValues().get("prop3", Integer.class));
+        assertFalse(configData.getValues().get("prop4", Boolean.class));
+        assertEquals("value5_level3", configData.getValues().get("prop5", String.class));
+        
+        assertEquals("value1", configData.getEffectiveValues().get("prop1", String.class));
+        assertNull(configData.getEffectiveValues().get("prop2", String.class));
+        assertEquals((Integer)5, configData.getEffectiveValues().get("prop3", 0));
+        assertFalse(configData.getEffectiveValues().get("prop4", Boolean.class));
+        assertEquals("value5_level3", configData.getEffectiveValues().get("prop5", String.class));
+
+        String configPath = getConfigPropertiesPath("/conf/test/" + CONFIGS_PARENT_NAME + "/" + CONFIG_NAME);
+        String configPathLevel3 = getConfigPropertiesPath("/conf/test/level2/level3/" + CONFIGS_PARENT_NAME + "/" + CONFIG_NAME);
+        assertTrue(configData.getValueInfo("prop1").isInherited());
+        assertEquals(configPath, configData.getValueInfo("prop1").getConfigSourcePath());
+        assertFalse(configData.getValueInfo("prop2").isInherited());
+        assertNull(configData.getValueInfo("prop2").getConfigSourcePath());
+        assertFalse(configData.getValueInfo("prop3").isInherited());
+        assertNull(configData.getValueInfo("prop3").getConfigSourcePath());
+        assertFalse(configData.getValueInfo("prop4").isInherited());
+        assertEquals(configPathLevel3, configData.getValueInfo("prop4").getConfigSourcePath());
+        assertFalse(configData.getValueInfo("prop5").isInherited());
+        assertEquals(configPathLevel3, configData.getValueInfo("prop5").getConfigSourcePath());
+    }
+
+    @Test
+    public void testGet_NoConfigResource() {
+        ConfigurationData configData = underTest.get(contextResourceNoConfig, 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));
+
+        assertFalse(configData.getValueInfo("prop1").isInherited());
+        assertFalse(configData.getValueInfo("prop3").isInherited());
     }
 
     @Test
     public void testGet_NoConfigMetadata() {
-        when(configurationResourceResolver.getResource(contextResource, CONFIGS_PARENT_NAME, CONFIG_NAME)).thenReturn(configResource);
+        when(configurationMetadataProvider.getConfigurationMetadata(CONFIG_NAME)).thenReturn(null);
 
         ConfigurationData configData = underTest.get(contextResource, CONFIG_NAME);
         assertNotNull(configData);
@@ -150,48 +219,127 @@ public class ConfigurationManagerImplTes
         assertEquals(ImmutableSet.of("prop1", "prop4"), configData.getPropertyNames());
         assertEquals("value1", configData.getValues().get("prop1", String.class));
         assertEquals((Integer)0, configData.getEffectiveValues().get("prop3", 0));
+
+        assertFalse(configData.getValueInfo("prop1").isInherited());
+        assertFalse(configData.getValueInfo("prop3").isInherited());
     }
 
     @Test
     public void testGet_NoConfigResource_NoConfigMetadata() {
-        ConfigurationData configData = underTest.get(contextResource, CONFIG_NAME);
+        when(configurationMetadataProvider.getConfigurationMetadata(CONFIG_NAME)).thenReturn(null);
+
+        ConfigurationData configData = underTest.get(contextResourceNoConfig, 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_COL_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));
+
+        assertFalse(configData1.getValueInfo("prop1").isInherited());
+        assertFalse(configData1.getValueInfo("prop3").isInherited());
         
-        List<ConfigurationData> configDatas = ImmutableList.copyOf(underTest.getCollection(contextResource, CONFIG_NAME));
+        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));
+
+        assertFalse(configData2.getValueInfo("prop1").isInherited());
+        assertFalse(configData2.getValueInfo("prop3").isInherited());
+    }
+
+    @Test
+    public void testGetCollection_WithResourceCollectionInheritance() {
+        List<ConfigurationData> configDatas = ImmutableList.copyOf(underTest.getCollection(contextResourceLevel2, CONFIG_COL_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("value1_level2", configData1.getValues().get("prop1", String.class));
+        assertEquals("value1_level2", configData1.getEffectiveValues().get("prop1", String.class));
         assertEquals((Integer)5, configData1.getEffectiveValues().get("prop3", 0));
 
+        String configPath1 = getConfigPropertiesPath("/conf/test/level2/" + CONFIGS_PARENT_NAME + "/" + CONFIG_COL_NAME + "/1");
+        assertFalse(configData1.getValueInfo("prop1").isInherited());
+        assertEquals(configPath1, configData1.getValueInfo("prop1").getConfigSourcePath());
+        assertFalse(configData1.getValueInfo("prop3").isInherited());
+        assertNull(configData1.getValueInfo("prop3").getConfigSourcePath());
+        
         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));
+
+        String configPath2 = getConfigPropertiesPath("/conf/test/" + CONFIGS_PARENT_NAME + "/" + CONFIG_COL_NAME + "/2");
+        assertTrue(configData2.getValueInfo("prop4").isInherited());
+        assertEquals(configPath2, configData2.getValueInfo("prop4").getConfigSourcePath());
+        assertFalse(configData2.getValueInfo("prop3").isInherited());
+        assertNull(configData2.getValueInfo("prop3").getConfigSourcePath());
     }
 
     @Test
-    public void testGetCollection_NoConfigResources() {
-        when(configurationMetadataProvider.getConfigurationMetadata(CONFIG_NAME)).thenReturn(configMetadata);
+    public void testGetCollection_WithResourceCollectionAndPropertyInheritance() {
+        List<ConfigurationData> configDatas = ImmutableList.copyOf(underTest.getCollection(contextResourceLevel3, CONFIG_COL_NAME));
+        assertEquals(2, configDatas.size());
+        
+        ConfigurationData configData1 = configDatas.get(0);
+        assertTrue(configData1.getPropertyNames().containsAll(ImmutableSet.of("prop1", "prop2", "prop3", "prop4", "prop5")));
+
+        assertTrue(configData1.getPropertyNames().containsAll(ImmutableSet.of("prop1", "prop2", "prop3", "prop4", "prop5")));
+        assertNull(configData1.getValues().get("prop1", String.class));
+        assertNull(configData1.getValues().get("prop2", String.class));
+        assertNull(configData1.getValues().get("prop3", Integer.class));
+        assertFalse(configData1.getValues().get("prop4", Boolean.class));
+        assertEquals("value5_level3", configData1.getValues().get("prop5", String.class));
         
-        List<ConfigurationData> configDatas = ImmutableList.copyOf(underTest.getCollection(contextResource, CONFIG_NAME));
+        assertEquals("value1_level2", configData1.getEffectiveValues().get("prop1", String.class));
+        assertNull(configData1.getEffectiveValues().get("prop2", String.class));
+        assertEquals((Integer)5, configData1.getEffectiveValues().get("prop3", 0));
+        assertFalse(configData1.getEffectiveValues().get("prop4", Boolean.class));
+        assertEquals("value5_level3", configData1.getEffectiveValues().get("prop5", String.class));
+
+        String configPathLevel2 = getConfigPropertiesPath("/conf/test/level2/" + CONFIGS_PARENT_NAME + "/" + CONFIG_COL_NAME + "/1");
+        String configPathLevel3 = getConfigPropertiesPath("/conf/test/level2/level3/" + CONFIGS_PARENT_NAME + "/" + CONFIG_COL_NAME + "/1");
+        assertTrue(configData1.getValueInfo("prop1").isInherited());
+        assertEquals(configPathLevel2, configData1.getValueInfo("prop1").getConfigSourcePath());
+        assertFalse(configData1.getValueInfo("prop2").isInherited());
+        assertNull(configData1.getValueInfo("prop2").getConfigSourcePath());
+        assertFalse(configData1.getValueInfo("prop3").isInherited());
+        assertNull(configData1.getValueInfo("prop3").getConfigSourcePath());
+        assertFalse(configData1.getValueInfo("prop4").isInherited());
+        assertEquals(configPathLevel3, configData1.getValueInfo("prop4").getConfigSourcePath());
+        assertFalse(configData1.getValueInfo("prop5").isInherited());
+        assertEquals(configPathLevel3, configData1.getValueInfo("prop5").getConfigSourcePath());
+                
+        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));
+
+        String configPath2 = getConfigPropertiesPath("/conf/test/" + CONFIGS_PARENT_NAME + "/" + CONFIG_COL_NAME + "/2");
+        assertTrue(configData2.getValueInfo("prop4").isInherited());
+        assertEquals(configPath2, configData2.getValueInfo("prop4").getConfigSourcePath());
+        assertFalse(configData2.getValueInfo("prop3").isInherited());
+        assertNull(configData2.getValueInfo("prop3").getConfigSourcePath());
+    }
+
+    @Test
+    public void testGetCollection_NoConfigResources() {
+        List<ConfigurationData> configDatas = ImmutableList.copyOf(underTest.getCollection(contextResourceNoConfig, CONFIG_COL_NAME));
         assertEquals(0, configDatas.size());
     }
 
     @Test
     public void testGetCollection_NoConfigMetadata() {
-        when(configurationResourceResolver.getResourceCollection(contextResource, CONFIGS_PARENT_NAME, CONFIG_NAME))
-            .thenReturn(ImmutableList.of(configResourceItem1, configResourceItem2));
+        when(configurationMetadataProvider.getConfigurationMetadata(CONFIG_COL_NAME)).thenReturn(null);
         
-        List<ConfigurationData> configDatas = ImmutableList.copyOf(underTest.getCollection(contextResource, CONFIG_NAME));
+        List<ConfigurationData> configDatas = ImmutableList.copyOf(underTest.getCollection(contextResource, CONFIG_COL_NAME));
         assertEquals(2, configDatas.size());
         
         ConfigurationData configData1 = configDatas.get(0);
@@ -199,60 +347,66 @@ public class ConfigurationManagerImplTes
         assertEquals("value1", configData1.getValues().get("prop1", String.class));
         assertEquals((Integer)0, configData1.getEffectiveValues().get("prop3", 0));
 
+        assertFalse(configData1.getValueInfo("prop1").isInherited());
+        assertFalse(configData1.getValueInfo("prop3").isInherited());
+
         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));
+
+        assertFalse(configData2.getValueInfo("prop1").isInherited());
+        assertFalse(configData2.getValueInfo("prop3").isInherited());
     }
 
     @Test
     public void testGetCollection_NoConfigResources_NoConfigMetadata() {
-        List<ConfigurationData> configDatas = ImmutableList.copyOf(underTest.getCollection(contextResource, CONFIG_NAME));
+        when(configurationMetadataProvider.getConfigurationMetadata(CONFIG_COL_NAME)).thenReturn(null);
+
+        List<ConfigurationData> configDatas = ImmutableList.copyOf(underTest.getCollection(contextResourceNoConfig, CONFIG_COL_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,
+        underTest.persist(contextResourceNoConfig, CONFIG_NAME,
                 ImmutableMap.<String, Object>of("prop1", "value1"));
         context.resourceResolver().commit();
 
-        ValueMap props = context.resourceResolver().getResource(getConfigPropertiesPath("/conf/new")).getValueMap();
+        String configPath = getConfigPropertiesPath("/conf/testNoConfig/" + CONFIGS_PARENT_NAME + "/" + CONFIG_NAME);
+        ValueMap props = context.resourceResolver().getResource(configPath).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(
+        underTest.persistCollection(contextResourceNoConfig, CONFIG_COL_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();
+        String configPath0 = getConfigPropertiesPath("/conf/testNoConfig/" + CONFIGS_PARENT_NAME + "/" + CONFIG_COL_NAME + "/0");
+        ValueMap props0 = context.resourceResolver().getResource(configPath0).getValueMap();
         assertEquals("value1", props0.get("prop1"));
-        ValueMap props1 = context.resourceResolver().getResource(getConfigPropertiesPath("/conf/newcol/1")).getValueMap();
+
+        String configPath1 = getConfigPropertiesPath("/conf/testNoConfig/" + CONFIGS_PARENT_NAME + "/" + CONFIG_COL_NAME + "/1");
+        ValueMap props1 = context.resourceResolver().getResource(configPath1).getValueMap();
         assertEquals((Integer)5, props1.get("prop2"));
     }
 
     @Test
     public void testNewCollectionItem() {
-        when(configurationMetadataProvider.getConfigurationMetadata(CONFIG_NAME)).thenReturn(configMetadata);
-        
-        ConfigurationData newItem = underTest.newCollectionItem(CONFIG_NAME);
+        ConfigurationData newItem = underTest.newCollectionItem(CONFIG_COL_NAME);
         assertNotNull(newItem);
         assertEquals((Integer)5, newItem.getEffectiveValues().get("prop3", 0));
     }
 
     @Test
     public void testNewCollectionItem_NoConfigMetadata() {
-        ConfigurationData newItem = underTest.newCollectionItem(CONFIG_NAME);
+        when(configurationMetadataProvider.getConfigurationMetadata(CONFIG_COL_NAME)).thenReturn(null);
+
+        ConfigurationData newItem = underTest.newCollectionItem(CONFIG_COL_NAME);
         assertNull(newItem);
     }
 

Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/management/impl/ValueInfoImplTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/management/impl/ValueInfoImplTest.java?rev=1770253&r1=1770252&r2=1770253&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/management/impl/ValueInfoImplTest.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/management/impl/ValueInfoImplTest.java Thu Nov 17 18:03:45 2016
@@ -40,35 +40,41 @@ public class ValueInfoImplTest {
     
     @Test
     public void testValueMetadata() {
-        ValueInfo<String> underTest = new ValueInfoImpl<>("value", "/conf/test", propertyMetadata);
+        ValueInfo<String> underTest = new ValueInfoImpl<>("name1", "value", propertyMetadata, null, null, null);
         
+        assertEquals("name1", underTest.getName());
         assertSame(propertyMetadata, underTest.getPropertyMetadata());
         assertEquals("value", underTest.getValue());
         assertEquals("value", underTest.getEffectiveValue());
-        assertEquals("/conf/test", underTest.getConfigSourcePath());
+        assertNull(underTest.getConfigSourcePath());
         assertFalse(underTest.isDefault());
+        assertFalse(underTest.isInherited());
     }
 
     @Test
     public void testNoValueMetadata() {
-        ValueInfo<String> underTest = new ValueInfoImpl<>(null, "/conf/test", propertyMetadata);
+        ValueInfo<String> underTest = new ValueInfoImpl<>("name1", null, propertyMetadata, null, null, null);
         
+        assertEquals("name1", underTest.getName());
         assertSame(propertyMetadata, underTest.getPropertyMetadata());
         assertNull(underTest.getValue());
         assertEquals("defValue", underTest.getEffectiveValue());
-        assertEquals("/conf/test", underTest.getConfigSourcePath());
+        assertNull(underTest.getConfigSourcePath());
         assertTrue(underTest.isDefault());
+        assertFalse(underTest.isInherited());
     }
 
     @Test
     public void testValueNoMetadata() {
-        ValueInfo<String> underTest = new ValueInfoImpl<>("value", "/conf/test", null);
+        ValueInfo<String> underTest = new ValueInfoImpl<>("name1", "value", null, null, null, null);
         
+        assertEquals("name1", underTest.getName());
         assertNull(underTest.getPropertyMetadata());
         assertEquals("value", underTest.getValue());
         assertEquals("value", underTest.getEffectiveValue());
-        assertEquals("/conf/test", underTest.getConfigSourcePath());
+        assertNull(underTest.getConfigSourcePath());
         assertFalse(underTest.isDefault());
+        assertFalse(underTest.isInherited());
     }
 
 }