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 "));

Reply via email to