You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by da...@apache.org on 2018/03/16 14:41:08 UTC

[sling-whiteboard] branch master updated: [Feature Model] Support '#' keys as comments

This is an automated email from the ASF dual-hosted git repository.

davidb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git


The following commit(s) were added to refs/heads/master by this push:
     new 97c694f  [Feature Model] Support '#' keys as comments
97c694f is described below

commit 97c694f7aa387bb5f32cd8dda5c57cf9c3fd84e3
Author: David Bosschaert <da...@gmail.com>
AuthorDate: Fri Mar 16 14:40:05 2018 +0000

    [Feature Model] Support '#' keys as comments
    
    When a key starts with a '#' then both the key and its value are
    considered a comment for the Feature Model.
---
 .../feature/support/json/FeatureJSONReader.java    |  8 ++---
 .../sling/feature/support/json/JSONReaderBase.java | 41 ++++++++++++++++++++++
 .../support/json/FeatureJSONReaderTest.java        | 21 +++++++++--
 .../src/test/resources/features/test3.json         | 17 +++++++--
 4 files changed, 77 insertions(+), 10 deletions(-)

diff --git a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/json/FeatureJSONReader.java b/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/json/FeatureJSONReader.java
index 50d5a0b..13fa62d 100644
--- a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/json/FeatureJSONReader.java
+++ b/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/json/FeatureJSONReader.java
@@ -16,7 +16,6 @@
  */
 package org.apache.sling.feature.support.json;
 
-import org.apache.felix.configurator.impl.json.JSONUtil;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Feature;
 import org.apache.sling.feature.Include;
