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 17:50:36 UTC
svn commit: r1770249 [1/2] - in
/sling/trunk/contrib/extensions/contextaware-config: impl/
impl/src/main/java/org/apache/sling/caconfig/impl/
impl/src/main/java/org/apache/sling/caconfig/impl/def/
impl/src/main/java/org/apache/sling/caconfig/resource/i...
Author: sseifert
Date: Thu Nov 17 17:50:36 2016
New Revision: 1770249
URL: http://svn.apache.org/viewvc?rev=1770249&view=rev
Log:
SLING-6293 refactor property inheritance out of DefaultConfigurationResourceResolvingStrategy and create separate SPI and impl for it
*this breaks backward compatibility of package org.apache.sling.caconfig.resource.spi -> major version increase*
Added:
sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationInheritanceStrategyMultiplexer.java (with props)
sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/ConfigurationDefNameConstants.java (with props)
sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/ConfigurationResourceWrapper.java (with props)
sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/DefaultConfigurationInheritanceStrategy.java (with props)
sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationInheritanceStrategyMultiplexerTest.java (with props)
sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/def/DefaultConfigurationInheritanceStrategyTest.java (with props)
sling/trunk/contrib/extensions/contextaware-config/spi/src/main/java/org/apache/sling/caconfig/spi/ConfigurationInheritanceStrategy.java (with props)
Removed:
sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/resource/impl/def/ConfigurationResourceWrapper.java
Modified:
sling/trunk/contrib/extensions/contextaware-config/impl/pom.xml
sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationBuilderImpl.java
sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationResolverImpl.java
sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/resource/impl/ConfigurationResourceResolvingStrategyMultiplexer.java
sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/resource/impl/def/ConfigurationResourceNameConstants.java
sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/resource/impl/def/DefaultConfigurationResourceResolvingStrategy.java
sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationResolverAnnotationClassTest.java
sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationTestUtils.java
sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/def/ConfigurationResolverPropertyInheritanceTest.java
sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/resource/impl/ConfigurationResourceResolvingStrategyMultiplexerTest.java
sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/resource/impl/def/DefaultConfigurationResourceResolvingStrategyHierarchyTest.java
sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/resource/impl/def/DefaultConfigurationResourceResolvingStrategyTest.java
sling/trunk/contrib/extensions/contextaware-config/spi/src/main/java/org/apache/sling/caconfig/resource/spi/ConfigurationResourceResolvingStrategy.java
sling/trunk/contrib/extensions/contextaware-config/spi/src/main/java/org/apache/sling/caconfig/resource/spi/package-info.java
sling/trunk/contrib/extensions/contextaware-config/spi/src/main/java/org/apache/sling/caconfig/spi/package-info.java
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=1770249&r1=1770248&r2=1770249&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/pom.xml (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/pom.xml Thu Nov 17 17:50:36 2016
@@ -85,7 +85,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.caconfig.spi</artifactId>
- <version>1.1.0</version>
+ <version>1.1.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationBuilderImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationBuilderImpl.java?rev=1770249&r1=1770248&r2=1770249&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationBuilderImpl.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationBuilderImpl.java Thu Nov 17 17:50:36 2016
@@ -23,7 +23,10 @@ import static org.apache.sling.caconfig.
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Iterator;
+import org.apache.commons.collections.IteratorUtils;
+import org.apache.commons.collections.Transformer;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceUtil;
@@ -33,26 +36,30 @@ import org.apache.sling.caconfig.Configu
import org.apache.sling.caconfig.ConfigurationResolver;
import org.apache.sling.caconfig.impl.ConfigurationProxy.ChildResolver;
import org.apache.sling.caconfig.impl.metadata.AnnotationClassParser;
-import org.apache.sling.caconfig.resource.ConfigurationResourceResolver;
+import org.apache.sling.caconfig.resource.spi.ConfigurationResourceResolvingStrategy;
+import org.apache.sling.caconfig.spi.ConfigurationInheritanceStrategy;
import org.apache.sling.caconfig.spi.ConfigurationPersistenceStrategy;
class ConfigurationBuilderImpl implements ConfigurationBuilder {
private final Resource contentResource;
private final ConfigurationResolver configurationResolver;
- private final ConfigurationResourceResolver configurationResourceResolver;
+ private final ConfigurationResourceResolvingStrategy configurationResourceResolvingStrategy;
private final ConfigurationPersistenceStrategy configurationPersistenceStrategy;
+ private final ConfigurationInheritanceStrategy configurationInheritanceStrategy;
private String configName;
public ConfigurationBuilderImpl(final Resource resource,
final ConfigurationResolver configurationResolver,
- final ConfigurationResourceResolver configurationResourceResolver,
- final ConfigurationPersistenceStrategy configurationPersistenceStrategy) {
+ final ConfigurationResourceResolvingStrategy configurationResourceResolvingStrategy,
+ final ConfigurationPersistenceStrategy configurationPersistenceStrategy,
+ final ConfigurationInheritanceStrategy configurationInheritanceStrategy) {
this.contentResource = resource;
this.configurationResolver = configurationResolver;
- this.configurationResourceResolver = configurationResourceResolver;
+ this.configurationResourceResolvingStrategy = configurationResourceResolvingStrategy;
this.configurationPersistenceStrategy = configurationPersistenceStrategy;
+ this.configurationInheritanceStrategy = configurationInheritanceStrategy;
}
@Override
@@ -102,12 +109,13 @@ class ConfigurationBuilderImpl implement
* @return Converted singleton configuration
*/
private <T> T getConfigResource(String name, Class<T> clazz, Converter<T> converter) {
- Resource configResource = null;
+ Iterator<Resource> resourceInheritanceChain = null;
if (this.contentResource != null) {
validateConfigurationName(name);
- configResource = this.configurationResourceResolver.getResource(this.contentResource, CONFIGS_PARENT_NAME, name);
+ resourceInheritanceChain = this.configurationResourceResolvingStrategy
+ .getResourceInheritanceChain(this.contentResource, CONFIGS_PARENT_NAME, name);
}
- return convert(configResource, clazz, converter, name);
+ return convert(resourceInheritanceChain, clazz, converter, name, false);
}
/**
@@ -121,8 +129,9 @@ 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 = convert(rsrc, clazz, converter, name + "/" + rsrc.getName());
+ for (final Iterator<Resource> resourceInheritanceChain : this.configurationResourceResolvingStrategy
+ .getResourceCollectionInheritanceChain(this.contentResource, CONFIGS_PARENT_NAME, name)) {
+ final T obj = convert(resourceInheritanceChain, clazz, converter, name, true);
if (obj != null) {
result.add(obj);
}
@@ -134,12 +143,28 @@ class ConfigurationBuilderImpl implement
}
}
- private <T> T convert(Resource resource, Class<T> clazz, Converter<T> converter, String name) {
+ @SuppressWarnings("unchecked")
+ private <T> T convert(Iterator<Resource> resourceInhertianceChain, Class<T> clazz, Converter<T> converter,
+ String name, boolean appendResourceName) {
Resource configResource = null;
- if (resource != null) {
- configResource = configurationPersistenceStrategy.getResource(resource);
+ String conversionName = name;
+ if (resourceInhertianceChain != null) {
+ // apply persistence transformation
+ Iterator<Resource> transformedResources = IteratorUtils.transformedIterator(resourceInhertianceChain,
+ new Transformer() {
+ @Override
+ public Object transform(Object input) {
+ return configurationPersistenceStrategy.getResource((Resource)input);
+ }
+ });
+ // apply resource inheritance
+ configResource = configurationInheritanceStrategy.getResource(transformedResources);
+ // build name
+ if (configResource != null && appendResourceName) {
+ conversionName = conversionName + "/" + configResource.getName();
+ }
}
- return converter.convert(configResource, clazz, name);
+ return converter.convert(configResource, clazz, conversionName);
}
// --- Annotation class support ---
Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationInheritanceStrategyMultiplexer.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationInheritanceStrategyMultiplexer.java?rev=1770249&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationInheritanceStrategyMultiplexer.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationInheritanceStrategyMultiplexer.java Thu Nov 17 17:50:36 2016
@@ -0,0 +1,88 @@
+/*
+ * 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.caconfig.impl;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections.ResettableListIterator;
+import org.apache.commons.collections.iterators.ListIteratorWrapper;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.caconfig.spi.ConfigurationInheritanceStrategy;
+import org.apache.sling.commons.osgi.Order;
+import org.apache.sling.commons.osgi.RankedServices;
+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 ConfigurationInheritanceStrategy} implementations in the container
+ * and consolidates their result based on service ranking.
+ */
+@Component(service = ConfigurationInheritanceStrategyMultiplexer.class,
+reference={
+ @Reference(name="configurationInheritanceStrategy", service=ConfigurationInheritanceStrategy.class,
+ bind="bindConfigurationInheritanceStrategy", unbind="unbindConfigurationInheritanceStrategy",
+ cardinality=ReferenceCardinality.MULTIPLE,
+ policy=ReferencePolicy.DYNAMIC, policyOption=ReferencePolicyOption.GREEDY)
+})
+public class ConfigurationInheritanceStrategyMultiplexer implements ConfigurationInheritanceStrategy {
+
+ private RankedServices<ConfigurationInheritanceStrategy> items = new RankedServices<>(Order.DESCENDING);
+
+ protected void bindConfigurationInheritanceStrategy(ConfigurationInheritanceStrategy item, Map<String, Object> props) {
+ items.bind(item, props);
+ }
+
+ protected void unbindConfigurationInheritanceStrategy(ConfigurationInheritanceStrategy item, Map<String, Object> props) {
+ items.unbind(item, props);
+ }
+
+ /**
+ * Get result from first strategy implementation that has an answer.
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public Resource getResource(Iterator<Resource> configResources) {
+ List<ConfigurationInheritanceStrategy> itemList = items.getList();
+ if (itemList.isEmpty()) {
+ return null;
+ }
+ else if (itemList.size() == 1) {
+ return itemList.get(0).getResource(configResources);
+ }
+ else {
+ ResettableListIterator resettableConfigResources = new ListIteratorWrapper(configResources);
+ for (ConfigurationInheritanceStrategy item : items) {
+ Resource result = item.getResource(resettableConfigResources);
+ if (result != null) {
+ return result;
+ }
+ else {
+ resettableConfigResources.reset();
+ }
+ }
+ return null;
+ }
+ }
+
+}
Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationInheritanceStrategyMultiplexer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationInheritanceStrategyMultiplexer.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Thu Nov 17 17:50:36 2016
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author
Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationInheritanceStrategyMultiplexer.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationResolverImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationResolverImpl.java?rev=1770249&r1=1770248&r2=1770249&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationResolverImpl.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/ConfigurationResolverImpl.java Thu Nov 17 17:50:36 2016
@@ -22,7 +22,7 @@ import org.apache.sling.api.resource.Res
import org.apache.sling.caconfig.ConfigurationBuilder;
import org.apache.sling.caconfig.ConfigurationResolver;
import org.apache.sling.caconfig.management.impl.ConfigurationPersistenceStrategyMultiplexer;
-import org.apache.sling.caconfig.resource.ConfigurationResourceResolver;
+import org.apache.sling.caconfig.resource.impl.ConfigurationResourceResolvingStrategyMultiplexer;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
@@ -30,15 +30,18 @@ import org.osgi.service.component.annota
public class ConfigurationResolverImpl implements ConfigurationResolver {
@Reference
- private ConfigurationResourceResolver configurationResourceResolver;
+ private ConfigurationResourceResolvingStrategyMultiplexer configurationResourceResolvingStrategy;
@Reference
- private ConfigurationPersistenceStrategyMultiplexer configurationResourcePersistenceStrategy;
+ private ConfigurationPersistenceStrategyMultiplexer configurationPersistenceStrategy;
+
+ @Reference
+ private ConfigurationInheritanceStrategyMultiplexer configurationInheritanceStrategy;
@Override
public ConfigurationBuilder get(Resource resource) {
return new ConfigurationBuilderImpl(resource, this,
- configurationResourceResolver, configurationResourcePersistenceStrategy);
+ configurationResourceResolvingStrategy, configurationPersistenceStrategy, configurationInheritanceStrategy);
}
}
Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/ConfigurationDefNameConstants.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/ConfigurationDefNameConstants.java?rev=1770249&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/ConfigurationDefNameConstants.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/ConfigurationDefNameConstants.java Thu Nov 17 17:50:36 2016
@@ -0,0 +1,33 @@
+/*
+ * 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.caconfig.impl.def;
+
+public final class ConfigurationDefNameConstants {
+
+ private ConfigurationDefNameConstants() {
+ // constants only
+ }
+
+ /**
+ * Boolean property that controls whether the properties (key/value pairs) of configuration resources
+ * should be inherited from the configuration hierarchy and merged.
+ */
+ public static final String PROPERTY_CONFIG_PROPERTY_INHERIT = "sling:configPropertyInherit";
+
+}
Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/ConfigurationDefNameConstants.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/ConfigurationDefNameConstants.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Thu Nov 17 17:50:36 2016
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author
Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/ConfigurationDefNameConstants.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/ConfigurationResourceWrapper.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/ConfigurationResourceWrapper.java?rev=1770249&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/ConfigurationResourceWrapper.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/ConfigurationResourceWrapper.java Thu Nov 17 17:50:36 2016
@@ -0,0 +1,52 @@
+/*
+ * 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.caconfig.impl.def;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceWrapper;
+import org.apache.sling.api.resource.ValueMap;
+
+/**
+ * Wrapper that returns an enhanced value map for the resource
+ * providing a merged map with all inherited property values.
+ */
+class ConfigurationResourceWrapper extends ResourceWrapper {
+
+ private final ValueMap props;
+
+ public ConfigurationResourceWrapper(Resource resource, ValueMap props) {
+ super(resource);
+ this.props = props;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
+ if (type == ValueMap.class) {
+ return (AdapterType)props;
+ }
+ return super.adaptTo(type);
+ }
+
+ @Override
+ public ValueMap getValueMap() {
+ return props;
+ }
+
+}
Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/ConfigurationResourceWrapper.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/ConfigurationResourceWrapper.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Thu Nov 17 17:50:36 2016
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author
Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/ConfigurationResourceWrapper.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/DefaultConfigurationInheritanceStrategy.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/DefaultConfigurationInheritanceStrategy.java?rev=1770249&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/DefaultConfigurationInheritanceStrategy.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/DefaultConfigurationInheritanceStrategy.java Thu Nov 17 17:50:36 2016
@@ -0,0 +1,87 @@
+/*
+ * 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.caconfig.impl.def;
+
+import static org.apache.sling.caconfig.impl.def.ConfigurationDefNameConstants.PROPERTY_CONFIG_PROPERTY_INHERIT;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.wrappers.ValueMapDecorator;
+import org.apache.sling.caconfig.spi.ConfigurationInheritanceStrategy;
+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;
+
+@Component(service=ConfigurationInheritanceStrategy.class)
+@Designate(ocd=DefaultConfigurationInheritanceStrategy.Config.class)
+public class DefaultConfigurationInheritanceStrategy implements ConfigurationInheritanceStrategy {
+
+ @ObjectClassDefinition(name="Apache Sling Context-Aware Default Configuration Inheritance Strategy",
+ description="Standardized resource inheritance for configurations.")
+ public static @interface Config {
+
+ @AttributeDefinition(name="Enabled",
+ description = "Enable this configuration inheritance strategy.")
+ boolean enabled() default true;
+
+ @AttributeDefinition(name="Config property inheritance property names",
+ description = "Additional property names to " + PROPERTY_CONFIG_PROPERTY_INHERIT + " to handle property inheritance. The names are used in the order defined, "
+ + "always starting with " + PROPERTY_CONFIG_PROPERTY_INHERIT + ". Once a property with a value is found, that value is used and the following property names are skipped.")
+ String[] configPropertyInheritancePropertyNames();
+
+ }
+
+ @Override
+ public Resource getResource(Iterator<Resource> configResources) {
+ if (!configResources.hasNext()) {
+ return null;
+ }
+ Resource primary = configResources.next();
+ if (!isPropertyInheritance(primary) || !configResources.hasNext()) {
+ return primary;
+ }
+ Map<String,Object> mergedProps = getInheritedProperties(primary.getValueMap(), configResources);
+ return new ConfigurationResourceWrapper(primary, new ValueMapDecorator(mergedProps));
+ }
+
+ private boolean isPropertyInheritance(Resource resource) {
+ return resource.getValueMap().get(PROPERTY_CONFIG_PROPERTY_INHERIT, false);
+ }
+
+ private Map<String,Object> getInheritedProperties(Map<String,Object> parentProps, Iterator<Resource> inheritanceChain) {
+ if (!inheritanceChain.hasNext()) {
+ return parentProps;
+ }
+ Resource next = inheritanceChain.next();
+ Map<String,Object> merged = new HashMap<>(next.getValueMap());
+ merged.putAll(parentProps);
+ if (isPropertyInheritance(next)) {
+ return getInheritedProperties(merged, inheritanceChain);
+ }
+ else {
+ return merged;
+ }
+ }
+
+}
+
\ No newline at end of file
Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/DefaultConfigurationInheritanceStrategy.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/DefaultConfigurationInheritanceStrategy.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Thu Nov 17 17:50:36 2016
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author
Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/impl/def/DefaultConfigurationInheritanceStrategy.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/resource/impl/ConfigurationResourceResolvingStrategyMultiplexer.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/resource/impl/ConfigurationResourceResolvingStrategyMultiplexer.java?rev=1770249&r1=1770248&r2=1770249&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/resource/impl/ConfigurationResourceResolvingStrategyMultiplexer.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/resource/impl/ConfigurationResourceResolvingStrategyMultiplexer.java Thu Nov 17 17:50:36 2016
@@ -18,9 +18,8 @@
*/
package org.apache.sling.caconfig.resource.impl;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.List;
+import java.util.Iterator;
import java.util.Map;
import org.apache.sling.api.resource.Resource;
@@ -71,15 +70,46 @@ public class ConfigurationResourceResolv
}
/**
- * Merge the configuration resources from all implementations into a combined list.
+ * Gets the configuration resource collection from the first implementation that has an answer.
*/
@Override
public Collection<Resource> getResourceCollection(Resource resource, String bucketName, String configName) {
- List<Resource> result = new ArrayList<>();
for (ConfigurationResourceResolvingStrategy item : items) {
- result.addAll(item.getResourceCollection(resource, bucketName, configName));
+ Collection<Resource> result = item.getResourceCollection(resource, bucketName, configName);
+ if (result != null) {
+ return result;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Gets the configuration resource inheritance chain from the first implementation that has an answer.
+ */
+ @Override
+ public Iterator<Resource> getResourceInheritanceChain(Resource resource, String bucketName, String configName) {
+ for (ConfigurationResourceResolvingStrategy item : items) {
+ Iterator<Resource> result = item.getResourceInheritanceChain(resource, bucketName, configName);
+ if (result != null) {
+ return result;
+ }
}
- return result;
+ return null;
+ }
+
+ /**
+ * Gets the configuration resource collection inheritance chains from the first implementation that has an answer.
+ */
+ @Override
+ public Collection<Iterator<Resource>> getResourceCollectionInheritanceChain(Resource resource, String bucketName,
+ String configName) {
+ for (ConfigurationResourceResolvingStrategy item : items) {
+ Collection<Iterator<Resource>> result = item.getResourceCollectionInheritanceChain(resource, bucketName, configName);
+ if (result != null) {
+ return result;
+ }
+ }
+ return null;
}
/**
Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/resource/impl/def/ConfigurationResourceNameConstants.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/resource/impl/def/ConfigurationResourceNameConstants.java?rev=1770249&r1=1770248&r2=1770249&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/resource/impl/def/ConfigurationResourceNameConstants.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/resource/impl/def/ConfigurationResourceNameConstants.java Thu Nov 17 17:50:36 2016
@@ -36,10 +36,4 @@ public final class ConfigurationResource
*/
public static final String PROPERTY_CONFIG_COLLECTION_INHERIT = "sling:configCollectionInherit";
- /**
- * Boolean property that controls whether the properties (key/value pairs) of configuration resources
- * should be inherited from the configuration hierarchy and merged.
- */
- public static final String PROPERTY_CONFIG_PROPERTY_INHERIT = "sling:configPropertyInherit";
-
}
Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/resource/impl/def/DefaultConfigurationResourceResolvingStrategy.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/resource/impl/def/DefaultConfigurationResourceResolvingStrategy.java?rev=1770249&r1=1770248&r2=1770249&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/resource/impl/def/DefaultConfigurationResourceResolvingStrategy.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/main/java/org/apache/sling/caconfig/resource/impl/def/DefaultConfigurationResourceResolvingStrategy.java Thu Nov 17 17:50:36 2016
@@ -19,12 +19,9 @@
package org.apache.sling.caconfig.resource.impl.def;
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_PROPERTY_INHERIT;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -33,14 +30,17 @@ import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
+import org.apache.commons.collections.IteratorUtils;
+import org.apache.commons.collections.PredicateUtils;
+import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.iterators.ArrayIterator;
import org.apache.commons.collections.iterators.IteratorChain;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
-import org.apache.sling.api.wrappers.ValueMapDecorator;
import org.apache.sling.caconfig.resource.impl.ContextPathStrategyMultiplexer;
import org.apache.sling.caconfig.resource.impl.util.PathEliminateDuplicatesIterator;
import org.apache.sling.caconfig.resource.impl.util.PathParentExpandIterator;
@@ -70,7 +70,7 @@ public class DefaultConfigurationResourc
public static @interface Config {
@AttributeDefinition(name="Enabled",
- description = "Enable this configuration resourcer resolving strategy.")
+ description = "Enable this configuration resource resolving strategy.")
boolean enabled() default true;
@AttributeDefinition(name="Configurations path",
@@ -86,10 +86,6 @@ public class DefaultConfigurationResourc
+ "always starting with " + PROPERTY_CONFIG_COLLECTION_INHERIT + ". Once a property with a value is found, that value is used and the following property names are skipped.")
String[] configCollectionInheritancePropertyNames();
- @AttributeDefinition(name="Config property inheritance property names",
- description = "Additional property names to " + PROPERTY_CONFIG_PROPERTY_INHERIT + " to handle property inheritance. The names are used in the order defined, "
- + "always starting with " + PROPERTY_CONFIG_PROPERTY_INHERIT + ". Once a property with a value is found, that value is used and the following property names are skipped.")
- String[] configPropertyInheritancePropertyNames();
}
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@@ -276,56 +272,40 @@ public class DefaultConfigurationResourc
@Override
public Resource getResource(final Resource contentResource, final String bucketName, final String configName) {
- if (!isEnabledAndParamsValid(contentResource, bucketName, configName)) {
- return null;
+ Iterator<Resource> resources = getResourceInheritanceChain(contentResource, bucketName, configName);
+ if (resources != null && resources.hasNext()) {
+ return resources.next();
}
- String name = bucketName + "/" + configName;
- logger.debug("Searching {} for resource {}", name, contentResource.getPath());
-
- // strategy: find first item among all configured paths
- int idx = 1;
- Iterator<String> paths = getResolvePaths(contentResource, bucketName);
- Resource configResource = null;
- Map<String,Object> configValueMap = null;
- boolean propertyInheritance = false;
- while (paths.hasNext()) {
- final String path = paths.next();
- final Resource item = contentResource.getResourceResolver().getResource(buildResourcePath(path, name));
- if (item != null) {
- logger.debug("Resolved config item at [{}]: {}", idx, item.getPath());
+ return null;
+ }
- if (propertyInheritance) {
- // merge property map with values from inheritance parent
- Map<String,Object> mergedValueMap = new HashMap<>(item.getValueMap());
- mergedValueMap.putAll(configValueMap);
- configValueMap = mergedValueMap;
- }
- else {
- configResource = item;
- configValueMap = item.getValueMap();
- }
+ @SuppressWarnings("unchecked")
+ private Iterator<Resource> getResourceInheritanceChainInternal(final String bucketName, final String configName,
+ final Iterator<String> paths, final ResourceResolver resourceResolver) {
+ final String name = bucketName + "/" + configName;
- // check property inheritance mode on current level - should we check on next-highest level as well?
- propertyInheritance = getBooleanValue(item.getValueMap(), PROPERTY_CONFIG_PROPERTY_INHERIT, config.configPropertyInheritancePropertyNames());
- if (!propertyInheritance) {
- break;
- }
+ // find all matching items among all configured paths
+ Iterator<Resource> matchingResources = IteratorUtils.transformedIterator(paths, new Transformer() {
+ @Override
+ public Object transform(Object input) {
+ String path = (String)input;
+ return resourceResolver.getResource(buildResourcePath(path, name));
}
- idx++;
- }
+ });
+ return IteratorUtils.filteredIterator(matchingResources, PredicateUtils.notNullPredicate());
+ }
- if (configResource == null) {
- logger.debug("Could not resolve any config item for '{}' (or no permissions to read it)", name);
+ @Override
+ public Iterator<Resource> getResourceInheritanceChain(Resource contentResource, String bucketName, String configName) {
+ if (!isEnabledAndParamsValid(contentResource, bucketName, configName)) {
return null;
}
+ final ResourceResolver resourceResolver = contentResource.getResourceResolver();
+ final String name = bucketName + "/" + configName;
+ logger.debug("Searching {} for resource {}", name, contentResource.getPath());
- if (configValueMap instanceof ValueMap) {
- // valuemap was not merged - return original resource with original valuemap
- return configResource;
- }
- else {
- return new ConfigurationResourceWrapper(configResource, new ValueMapDecorator(configValueMap));
- }
+ Iterator<String> paths = getResolvePaths(contentResource, bucketName);
+ return getResourceInheritanceChainInternal(bucketName, configName, paths, resourceResolver);
}
private boolean include(final List<CollectionInheritanceDecider> deciders,
@@ -349,31 +329,22 @@ public class DefaultConfigurationResourc
return result;
}
- @Override
- public Collection<Resource> getResourceCollection(final Resource contentResource, final String bucketName, final String configName) {
- if (!isEnabledAndParamsValid(contentResource, bucketName, configName)) {
- return Collections.emptyList();
- }
+ private Collection<Resource> getResourceCollectionInternal(final String bucketName, final String configName,
+ Iterator<String> paths, ResourceResolver resourceResolver) {
String name = bucketName + "/" + configName;
if (logger.isTraceEnabled()) {
logger.trace("- searching for list '{}'", name);
}
final Map<String,Resource> result = new LinkedHashMap<>();
- final Map<String,Map<String,Object>> configValueMaps = new HashMap<>();
-
final List<CollectionInheritanceDecider> deciders = this.collectionInheritanceDeciders;
final Set<String> blockedItems = new HashSet<>();
int idx = 1;
- Iterator<String> paths = getResolvePaths(contentResource, bucketName);
- boolean inheritCollection = false;
- boolean inheritProperties = false;
boolean inherit = false;
- boolean propertyInheritanceApplied = false;
while (paths.hasNext()) {
final String path = paths.next();
- Resource item = contentResource.getResourceResolver().getResource(buildResourcePath(path, name));
+ Resource item = resourceResolver.getResource(buildResourcePath(path, name));
if (item != null) {
if (logger.isTraceEnabled()) {
@@ -381,26 +352,16 @@ public class DefaultConfigurationResourc
}
for (Resource child : item.getChildren()) {
- if (isValidResourceCollectionItem(child) && include(deciders, bucketName, child, blockedItems)) {
- if ((!inherit || inheritCollection) && !result.containsKey(child.getName())) {
- result.put(child.getName(), child);
- configValueMaps.put(child.getName(), child.getValueMap());
- }
- else if (inheritProperties && configValueMaps.containsKey(child.getName())) {
- // merge property map with values from inheritance parent
- Map<String,Object> mergedValueMap = new HashMap<>(child.getValueMap());
- mergedValueMap.putAll(configValueMaps.get(child.getName()));
- configValueMaps.put(child.getName(), mergedValueMap);
- propertyInheritanceApplied = true;
- }
- }
+ if (isValidResourceCollectionItem(child)
+ && !result.containsKey(child.getName())
+ && include(deciders, bucketName, child, blockedItems)) {
+ result.put(child.getName(), child);
+ }
}
- // check collection and property inheritance mode on current level - should we check on next-highest level as well?
+ // check collection inheritance mode on current level - should we check on next-highest level as well?
final ValueMap valueMap = item.getValueMap();
- inheritCollection = getBooleanValue(valueMap, PROPERTY_CONFIG_COLLECTION_INHERIT, config.configCollectionInheritancePropertyNames());
- inheritProperties = getBooleanValue(valueMap, PROPERTY_CONFIG_PROPERTY_INHERIT, config.configPropertyInheritancePropertyNames());
- inherit = inheritCollection || inheritProperties;
+ inherit = getBooleanValue(valueMap, PROPERTY_CONFIG_COLLECTION_INHERIT, config.configCollectionInheritancePropertyNames());
if (!inherit) {
break;
}
@@ -417,23 +378,41 @@ public class DefaultConfigurationResourc
logger.trace("- final list has {} items", result.size());
}
- // replace config resources with wrappers with merged properties if property inheritance was applied
- if (propertyInheritanceApplied) {
- List<Resource> transformedResult = new ArrayList<>();
- for (Map.Entry<String, Resource> entry : result.entrySet()) {
- Map<String,Object> configValueMap = configValueMaps.get(entry.getKey());
- if (configValueMap instanceof ValueMap) {
- transformedResult.add(entry.getValue());
- }
- else {
- transformedResult.add(new ConfigurationResourceWrapper(entry.getValue(), new ValueMapDecorator(configValueMap)));
- }
- }
- return transformedResult;
+ return result.values();
+ }
+
+ @Override
+ public Collection<Resource> getResourceCollection(final Resource contentResource, final String bucketName, final String configName) {
+ if (!isEnabledAndParamsValid(contentResource, bucketName, configName)) {
+ return null;
}
- else {
- return result.values();
+ Iterator<String> paths = getResolvePaths(contentResource, bucketName);
+ return getResourceCollectionInternal(bucketName, configName, paths, contentResource.getResourceResolver());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Collection<Iterator<Resource>> getResourceCollectionInheritanceChain(final Resource contentResource,
+ final String bucketName, final String configName) {
+ if (!isEnabledAndParamsValid(contentResource, bucketName, configName)) {
+ return null;
}
+ final ResourceResolver resourceResolver = contentResource.getResourceResolver();
+ final List<String> paths = IteratorUtils.toList(getResolvePaths(contentResource, bucketName));
+
+ // get resource collection with respect to collection inheritance
+ Collection<Resource> resourceCollection = getResourceCollectionInternal(bucketName, configName, paths.iterator(), resourceResolver);
+
+ // get inheritance chain for each item found
+ // yes, this resolves the closest item twice, but is the easiest solution to combine both logic aspects
+ Iterator<Iterator<Resource>> result = IteratorUtils.transformedIterator(resourceCollection.iterator(), new Transformer() {
+ @Override
+ public Object transform(Object input) {
+ Resource item = (Resource)input;
+ return getResourceInheritanceChainInternal(bucketName, configName + "/" + item.getName(), paths.iterator(), resourceResolver);
+ }
+ });
+ return IteratorUtils.toList(result);
}
private boolean isValidResourceCollectionItem(Resource resource) {
@@ -468,28 +447,14 @@ public class DefaultConfigurationResourc
return configPath;
}
else {
- logger.debug("No configuration path {} foundfor resource {}.", name, contentResource.getPath());
+ logger.debug("No configuration path {} found for resource {}.", name, contentResource.getPath());
return null;
}
}
@Override
public String getResourceCollectionParentPath(Resource contentResource, String bucketName, String configName) {
- if (!isEnabledAndParamsValid(contentResource, bucketName, configName)) {
- return null;
- }
- String name = bucketName + "/" + configName;
-
- Iterator<String> configPaths = this.findConfigRefs(contentResource, bucketName);
- if (configPaths.hasNext()) {
- String configPath = buildResourcePath(configPaths.next(), name);
- logger.debug("Building configuration collection parent path {} for resource {}: {}", name, contentResource.getPath(), configPath);
- return configPath;
- }
- else {
- logger.debug("No configuration collection parent path {} foundfor resource {}.", name, contentResource.getPath());
- return null;
- }
+ return getResourcePath(contentResource, bucketName, configName);
}
}
Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationInheritanceStrategyMultiplexerTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationInheritanceStrategyMultiplexerTest.java?rev=1770249&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationInheritanceStrategyMultiplexerTest.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationInheritanceStrategyMultiplexerTest.java Thu Nov 17 17:50:36 2016
@@ -0,0 +1,125 @@
+/*
+ * 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.caconfig.impl;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import java.util.Iterator;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.caconfig.spi.ConfigurationInheritanceStrategy;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.stubbing.Answer;
+
+import com.google.common.collect.ImmutableList;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ConfigurationInheritanceStrategyMultiplexerTest {
+
+ @Rule
+ public SlingContext context = new SlingContext();
+
+ @Mock
+ private Resource resource1;
+ @Mock
+ private Resource resource2;
+
+ private Iterator<Resource> resources;
+ private ConfigurationInheritanceStrategy underTest;
+
+ @Before
+ public void setUp() {
+ resources = ImmutableList.of(resource1, resource2).iterator();
+ underTest = context.registerInjectActivateService(new ConfigurationInheritanceStrategyMultiplexer());
+ }
+
+ @Test
+ public void testWithNoStrategies() {
+ assertNull(underTest.getResource(resources));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testWithOneStrategy() {
+ ConfigurationInheritanceStrategy strategy = mock(ConfigurationInheritanceStrategy.class);
+
+ when(strategy.getResource((Iterator<Resource>)any())).thenAnswer(new Answer<Resource>() {
+ @Override
+ public Resource answer(InvocationOnMock invocation) throws Throwable {
+ Iterator<Resource> items = invocation.getArgument(0);
+ return items.next();
+ }
+ });
+
+ context.registerService(ConfigurationInheritanceStrategy.class, strategy);
+
+ assertSame(resource1, underTest.getResource(resources));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testWithMultipleStrategies() {
+ ConfigurationInheritanceStrategy strategy1 = mock(ConfigurationInheritanceStrategy.class);
+ ConfigurationInheritanceStrategy strategy2 = mock(ConfigurationInheritanceStrategy.class);
+ ConfigurationInheritanceStrategy strategy3 = mock(ConfigurationInheritanceStrategy.class);
+
+ when(strategy1.getResource((Iterator<Resource>)any())).thenAnswer(new Answer<Resource>() {
+ @Override
+ public Resource answer(InvocationOnMock invocation) throws Throwable {
+ Iterator<Resource> items = invocation.getArgument(0);
+ while (items.hasNext()) {
+ items.next();
+ }
+ return null;
+ }
+ });
+ when(strategy2.getResource((Iterator<Resource>)any())).thenAnswer(new Answer<Resource>() {
+ @Override
+ public Resource answer(InvocationOnMock invocation) throws Throwable {
+ Iterator<Resource> items = invocation.getArgument(0);
+ return items.next();
+ }
+ });
+
+ context.registerService(ConfigurationInheritanceStrategy.class, strategy1);
+ context.registerService(ConfigurationInheritanceStrategy.class, strategy2);
+ context.registerService(ConfigurationInheritanceStrategy.class, strategy3);
+
+ assertSame(resource1, underTest.getResource(resources));
+
+ verify(strategy1, times(1)).getResource((Iterator<Resource>)any());
+ verify(strategy2, times(1)).getResource((Iterator<Resource>)any());
+ verifyNoMoreInteractions(strategy3);
+ }
+
+}
Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationInheritanceStrategyMultiplexerTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationInheritanceStrategyMultiplexerTest.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Thu Nov 17 17:50:36 2016
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author
Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationInheritanceStrategyMultiplexerTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationResolverAnnotationClassTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationResolverAnnotationClassTest.java?rev=1770249&r1=1770248&r2=1770249&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationResolverAnnotationClassTest.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationResolverAnnotationClassTest.java Thu Nov 17 17:50:36 2016
@@ -18,8 +18,8 @@
*/
package org.apache.sling.caconfig.impl;
+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_PROPERTY_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.assertNotNull;
@@ -161,12 +161,11 @@ public class ConfigurationResolverAnnota
.siblingsMode()
.resource("1", "stringParam", "configValue1.1", "intParam", "111")
.resource("2", "stringParam", "configValue1.2", "intParam", "222")
- .resource("/conf/content/site1/sling:configs/org.apache.sling.caconfig.example.ListConfig",
- PROPERTY_CONFIG_PROPERTY_INHERIT, true,
+ .resource("/conf/content/site1/sling:configs/org.apache.sling.caconfig.example.ListConfig",
PROPERTY_CONFIG_COLLECTION_INHERIT, true)
.siblingsMode()
- .resource("2", "stringParam", "configValue2.2")
- .resource("3", "stringParam", "configValue2.3", "intParam", "333");
+ .resource("2", "stringParam", "configValue2.2", PROPERTY_CONFIG_PROPERTY_INHERIT, true)
+ .resource("3", "stringParam", "configValue2.3", "intParam", "333", PROPERTY_CONFIG_PROPERTY_INHERIT, true);
List<ListConfig> cfgList = ImmutableList.copyOf(underTest.get(site1Page1).asCollection(ListConfig.class));
Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationTestUtils.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationTestUtils.java?rev=1770249&r1=1770248&r2=1770249&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationTestUtils.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/ConfigurationTestUtils.java Thu Nov 17 17:50:36 2016
@@ -19,6 +19,7 @@
package org.apache.sling.caconfig.impl;
import org.apache.sling.caconfig.ConfigurationResolver;
+import org.apache.sling.caconfig.impl.def.DefaultConfigurationInheritanceStrategy;
import org.apache.sling.caconfig.impl.def.DefaultConfigurationPersistenceStrategy;
import org.apache.sling.caconfig.management.impl.ConfigurationPersistenceStrategyMultiplexer;
import org.apache.sling.caconfig.resource.impl.ConfigurationResourceTestUtils;
@@ -38,6 +39,8 @@ public final class ConfigurationTestUtil
ConfigurationResourceTestUtils.registerConfigurationResourceResolver(context);
context.registerInjectActivateService(new DefaultConfigurationPersistenceStrategy());
context.registerInjectActivateService(new ConfigurationPersistenceStrategyMultiplexer());
+ context.registerInjectActivateService(new DefaultConfigurationInheritanceStrategy());
+ context.registerInjectActivateService(new ConfigurationInheritanceStrategyMultiplexer());
return context.registerInjectActivateService(new ConfigurationResolverImpl());
}
Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/def/ConfigurationResolverPropertyInheritanceTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/def/ConfigurationResolverPropertyInheritanceTest.java?rev=1770249&r1=1770248&r2=1770249&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/def/ConfigurationResolverPropertyInheritanceTest.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/def/ConfigurationResolverPropertyInheritanceTest.java Thu Nov 17 17:50:36 2016
@@ -18,7 +18,7 @@
*/
package org.apache.sling.caconfig.impl.def;
-import static org.apache.sling.caconfig.resource.impl.def.ConfigurationResourceNameConstants.PROPERTY_CONFIG_PROPERTY_INHERIT;
+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_REF;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.hasEntry;
@@ -158,8 +158,8 @@ public class ConfigurationResolverProper
context.build()
.resource("/conf/global/sling:configs/test")
.resource("item1", "param1", "value1", "param2", "value2")
- .resource("/conf/brand1/tenant1/region1/site1/sling:configs/test", PROPERTY_CONFIG_PROPERTY_INHERIT, true)
- .resource("item1", "param1", "value1a")
+ .resource("/conf/brand1/tenant1/region1/site1/sling:configs/test")
+ .resource("item1", "param1", "value1a", PROPERTY_CONFIG_PROPERTY_INHERIT, true)
.resource("/conf/brand1/tenant1/region1/site2/sling:configs/test")
.resource("item1", "param1", "value1b");
@@ -176,12 +176,12 @@ public class ConfigurationResolverProper
context.build()
.resource("/conf/global/sling:configs/test")
.resource("item1", "param1", "value1", "param4", "value4")
- .resource("/conf/brand1/tenant1/sling:configs/test", PROPERTY_CONFIG_PROPERTY_INHERIT, true)
- .resource("item1", "param1", "value1a", "param3", "value3")
- .resource("/conf/brand1/tenant1/region1/sling:configs/test", PROPERTY_CONFIG_PROPERTY_INHERIT, true)
- .resource("item1", "param1", "value1b", "param2", "value2")
- .resource("/conf/brand1/tenant1/region1/site1/sling:configs/test", PROPERTY_CONFIG_PROPERTY_INHERIT, true)
- .resource("item1", "param1", "value1c")
+ .resource("/conf/brand1/tenant1/sling:configs/test")
+ .resource("item1", "param1", "value1a", "param3", "value3", PROPERTY_CONFIG_PROPERTY_INHERIT, true)
+ .resource("/conf/brand1/tenant1/region1/sling:configs/test")
+ .resource("item1", "param1", "value1b", "param2", "value2", PROPERTY_CONFIG_PROPERTY_INHERIT, true)
+ .resource("/conf/brand1/tenant1/region1/site1/sling:configs/test")
+ .resource("item1", "param1", "value1c", PROPERTY_CONFIG_PROPERTY_INHERIT, true)
.resource("/conf/brand1/tenant1/region1/site2/sling:configs/test")
.resource("item1", "param1", "value1d");
Added: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/def/DefaultConfigurationInheritanceStrategyTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/def/DefaultConfigurationInheritanceStrategyTest.java?rev=1770249&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/def/DefaultConfigurationInheritanceStrategyTest.java (added)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/def/DefaultConfigurationInheritanceStrategyTest.java Thu Nov 17 17:50:36 2016
@@ -0,0 +1,100 @@
+/*
+ * 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.caconfig.impl.def;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.Iterator;
+import static org.apache.sling.caconfig.impl.def.ConfigurationDefNameConstants.PROPERTY_CONFIG_PROPERTY_INHERIT;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.caconfig.spi.ConfigurationInheritanceStrategy;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class DefaultConfigurationInheritanceStrategyTest {
+
+ @Rule
+ public SlingContext context = new SlingContext();
+
+ private ConfigurationInheritanceStrategy underTest;
+
+ @Before
+ public void setUp() {
+ underTest = context.registerInjectActivateService(new DefaultConfigurationInheritanceStrategy());
+ }
+
+ @Test
+ public void testWithoutPropertyMerging() {
+ Iterator<Resource> resources = ImmutableList.of(
+ context.create().resource("/conf/resource1", "prop1", "value1a", "prop2", "value2a"),
+ context.create().resource("/conf/resource2", "prop2", "value2b", "prop3", "value3b"),
+ context.create().resource("/conf/resource3", "prop4", "value4b")
+ ).iterator();
+
+ Resource inherited = underTest.getResource(resources);
+ ValueMap props = inherited.getValueMap();
+
+ assertEquals("value1a", props.get("prop1", String.class));
+ assertEquals("value2a", props.get("prop2", String.class));
+ assertNull(props.get("prop3", String.class));
+ assertNull(props.get("prop4", String.class));
+ }
+
+ @Test
+ public void testWithPropertyMerging() {
+ Iterator<Resource> resources = ImmutableList.of(
+ context.create().resource("/conf/resource1", "prop1", "value1a", "prop2", "value2a", PROPERTY_CONFIG_PROPERTY_INHERIT, true),
+ context.create().resource("/conf/resource2", "prop2", "value2b", "prop3", "value3b", PROPERTY_CONFIG_PROPERTY_INHERIT, true),
+ context.create().resource("/conf/resource3", "prop4", "value4b")
+ ).iterator();
+
+ Resource inherited = underTest.getResource(resources);
+ ValueMap props = inherited.getValueMap();
+
+ assertEquals("value1a", props.get("prop1", String.class));
+ assertEquals("value2a", props.get("prop2", String.class));
+ assertEquals("value3b", props.get("prop3", String.class));
+ assertEquals("value4b", props.get("prop4", String.class));
+ }
+
+ @Test
+ public void testWithPartialPropertyMerging() {
+ Iterator<Resource> resources = ImmutableList.of(
+ context.create().resource("/conf/resource1", "prop1", "value1a", "prop2", "value2a", PROPERTY_CONFIG_PROPERTY_INHERIT, true),
+ context.create().resource("/conf/resource2", "prop2", "value2b", "prop3", "value3b"),
+ context.create().resource("/conf/resource3", "prop4", "value4b")
+ ).iterator();
+
+ Resource inherited = underTest.getResource(resources);
+ ValueMap props = inherited.getValueMap();
+
+ assertEquals("value1a", props.get("prop1", String.class));
+ assertEquals("value2a", props.get("prop2", String.class));
+ assertEquals("value3b", props.get("prop3", String.class));
+ assertNull(props.get("prop4", String.class));
+ }
+
+}
Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/def/DefaultConfigurationInheritanceStrategyTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/def/DefaultConfigurationInheritanceStrategyTest.java
------------------------------------------------------------------------------
--- svn:keywords (added)
+++ svn:keywords Thu Nov 17 17:50:36 2016
@@ -0,0 +1 @@
+LastChangedDate LastChangedRevision LastChangedBy HeadURL Id Author
Propchange: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/impl/def/DefaultConfigurationInheritanceStrategyTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/resource/impl/ConfigurationResourceResolvingStrategyMultiplexerTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/resource/impl/ConfigurationResourceResolvingStrategyMultiplexerTest.java?rev=1770249&r1=1770248&r2=1770249&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/resource/impl/ConfigurationResourceResolvingStrategyMultiplexerTest.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/resource/impl/ConfigurationResourceResolvingStrategyMultiplexerTest.java Thu Nov 17 17:50:36 2016
@@ -23,22 +23,26 @@ import static org.apache.sling.caconfig.
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
import java.util.Collection;
+import java.util.Iterator;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.caconfig.resource.impl.def.DefaultConfigurationResourceResolvingStrategy;
import org.apache.sling.caconfig.resource.impl.def.DefaultContextPathStrategy;
import org.apache.sling.caconfig.resource.spi.ConfigurationResourceResolvingStrategy;
import org.apache.sling.hamcrest.ResourceCollectionMatchers;
+import org.apache.sling.hamcrest.ResourceMatchers;
import org.apache.sling.testing.mock.sling.junit.SlingContext;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.osgi.framework.Constants;
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterators;
public class ConfigurationResourceResolvingStrategyMultiplexerTest {
@@ -82,9 +86,10 @@ public class ConfigurationResourceResolv
@Test
public void testWithNoStrategies() {
assertNull(underTest.getResource(site1Page1, BUCKET, "test"));
-
- Collection<Resource> col1 = underTest.getResourceCollection(site1Page1, BUCKET, "feature");
- assertTrue(col1.isEmpty());
+ assertNull(underTest.getResourceCollection(site1Page1, BUCKET, "feature"));
+
+ assertNull(underTest.getResourceInheritanceChain(site1Page1, BUCKET, "test"));
+ assertNull(underTest.getResourceCollectionInheritanceChain(site1Page1, BUCKET, "feature"));
assertNull(underTest.getResourcePath(site1Page1, BUCKET, "test"));
assertNull(underTest.getResourceCollectionParentPath(site1Page1, BUCKET, "feature"));
@@ -94,13 +99,18 @@ public class ConfigurationResourceResolv
public void testWithDefaultStrategy() {
context.registerInjectActivateService(new DefaultConfigurationResourceResolvingStrategy());
- assertEquals("/conf/site1/sling:test/test", underTest.getResource(site1Page1, BUCKET, "test").getPath());
-
+ assertThat(underTest.getResource(site1Page1, BUCKET, "test"), ResourceMatchers.path("/conf/site1/sling:test/test"));
assertThat(underTest.getResourceCollection(site1Page1, BUCKET, "feature"), ResourceCollectionMatchers.paths(
"/conf/site1/sling:test/feature/c",
"/apps/conf/sling:test/feature/a",
"/libs/conf/sling:test/feature/b"));
+ assertThat(first(underTest.getResourceInheritanceChain(site1Page1, BUCKET, "test")), ResourceMatchers.path("/conf/site1/sling:test/test"));
+ assertThat(first(underTest.getResourceCollectionInheritanceChain(site1Page1, BUCKET, "feature")), ResourceCollectionMatchers.paths(
+ "/conf/site1/sling:test/feature/c",
+ "/apps/conf/sling:test/feature/a",
+ "/libs/conf/sling:test/feature/b"));
+
assertEquals("/conf/site1/sling:test/test", underTest.getResourcePath(site1Page1, BUCKET, "test"));
assertEquals("/conf/site1/sling:test/feature", underTest.getResourceCollectionParentPath(site1Page1, BUCKET, "feature"));
}
@@ -119,6 +129,20 @@ public class ConfigurationResourceResolv
return ImmutableList.copyOf(context.resourceResolver().getResource("/conf/site1/sling:test/feature").listChildren());
}
@Override
+ public Iterator<Resource> getResourceInheritanceChain(Resource resource, String bucketName, String configName) {
+ return Iterators.singletonIterator(getResource(resource, bucketName, configName));
+ }
+ @Override
+ public Collection<Iterator<Resource>> getResourceCollectionInheritanceChain(Resource resource,
+ String bucketName, String configName) {
+ return Collections2.transform(getResourceCollection(resource, bucketName, configName), new Function<Resource, Iterator<Resource>>() {
+ @Override
+ public Iterator<Resource> apply(Resource input) {
+ return Iterators.singletonIterator(input);
+ }
+ });
+ }
+ @Override
public String getResourcePath(Resource resource, String bucketName, String configName) {
return "/conf/site1/sling:test/test";
}
@@ -139,6 +163,20 @@ public class ConfigurationResourceResolv
return ImmutableList.copyOf(context.resourceResolver().getResource("/libs/conf/sling:test/feature").listChildren());
}
@Override
+ public Iterator<Resource> getResourceInheritanceChain(Resource resource, String bucketName, String configName) {
+ return Iterators.singletonIterator(getResource(resource, bucketName, configName));
+ }
+ @Override
+ public Collection<Iterator<Resource>> getResourceCollectionInheritanceChain(Resource resource,
+ String bucketName, String configName) {
+ return Collections2.transform(getResourceCollection(resource, bucketName, configName), new Function<Resource, Iterator<Resource>>() {
+ @Override
+ public Iterator<Resource> apply(Resource input) {
+ return Iterators.singletonIterator(input);
+ }
+ });
+ }
+ @Override
public String getResourcePath(Resource resource, String bucketName, String configName) {
return null;
}
@@ -148,14 +186,35 @@ public class ConfigurationResourceResolv
}
}, Constants.SERVICE_RANKING, 1000);
- assertEquals("/conf/site1/sling:test/test", underTest.getResource(site1Page1, BUCKET, "test").getPath());
-
+ assertThat(underTest.getResource(site1Page1, BUCKET, "test"), ResourceMatchers.path("/conf/site1/sling:test/test"));
assertThat(underTest.getResourceCollection(site1Page1, BUCKET, "feature"), ResourceCollectionMatchers.paths(
- "/conf/site1/sling:test/feature/c",
- "/libs/conf/sling:test/feature/b"));
+ "/conf/site1/sling:test/feature/c"));
+
+ assertThat(first(underTest.getResourceInheritanceChain(site1Page1, BUCKET, "test")), ResourceMatchers.path("/conf/site1/sling:test/test"));
+ assertThat(first(underTest.getResourceCollectionInheritanceChain(site1Page1, BUCKET, "feature")), ResourceCollectionMatchers.paths(
+ "/conf/site1/sling:test/feature/c"));
assertEquals("/conf/site1/sling:test/test", underTest.getResourcePath(site1Page1, BUCKET, "test"));
assertEquals("/conf/site1/sling:test/feature", underTest.getResourceCollectionParentPath(site1Page1, BUCKET, "feature"));
}
+ private Resource first(Iterator<Resource> resources) {
+ if (resources.hasNext()) {
+ return resources.next();
+ }
+ else {
+ return null;
+ }
+ }
+
+ private Collection<Resource> first(Collection<Iterator<Resource>> resources) {
+ return Collections2.transform(underTest.getResourceCollectionInheritanceChain(site1Page1, BUCKET, "feature"),
+ new Function<Iterator<Resource>, Resource>() {
+ @Override
+ public Resource apply(Iterator<Resource> input) {
+ return input.next();
+ }
+ });
+ }
+
}
Modified: sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/resource/impl/def/DefaultConfigurationResourceResolvingStrategyHierarchyTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/resource/impl/def/DefaultConfigurationResourceResolvingStrategyHierarchyTest.java?rev=1770249&r1=1770248&r2=1770249&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/resource/impl/def/DefaultConfigurationResourceResolvingStrategyHierarchyTest.java (original)
+++ sling/trunk/contrib/extensions/contextaware-config/impl/src/test/java/org/apache/sling/caconfig/resource/impl/def/DefaultConfigurationResourceResolvingStrategyHierarchyTest.java Thu Nov 17 17:50:36 2016
@@ -24,15 +24,21 @@ import static org.junit.Assert.assertEqu
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
+import java.util.Iterator;
+import java.util.List;
+
import org.apache.sling.api.resource.Resource;
import org.apache.sling.caconfig.resource.impl.ContextPathStrategyMultiplexer;
import org.apache.sling.caconfig.resource.spi.ConfigurationResourceResolvingStrategy;
import org.apache.sling.hamcrest.ResourceCollectionMatchers;
+import org.apache.sling.hamcrest.ResourceIteratorMatchers;
import org.apache.sling.testing.mock.sling.junit.SlingContext;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import com.google.common.collect.ImmutableList;
+
/**
* Tests with content and configurations that form a deeper nested hierarchy.
*/
@@ -62,12 +68,10 @@ public class DefaultConfigurationResourc
.resource("/content/tenant1/region1/site2", PROPERTY_CONFIG_REF, "/conf/brand1/tenant1/region1/site2");
site1Page1 = context.create().resource("/content/tenant1/region1/site1/page1");
site2Page1 = context.create().resource("/content/tenant1/region1/site2/page1");
-
}
@Test
public void testGetResource() {
- // build config resources
context.build()
.resource("/conf/brand1/tenant1/region1/site1/sling:test/cfgSite1")
.resource("/conf/brand1/tenant1/region1/sling:test/cfgRegion1")
@@ -101,8 +105,30 @@ public class DefaultConfigurationResourc
}
@Test
+ public void testGetResourceInheritanceChain() {
+ context.build()
+ .resource("/conf/brand1/tenant1/region1/site1/sling:test/test")
+ .resource("/conf/brand1/tenant1/sling:test/test")
+ .resource("/conf/global/sling:test/test")
+ .resource("/apps/conf/sling:test/test")
+ .resource("/libs/conf/sling:test/test");
+
+ assertThat(underTest.getResourceInheritanceChain(site1Page1, BUCKET, "test"), ResourceIteratorMatchers.paths(
+ "/conf/brand1/tenant1/region1/site1/sling:test/test",
+ "/conf/brand1/tenant1/sling:test/test",
+ "/conf/global/sling:test/test",
+ "/apps/conf/sling:test/test",
+ "/libs/conf/sling:test/test"));
+
+ assertThat(underTest.getResourceInheritanceChain(site2Page1, BUCKET, "test"), ResourceIteratorMatchers.paths(
+ "/conf/brand1/tenant1/sling:test/test",
+ "/conf/global/sling:test/test",
+ "/apps/conf/sling:test/test",
+ "/libs/conf/sling:test/test"));
+ }
+
+ @Test
public void testGetResourceCollectionWithInheritance() {
- // build config resources
context.build()
.resource("/conf/brand1/tenant1/region1/site1/sling:test/cfgCol", PROPERTY_CONFIG_COLLECTION_INHERIT, true).resource("site1")
.resource("/conf/brand1/tenant1/region1/sling:test/cfgCol", PROPERTY_CONFIG_COLLECTION_INHERIT, true).resource("region1")
@@ -134,8 +160,46 @@ public class DefaultConfigurationResourc
}
@Test
- public void testGetResourceCollectionContentConfigRefInheritanceAndConfigResourceInheritance() {
+ public void testGetResourceCollectionInheritanceChain() {
+ context.build()
+ .resource("/conf/brand1/tenant1/region1/site1/sling:test/cfgCol", PROPERTY_CONFIG_COLLECTION_INHERIT, true)
+ .siblingsMode()
+ .resource("item1")
+ .resource("item2")
+ .resource("/conf/brand1/tenant1/region1/sling:test/cfgCol", PROPERTY_CONFIG_COLLECTION_INHERIT, true)
+ .siblingsMode()
+ .resource("item1")
+ .resource("item3")
+ .resource("/conf/brand1/tenant1/sling:test/cfgCol", PROPERTY_CONFIG_COLLECTION_INHERIT, true)
+ .siblingsMode()
+ .resource("item4")
+ .resource("/conf/global/sling:test/cfgCol", PROPERTY_CONFIG_COLLECTION_INHERIT, true)
+ .siblingsMode()
+ .resource("item1")
+ .resource("/libs/conf/sling:test/cfgCol")
+ .siblingsMode()
+ .resource("item2")
+ .resource("item3");
+
+ List<Iterator<Resource>> resources = ImmutableList.copyOf(underTest.getResourceCollectionInheritanceChain(site1Page1, BUCKET, "cfgCol"));
+ assertEquals(4, resources.size());
+ assertThat(resources.get(0), ResourceIteratorMatchers.paths(
+ "/conf/brand1/tenant1/region1/site1/sling:test/cfgCol/item1",
+ "/conf/brand1/tenant1/region1/sling:test/cfgCol/item1",
+ "/conf/global/sling:test/cfgCol/item1"));
+ assertThat(resources.get(1), ResourceIteratorMatchers.paths(
+ "/conf/brand1/tenant1/region1/site1/sling:test/cfgCol/item2",
+ "/libs/conf/sling:test/cfgCol/item2"));
+ assertThat(resources.get(2), ResourceIteratorMatchers.paths(
+ "/conf/brand1/tenant1/region1/sling:test/cfgCol/item3",
+ "/libs/conf/sling:test/cfgCol/item3"));
+ assertThat(resources.get(3), ResourceIteratorMatchers.paths(
+ "/conf/brand1/tenant1/sling:test/cfgCol/item4"));
+ }
+
+ @Test
+ public void testGetResourceCollectionContentConfigRefInheritanceAndConfigResourceInheritance() {
context.build()
.resource("/content/level1", PROPERTY_CONFIG_REF, "/conf/a1/a2")
.resource("/content/level1/level2", PROPERTY_CONFIG_REF, "/conf/b1/b2")