This is an automated email from the ASF dual-hosted git repository.
cziegeler pushed a commit to branch master
in repository
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature.git
The following commit(s) were added to refs/heads/master by this push:
new 0b54409 SLING-8108 : Provide setter methods for optional context info
0b54409 is described below
commit 0b54409aeee0ff401a26b0208a03c153fdaa8d20
Author: Carsten Ziegeler <[email protected]>
AuthorDate: Wed Nov 14 10:00:20 2018 +0100
SLING-8108 : Provide setter methods for optional context info
---
.../java/org/apache/sling/feature/KeyValueMap.java | 33 +++++-
.../sling/feature/builder/ArtifactProvider.java | 3 +
.../sling/feature/builder/BuilderContext.java | 122 +++++++++++++++------
.../apache/sling/feature/builder/BuilderUtil.java | 26 ++---
.../sling/feature/builder/HandlerContext.java | 4 +-
.../sling/feature/builder/BuilderUtilTest.java | 15 ++-
.../sling/feature/builder/FeatureBuilderTest.java | 32 +++---
7 files changed, 158 insertions(+), 77 deletions(-)
diff --git a/src/main/java/org/apache/sling/feature/KeyValueMap.java
b/src/main/java/org/apache/sling/feature/KeyValueMap.java
index a00e4c6..60b49e5 100644
--- a/src/main/java/org/apache/sling/feature/KeyValueMap.java
+++ b/src/main/java/org/apache/sling/feature/KeyValueMap.java
@@ -42,8 +42,24 @@ public class KeyValueMap
}
/**
- * Put an item in the map
+ * Get an item from the map or the default.
+ *
* @param key The key of the item.
+ * @param def The default value
+ * @return The item or the default.
+ */
+ public String getOrDefault(final String key, final String def) {
+ String result = this.properties.get(key);
+ if (result == null) {
+ result = def;
+ }
+ return result;
+ }
+
+ /**
+ * Put an item in the map
+ *
+ * @param key The key of the item.
* @param value The value
*/
public void put(final String key, final String value) {
@@ -64,7 +80,20 @@ public class KeyValueMap
* @param map The other map
*/
public void putAll(final KeyValueMap map) {
- this.properties.putAll(map.properties);
+ if (map != null) {
+ this.properties.putAll(map.properties);
+ }
+ }
+
+ /**
+ * Put all items from the other map in this map
+ *
+ * @param map The other map
+ */
+ public void putAll(final Map<String, String> map) {
+ if (map != null) {
+ this.properties.putAll(map);
+ }
}
@Override
diff --git
a/src/main/java/org/apache/sling/feature/builder/ArtifactProvider.java
b/src/main/java/org/apache/sling/feature/builder/ArtifactProvider.java
index 02a1a91..c7b0b65 100644
--- a/src/main/java/org/apache/sling/feature/builder/ArtifactProvider.java
+++ b/src/main/java/org/apache/sling/feature/builder/ArtifactProvider.java
@@ -20,6 +20,9 @@ import java.io.File;
import org.apache.sling.feature.ArtifactId;
+/**
+ * The artifact provider provides a file for an artifact.
+ */
public interface ArtifactProvider {
/**
diff --git a/src/main/java/org/apache/sling/feature/builder/BuilderContext.java
b/src/main/java/org/apache/sling/feature/builder/BuilderContext.java
index 991a242..d10f81e 100644
--- a/src/main/java/org/apache/sling/feature/builder/BuilderContext.java
+++ b/src/main/java/org/apache/sling/feature/builder/BuilderContext.java
@@ -16,17 +16,18 @@
*/
package org.apache.sling.feature.builder;
+import java.util.ArrayList;
import java.util.Arrays;
-import java.util.LinkedHashMap;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.sling.feature.KeyValueMap;
/**
- * Builder context holds services used by {@link FeatureBuilder}.
+ * Builder context holds services used by {@link FeatureBuilder}.
+ *
+ * This class is not thread-safe.
*/
public class BuilderContext {
@@ -34,13 +35,17 @@ public class BuilderContext {
LATEST, HIGHEST
}
- private final ArtifactProvider artifactProvider;
+ /** The required feature provider */
private final FeatureProvider provider;
- private final Map<String, Map<String, String>> extensionConfiguration =
new ConcurrentHashMap<>();
- private final List<MergeHandler> mergeExtensions = new
CopyOnWriteArrayList<>();
- private final List<PostProcessHandler> postProcessExtensions = new
CopyOnWriteArrayList<>();
+
+ /** The optional artifact provider. */
+ private ArtifactProvider artifactProvider;
+
+ private final Map<String, KeyValueMap> extensionConfiguration = new
HashMap<>();
+ private final List<MergeHandler> mergeExtensions = new ArrayList<>();
+ private final List<PostProcessHandler> postProcessExtensions = new
ArrayList<>();
private final KeyValueMap variables = new KeyValueMap();
- private final Map<String, String> properties = new LinkedHashMap<>();
+ private final KeyValueMap frameworkProperties = new KeyValueMap();
private ArtifactMergeAlgorithm merge = ArtifactMergeAlgorithm.HIGHEST;
@@ -48,58 +53,100 @@ public class BuilderContext {
* Create a new context
*
* @param provider A provider providing the included features
- * @param ap An ArtifactProvider to resolve artifact IDs to files
* @throws IllegalArgumentException If feature provider is {@code null}
*/
- public BuilderContext(final FeatureProvider provider, final
ArtifactProvider ap) {
- this(provider, ap, null, null);
+ public BuilderContext(final FeatureProvider provider) {
+ if ( provider == null ) {
+ throw new IllegalArgumentException("Provider must not be null");
+ }
+ this.provider = provider;
}
/**
- * Create a new context
+ * Set the artifact provider
*
- * @param provider A provider providing the included features
* @param ap An ArtifactProvider to resolve artifact IDs to files
- * @param variables A map of variables to override on feature merge
- * @param properties A map of framework properties to override on feature
merge
- * @throws IllegalArgumentException If feature provider is {@code null}
+ * @return The builder context
*/
- public BuilderContext(final FeatureProvider provider, ArtifactProvider ap,
KeyValueMap variables, Map<String, String> properties) {
- if (variables != null) {
- this.variables.putAll(variables);
- }
- if (properties != null) {
- this.properties.putAll(properties);
- }
- if ( provider == null ) {
- throw new IllegalArgumentException("Provider must not be null");
- }
+ public BuilderContext setArtifactProvider(final ArtifactProvider ap) {
this.artifactProvider = ap;
- this.provider = provider;
+ return this;
}
+ /**
+ * Add overwrites for the variables
+ *
+ * @param vars The overwrites
+ * @return The builder context
+ */
+ public BuilderContext addVariablesOverwrites(final KeyValueMap vars) {
+ this.variables.putAll(vars);
+ return this;
+ }
+
+ /**
+ * Add overwrites for the framework properties
+ *
+ * @param props The overwrites
+ * @return The builder context
+ */
+ public BuilderContext addFrameworkPropertiesOverwrites(final KeyValueMap
props) {
+ this.frameworkProperties.putAll(props);
+ return this;
+ }
+
+ /**
+ * Add merge extensions
+ *
+ * @param extensions A list of merge extensions
+ * @return The builder context
+ */
public BuilderContext addMergeExtensions(final MergeHandler... extensions)
{
mergeExtensions.addAll(Arrays.asList(extensions));
return this;
}
+ /**
+ * Add post process extensions
+ *
+ * @param extensions A list of extensions
+ * @return The builder context
+ */
public BuilderContext addPostProcessExtensions(final PostProcessHandler...
extensions) {
postProcessExtensions.addAll(Arrays.asList(extensions));
return this;
}
+ /**
+ * Set the merge algorithm
+ *
+ * @param alg The algorithm
+ * @return The builder context
+ */
public BuilderContext setMergeAlgorithm(final ArtifactMergeAlgorithm alg) {
this.merge = alg;
return this;
}
/**
- * Obtain the handler configuration. The object returned can be modified
to provide
- * additional handler configurations.
+ * Set a handler configuration
+ *
+ * @param The name of the handler
+ * @param The configuration for the handler
+ * @return The builder context
+ */
+ public BuilderContext setHandlerConfiguration(final String name, final
KeyValueMap cfg) {
+ this.extensionConfiguration.put(name, cfg);
+ return this;
+ }
+
+ /**
+ * Obtain the handler configuration.
+ *
* @return The current handler configuration object. The key is the
handler name
- * and the value is a map of configuration values.
+ * and the value is a map of configuration values.
*/
- public Map<String, Map<String, String>> getHandlerConfiguration() {
+ Map<String, KeyValueMap> getHandlerConfigurations() {
return this.extensionConfiguration;
}
@@ -107,12 +154,12 @@ public class BuilderContext {
return this.artifactProvider;
}
- KeyValueMap getVariables() {
+ KeyValueMap getVariablesOverwrites() {
return this.variables;
}
- Map<String, String> getProperties() {
- return this.properties;
+ KeyValueMap getFrameworkPropertiesOverwrites() {
+ return this.frameworkProperties;
}
/**
@@ -149,7 +196,10 @@ public class BuilderContext {
* @return Cloned context
*/
BuilderContext clone(final FeatureProvider featureProvider) {
- final BuilderContext ctx = new BuilderContext(featureProvider,
this.artifactProvider, this.variables, this.properties);
+ final BuilderContext ctx = new BuilderContext(featureProvider);
+ ctx.setArtifactProvider(this.artifactProvider);
+ ctx.variables.putAll(this.variables);
+ ctx.frameworkProperties.putAll(this.frameworkProperties);
ctx.mergeExtensions.addAll(mergeExtensions);
ctx.postProcessExtensions.addAll(postProcessExtensions);
ctx.merge = this.merge;
diff --git a/src/main/java/org/apache/sling/feature/builder/BuilderUtil.java
b/src/main/java/org/apache/sling/feature/builder/BuilderUtil.java
index f8864b9..b007f4e 100644
--- a/src/main/java/org/apache/sling/feature/builder/BuilderUtil.java
+++ b/src/main/java/org/apache/sling/feature/builder/BuilderUtil.java
@@ -19,7 +19,6 @@ package org.apache.sling.feature.builder;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
@@ -107,7 +106,8 @@ class BuilderUtil {
// variables
static void mergeVariables(KeyValueMap target, KeyValueMap source,
BuilderContext context) {
- mergeWithContextOverwrite("Variable", target, source, (null !=
context) ? context.getVariables() : null);
+ mergeWithContextOverwrite("Variable", target, source,
+ (null != context) ? context.getVariablesOverwrites() : null);
}
/**
@@ -172,7 +172,8 @@ class BuilderUtil {
// framework properties (add/merge)
static void mergeFrameworkProperties(final KeyValueMap target, final
KeyValueMap source, BuilderContext context) {
- mergeWithContextOverwrite("Property", target, source, context != null
? context.getProperties().entrySet() : null);
+ mergeWithContextOverwrite("Property", target, source,
+ context != null ? context.getFrameworkPropertiesOverwrites() :
null);
}
// requirements (add)
@@ -359,7 +360,7 @@ class BuilderUtil {
private static class HandlerContextImpl implements HandlerContext {
private final ArtifactProvider artifactProvider;
- private final Map<String, String> configuration;
+ private final KeyValueMap configuration;
public HandlerContextImpl(BuilderContext bc, MergeHandler handler) {
artifactProvider = bc.getArtifactProvider();
@@ -371,16 +372,15 @@ class BuilderUtil {
configuration = getHandlerConfiguration(bc, handler);
}
- private Map<String, String> getHandlerConfiguration(BuilderContext bc,
Object handler) {
- String name = getHandlerName(handler);
- Map<String, String> cfg = null;
+ private KeyValueMap getHandlerConfiguration(BuilderContext bc, Object
handler) {
+ final KeyValueMap result = new KeyValueMap();
+
+ result.putAll(bc.getHandlerConfigurations().get("*"));
+ final String name = getHandlerName(handler);
if (name != null) {
- cfg = bc.getHandlerConfiguration().get(name);
+ result.putAll(bc.getHandlerConfigurations().get(name));
}
- if (cfg != null)
- return cfg;
- else
- return Collections.emptyMap();
+ return result;
}
private static String getHandlerName(Object handler) {
@@ -393,7 +393,7 @@ class BuilderUtil {
}
@Override
- public Map<String, String> getConfiguration() {
+ public KeyValueMap getConfiguration() {
return configuration;
}
}
diff --git a/src/main/java/org/apache/sling/feature/builder/HandlerContext.java
b/src/main/java/org/apache/sling/feature/builder/HandlerContext.java
index d89f6f3..c9637a6 100644
--- a/src/main/java/org/apache/sling/feature/builder/HandlerContext.java
+++ b/src/main/java/org/apache/sling/feature/builder/HandlerContext.java
@@ -17,7 +17,7 @@
*/
package org.apache.sling.feature.builder;
-import java.util.Map;
+import org.apache.sling.feature.KeyValueMap;
/**
* Context for an extension handler.
@@ -34,5 +34,5 @@ public interface HandlerContext {
* @return Map of provided configuration, or an empty map if there is no
configuration.
* Never {@code null}.
*/
- Map<String, String> getConfiguration();
+ KeyValueMap getConfiguration();
}
diff --git
a/src/test/java/org/apache/sling/feature/builder/BuilderUtilTest.java
b/src/test/java/org/apache/sling/feature/builder/BuilderUtilTest.java
index 798578a..ce3621f 100644
--- a/src/test/java/org/apache/sling/feature/builder/BuilderUtilTest.java
+++ b/src/test/java/org/apache/sling/feature/builder/BuilderUtilTest.java
@@ -24,7 +24,6 @@ import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -270,7 +269,7 @@ public class BuilderUtilTest {
JsonObjectBuilder jo = Json.createObjectBuilder();
boolean hasCfg = false;
- for (Map.Entry<String,String> entry :
context.getConfiguration().entrySet()) {
+ for (Map.Entry<String, String> entry : context.getConfiguration())
{
jo.add(entry.getKey(), entry.getValue());
hasCfg = true;
}
@@ -299,7 +298,7 @@ public class BuilderUtilTest {
@Test public void testMergeDefaultExtensionsFirst() {
FeatureProvider fp = Mockito.mock(FeatureProvider.class);
- BuilderContext ctx = new BuilderContext(fp, null);
+ BuilderContext ctx = new BuilderContext(fp);
Feature fs = new Feature(ArtifactId.fromMvnId("g:s:1"));
Extension e = new Extension(ExtensionType.JSON, "foo", false);
e.setJSON("{\"a\": 123}");
@@ -320,7 +319,7 @@ public class BuilderUtilTest {
@Test public void testMergeDefaultExtensionsSecond() {
FeatureProvider fp = Mockito.mock(FeatureProvider.class);
- BuilderContext ctx = new BuilderContext(fp, null);
+ BuilderContext ctx = new BuilderContext(fp);
Feature fs = new Feature(ArtifactId.fromMvnId("g:s:1"));
Extension e = new Extension(ExtensionType.JSON, "foo", false);
e.setJSON("[{\"a\": 123}]");
@@ -343,13 +342,13 @@ public class BuilderUtilTest {
}
@Test public void testMergeCustomExtensionsFirst() {
- Map<String, String> m = new HashMap<>();
+ KeyValueMap m = new KeyValueMap();
m.put("abc", "def");
m.put("hij", "klm");
FeatureProvider fp = Mockito.mock(FeatureProvider.class);
- BuilderContext ctx = new BuilderContext(fp, null);
- ctx.getHandlerConfiguration().put("TestMergeHandler", m);
+ BuilderContext ctx = new BuilderContext(fp);
+ ctx.setHandlerConfiguration("TestMergeHandler", m);
ctx.addMergeExtensions(new TestMergeHandler());
Feature fs = new Feature(ArtifactId.fromMvnId("g:s:1"));
Extension e = new Extension(ExtensionType.JSON, "foo", false);
@@ -371,7 +370,7 @@ public class BuilderUtilTest {
@Test public void testMergeCustomExtensionsSecond() {
FeatureProvider fp = Mockito.mock(FeatureProvider.class);
- BuilderContext ctx = new BuilderContext(fp, null);
+ BuilderContext ctx = new BuilderContext(fp);
ctx.addMergeExtensions(new TestMergeHandler());
Feature fs = new Feature(ArtifactId.fromMvnId("g:s:1"));
Extension e = new Extension(ExtensionType.JSON, "foo", false);
diff --git
a/src/test/java/org/apache/sling/feature/builder/FeatureBuilderTest.java
b/src/test/java/org/apache/sling/feature/builder/FeatureBuilderTest.java
index 78133cf..ddcd43d 100644
--- a/src/test/java/org/apache/sling/feature/builder/FeatureBuilderTest.java
+++ b/src/test/java/org/apache/sling/feature/builder/FeatureBuilderTest.java
@@ -248,7 +248,7 @@ public class FeatureBuilderTest {
assertFalse(base.isAssembled());
- final Feature assembled = FeatureBuilder.assemble(base, new
BuilderContext(provider, null));
+ final Feature assembled = FeatureBuilder.assemble(base, new
BuilderContext(provider));
equals(base, assembled);
}
@@ -313,7 +313,7 @@ public class FeatureBuilderTest {
result.getConfigurations().add(co3);
// assemble
- final Feature assembled = FeatureBuilder.assemble(base, new
BuilderContext(provider, null));
+ final Feature assembled = FeatureBuilder.assemble(base, new
BuilderContext(provider));
// and test
equals(result, assembled);
@@ -335,7 +335,7 @@ public class FeatureBuilderTest {
public Feature provide(ArtifactId id) {
return null;
}
- }, null), a, b);
+ }), a, b);
assertEquals(1, features.length);
assertEquals(idB, features[0].getId());
}
@@ -354,7 +354,7 @@ public class FeatureBuilderTest {
public Feature provide(ArtifactId id) {
return null;
}
- }, null), a, b);
+ }), a, b);
assertEquals(1, features.length);
assertEquals(idB, features[0].getId());
}
@@ -383,7 +383,7 @@ public class FeatureBuilderTest {
}
return null;
}
- }, null));
+ }));
final Set<ArtifactId> set = new HashSet<>();
for(final Artifact c : feature.getBundles()) {
set.add(c.getId());
@@ -417,7 +417,7 @@ public class FeatureBuilderTest {
}
return null;
}
- }, null));
+ }));
final Set<ArtifactId> set = new HashSet<>();
for(final Artifact c : feature.getBundles()) {
set.add(c.getId());
@@ -449,7 +449,7 @@ public class FeatureBuilderTest {
}
return null;
}
- }, null));
+ }));
fail();
} catch ( final IllegalStateException ise) {
// expected
@@ -482,7 +482,7 @@ public class FeatureBuilderTest {
}
return null;
}
- }, null));
+ }));
final Set<ArtifactId> set = new HashSet<>();
for(final Artifact c :
feature.getExtensions().getByName("foo").getArtifacts()) {
set.add(c.getId());
@@ -518,7 +518,7 @@ public class FeatureBuilderTest {
}
return null;
}
- }, null));
+ }));
final Set<ArtifactId> set = new HashSet<>();
for(final Artifact c :
feature.getExtensions().getByName("foo").getArtifacts()) {
set.add(c.getId());
@@ -552,7 +552,7 @@ public class FeatureBuilderTest {
}
return null;
}
- }, null));
+ }));
fail();
} catch ( final IllegalStateException ise) {
// expected
@@ -576,7 +576,7 @@ public class FeatureBuilderTest {
public Feature provide(ArtifactId id) {
return null;
}
- }, null), a, b);
+ }), a, b);
final Extension list =
target.getExtensions().getByName(FeatureConstants.EXTENSION_NAME_ASSEMBLED_FEATURES);
assertNotNull(list);
assertEquals(1, list.getArtifacts().size());
@@ -625,7 +625,7 @@ public class FeatureBuilderTest {
{
return null;
}
- }, null, override, null), aFeature, bFeature);
+ }).addVariablesOverwrites(override), aFeature, bFeature);
KeyValueMap vars = new KeyValueMap();
vars.putAll(kvMapA);
@@ -646,7 +646,7 @@ public class FeatureBuilderTest {
{
return null;
}
- }, null, override, null), aFeature, bFeature);
+ }).addVariablesOverwrites(override), aFeature, bFeature);
fail("Excepted merge exception");
} catch (IllegalStateException expected) {}
@@ -659,7 +659,7 @@ public class FeatureBuilderTest {
{
return null;
}
- }, null, override, null), aFeature, bFeature);
+ }).addVariablesOverwrites(override), aFeature, bFeature);
vars = new KeyValueMap();
vars.putAll(kvMapA);
@@ -678,7 +678,7 @@ public class FeatureBuilderTest {
{
return null;
}
- }, null, override, null), aFeature, bFeature);
+ }).addVariablesOverwrites(override), aFeature, bFeature);
vars.put("var2", null);
assertTrue(cFeature.getVariables().equals(vars));
@@ -709,7 +709,7 @@ public class FeatureBuilderTest {
}
return null;
}
- }, null));
+ }));
fail();
} catch (final IllegalStateException ise) {
assertTrue(ise.getMessage().contains(" final "));