@@ -97,6 +96,7 @@ public class FeatureJSONReader extends JSONReaderBase {
     /** The variables from the JSON. */
     private Map<String, String> variables;
 
+    /** The current reading phase. */
     private final Phase phase;
 
     /**
@@ -119,9 +119,7 @@ public class FeatureJSONReader extends JSONReaderBase {
     private Feature readFeature(final Reader reader)
     throws IOException {
         final JsonObject json = Json.createReader(new StringReader(minify(reader))).readObject();
-
-        @SuppressWarnings("unchecked")
-        final Map<String, Object> map = (Map<String, Object>) JSONUtil.getValue(json);
+        final Map<String, Object> map = getJsonMap(json);
 
         final ArtifactId fId;
         if ( !map.containsKey(JSONConstants.FEATURE_ID) ) {
@@ -160,8 +158,6 @@ public class FeatureJSONReader extends JSONReaderBase {
         return feature;
     }
 
-
-
     @Override
     protected Object handleResolveVars(Object val) {
         if (phase == Phase.RESOLVE) {
diff --git a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/json/JSONReaderBase.java b/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/json/JSONReaderBase.java
index a014ff1..f972c23 100644
--- a/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/json/JSONReaderBase.java
+++ b/featuremodel/feature-support/src/main/java/org/apache/sling/feature/support/json/JSONReaderBase.java
@@ -36,14 +36,18 @@ import java.io.StringWriter;
 import java.io.Writer;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Enumeration;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 
 import javax.json.Json;
 import javax.json.JsonArrayBuilder;
+import javax.json.JsonObject;
 import javax.json.JsonObjectBuilder;
 import javax.json.JsonStructure;
 import javax.json.JsonWriter;
@@ -83,6 +87,43 @@ abstract class JSONReaderBase {
         return contents;
     }
 
+    /** Get the JSON object as a map, removing all comments that start with a '#' character
+     */
+    protected Map<String, Object> getJsonMap(JsonObject json) {
+        @SuppressWarnings("unchecked")
+        Map<String, Object> m = (Map<String, Object>) JSONUtil.getValue(json);
+
+        removeComments(m);
+        return m;
+    }
+
+    private void removeComments(Map<String, Object> m) {
+        for(Iterator<Map.Entry<String, Object>> it = m.entrySet().iterator(); it.hasNext(); ) {
+            Entry<String, ?> entry = it.next();
+            if (entry.getKey().startsWith("#")) {
+                it.remove();
+            } else if (entry.getValue() instanceof Map) {
+                @SuppressWarnings("unchecked")
+                Map<String, Object> embedded = (Map<String, Object>) entry.getValue();
+                removeComments(embedded);
+            } else if (entry.getValue() instanceof Collection) {
+                Collection<?> embedded = (Collection<?>) entry.getValue();
+                removeComments(embedded);
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private void removeComments(Collection<?> embedded) {
+        for (Object el : embedded) {
+            if (el instanceof Collection) {
+                removeComments((Collection<?>) el);
+            } else if (el instanceof Map) {
+                removeComments((Map<String, Object>) el);
+            }
+        }
+    }
+
     protected String getProperty(final Map<String, Object> map, final String key) throws IOException {
         final Object val = map.get(key);
         if ( val != null ) {
diff --git a/featuremodel/feature-support/src/test/java/org/apache/sling/feature/support/json/FeatureJSONReaderTest.java b/featuremodel/feature-support/src/test/java/org/apache/sling/feature/support/json/FeatureJSONReaderTest.java
index e464f48..8410877 100644
--- a/featuremodel/feature-support/src/test/java/org/apache/sling/feature/support/json/FeatureJSONReaderTest.java
+++ b/featuremodel/feature-support/src/test/java/org/apache/sling/feature/support/json/FeatureJSONReaderTest.java
@@ -34,11 +34,13 @@ import java.lang.reflect.Field;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Dictionary;
+import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
@@ -135,6 +137,8 @@ public class FeatureJSONReaderTest {
         assertEquals("Requirement substitution should not happen at launch time",
                 "(&(osgi.contract=${contract.name})(&(version>=3.0)(!(version>=4.0))))",
                 req.getDirectives().get("filter"));
+        assertEquals("There should be 1 directive, comments should be ignored",
+                1, req.getDirectives().size());
 
         List<Capability> caps = feature.getCapabilities();
         Capability cap = null;
@@ -147,13 +151,26 @@ public class FeatureJSONReaderTest {
         assertEquals("Capability substitution should not happen at launch time",
                 Collections.singletonList("org.osgi.${svc}.http.runtime.HttpServiceRuntime"),
                 cap.getAttributes().get("objectClass"));
+        assertEquals("There should be 1 attribute, comments should be ignored",
+                1, cap.getAttributes().size());
 
         KeyValueMap fwProps = feature.getFrameworkProperties();
         assertEquals("something", fwProps.get("brave"));
+        assertEquals("There should be 3 framework properties, comments not included",
+                3, fwProps.size());
 
         Configurations configurations = feature.getConfigurations();
-        Configuration config = configurations.getConfiguration("my.pid2");
-        Dictionary<String, Object> props = config.getProperties();
+        assertEquals("There should be 2 configurations, comments not included",
+                2, configurations.size());
+
+        Configuration config1 = configurations.getConfiguration("my.pid2");
+        for (Enumeration<?> en = config1.getProperties().elements(); en.hasMoreElements(); ) {
+            assertFalse("The comment should not show up in the configuration",
+                "comment".equals(en.nextElement()));
+        }
+
+        Configuration config2 = configurations.getConfiguration("my.pid2");
+        Dictionary<String, Object> props = config2.getProperties();
         assertEquals("aaright!", props.get("a.value"));
         assertEquals("right!bb", props.get("b.value"));
         assertEquals("creally?c", props.get("c.value"));
diff --git a/featuremodel/feature-support/src/test/resources/features/test3.json b/featuremodel/feature-support/src/test/resources/features/test3.json
index eb44d5c..630239d 100644
--- a/featuremodel/feature-support/src/test/resources/features/test3.json
+++ b/featuremodel/feature-support/src/test/resources/features/test3.json
@@ -1,5 +1,7 @@
 {
-    "id" : "org.apache.sling/test2/1.1",
+    "#": "A comment",
+    "# array": ["array", "comment"],
+    "id": "org.apache.sling/test2/1.1",
 
     "variables": {
          "common.version": "1.2.3",
@@ -16,12 +18,14 @@
 
     "includes" : [
          {
+             "#": "comment",
              "id" : "${sling.gid}/sling/10",
              "removals" : {
                  "configurations" : [
                  ],
                  "bundles" : [
                  ],
+                 "#": "comment",
                  "framework-properties" : [
                  ]
              }
@@ -30,13 +34,16 @@
     "requirements" : [
           {
               "namespace" : "osgi.${ns}",
+              "#": "comment",
               "directives" : {
+                  "#": "comment",
                   "filter" : "(&(osgi.contract=${contract.name})(&(version>=3.0)(!(version>=4.0))))"
               }
           }
     ],
     "capabilities" : [
         {
+             "#": "comment",
              "namespace" : "osgi.implementation",
              "attributes" : {
                    "osgi.implementation" : "osgi.http",
@@ -49,6 +56,7 @@
         {
              "namespace" : "osgi.${svc}",
              "attributes" : {
+                  "#": "comment",
                   "objectClass:List<String>" : "org.osgi.${svc}.http.runtime.HttpServiceRuntime"
              },
              "directives" : {
@@ -68,6 +76,8 @@
         }
     ],
     "framework-properties" : {
+        "# one": "comment",
+        "# two": "comment",
         "foo" : 1,
         "brave" : "${something}",
         "org.apache.felix.scr.directory" : "launchpad/scr"
@@ -76,7 +86,8 @@
             {
               "id" : "org.apache.sling/oak-server/1.0.0",
               "hash" : "4632463464363646436",
-              "start-order" : 1
+              "start-order" : 1,
+              "#": "comment"
             },
             {
               "id" : "org.apache.sling/application-bundle/2.0.0",
@@ -88,7 +99,9 @@
             }
     ],
     "configurations" : {
+        "#": "comment",
         "my.pid" : {
+           "#": "comment",
            "foo" : 5,
            "bar" : "test",
            "number:Integer" : 7

-- 
To stop receiving notification emails like this one, please contact
davidb@apache.org.