CAMEL-10969: Use json-simple as json parser in JSonSchemaHelper instead of our 
own home-ground parser.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/d0f31f18
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/d0f31f18
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/d0f31f18

Branch: refs/heads/json-simple
Commit: d0f31f18f5c292f0f2e20d314adf84de45b9f15d
Parents: 372f327
Author: Claus Ibsen <davscl...@apache.org>
Authored: Sun Sep 24 11:25:23 2017 +0200
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Sun Sep 24 11:25:23 2017 +0200

----------------------------------------------------------------------
 tooling/apt/pom.xml                             |  23 ++--
 .../tools/apt/helper/JsonSchemaHelper.java      | 120 ++++++++----------
 .../maven/camel-package-maven-plugin/pom.xml    |   7 ++
 .../maven/packaging/CollectionStringBuffer.java |  58 +++++++++
 .../camel/maven/packaging/JSonSchemaHelper.java | 125 +++++++------------
 5 files changed, 176 insertions(+), 157 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/d0f31f18/tooling/apt/pom.xml
----------------------------------------------------------------------
diff --git a/tooling/apt/pom.xml b/tooling/apt/pom.xml
index 7ba1572..7e75194 100644
--- a/tooling/apt/pom.xml
+++ b/tooling/apt/pom.xml
@@ -36,12 +36,21 @@
   </properties>
 
   <dependencies>
+
+    <!-- camel annotations -->
     <dependency>
       <groupId>org.apache.camel</groupId>
       <artifactId>spi-annotations</artifactId>
       <version>${project.version}</version>
     </dependency>
 
+    <!-- json parser -->
+    <dependency>
+      <groupId>com.github.cliftonlabs</groupId>
+      <artifactId>json-simple</artifactId>
+      <version>${json-simple2-version}</version>
+    </dependency>
+
     <!-- logging -->
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>
@@ -58,7 +67,11 @@
       <artifactId>log4j-slf4j-impl</artifactId>
       <scope>test</scope>
     </dependency>
-
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <scope>test</scope>
+    </dependency>
 
     <!-- testing -->
     <dependency>
@@ -67,12 +80,6 @@
       <scope>test</scope>
     </dependency>
 
-    <!-- logging -->
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-log4j12</artifactId>
-      <scope>test</scope>
-    </dependency>
   </dependencies>
 
   <build>
@@ -82,7 +89,7 @@
         <configuration>
           <source>${jdk.version}</source>
           <target>${jdk.version}</target>
-          <!-- Disable annotation processing for ourselves. -->
+          <!-- Disable annotation processing for ourselves -->
           <proc>none</proc>
           <verbose>false</verbose>
         </configuration>

http://git-wip-us.apache.org/repos/asf/camel/blob/d0f31f18/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java
----------------------------------------------------------------------
diff --git 
a/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java
 
b/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java
index 7e3ec25..f27f95c 100644
--- 
a/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java
+++ 
b/tooling/apt/src/main/java/org/apache/camel/tools/apt/helper/JsonSchemaHelper.java
@@ -25,8 +25,9 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+
+import org.json.simple.JsonObject;
+import org.json.simple.Jsoner;
 
 /**
  * A helper class for <a href="http://json-schema.org/";>JSON schema</a>.
@@ -34,9 +35,6 @@ import java.util.regex.Pattern;
 public final class JsonSchemaHelper {
 
     private static final String VALID_CHARS = ".-='/\\!&():;";
-    // 0 = text, 1 = enum, 2 = boolean, 3 = integer or number
-    private static final Pattern PATTERN = 
Pattern.compile("\"(.+?)\"|\\[(.+)\\]|(true|false)|(-?\\d+\\.?\\d*)");
-    private static final String QUOT = "&quot;";
 
     private JsonSchemaHelper() {
     }
@@ -326,82 +324,62 @@ public final class JsonSchemaHelper {
      * @param json the json
      * @return a list of all the rows, where each row is a set of key value 
pairs with metadata
      */
+    @SuppressWarnings("unchecked")
     public static List<Map<String, String>> parseJsonSchema(String group, 
String json, boolean parseProperties) {
-        List<Map<String, String>> answer = new ArrayList<Map<String, 
String>>();
+        List<Map<String, String>> answer = new ArrayList<>();
         if (json == null) {
             return answer;
         }
 
-        boolean found = false;
-
-        // parse line by line
-        String[] lines = json.split("\n");
-        for (String line : lines) {
-            // we need to find the group first
-            if (!found) {
-                String s = line.trim();
-                found = s.startsWith("\"" + group + "\":") && s.endsWith("{");
-                continue;
-            }
-
-            // we should stop when we end the group
-            if (line.equals("  },") || line.equals("  }")) {
-                break;
-            }
-
-            // need to safe encode \" so we can parse the line
-            line = line.replaceAll("\"\\\\\"\"", '"' + QUOT + '"');
-
-            Map<String, String> row = new LinkedHashMap<String, String>();
-            Matcher matcher = PATTERN.matcher(line);
-
-            String key;
-            if (parseProperties) {
-                // when parsing properties the first key is given as name, so 
the first parsed token is the value of the name
-                key = "name";
-            } else {
-                key = null;
-            }
-            while (matcher.find()) {
-                if (key == null) {
-                    key = matcher.group(1);
-                } else {
-                    String value = matcher.group(1);
-                    if (value != null) {
-                        // its text based
-                        value = value.trim();
-                        // decode
-                        value = value.replaceAll(QUOT, "\"");
-                        value = decodeJson(value);
-                    }
-                    if (value == null) {
-                        // not text then its maybe an enum?
-                        value = matcher.group(2);
-                        if (value != null) {
-                            // its an enum so strip out " and trim spaces 
after comma
-                            value = value.replaceAll("\"", "");
-                            value = value.replaceAll(", ", ",");
-                            value = value.trim();
-                        }
+        // convert into a List<Map<String, String>> structure which is 
expected as output from this parser
+        JsonObject output = Jsoner.deserialize(json, new JsonObject());
+        for (String key : output.keySet()) {
+            Map row = output.getMap(key);
+            if (key.equals(group)) {
+                if (parseProperties) {
+                    // flattern each entry in the row with name as they key, 
and its value as the content (its a map also)
+                    for (Object obj : row.entrySet()) {
+                        Map.Entry entry = (Map.Entry) obj;
+                        Map<String, String> newRow = new LinkedHashMap();
+                        newRow.put("name", entry.getKey().toString());
+
+                        Map newData = transformMap((Map) entry.getValue());
+                        newRow.putAll(newData);
+                        answer.add(newRow);
                     }
-                    if (value == null) {
-                        // not text then its maybe a boolean?
-                        value = matcher.group(3);
-                    }
-                    if (value == null) {
-                        // not text then its maybe a integer?
-                        value = matcher.group(4);
-                    }
-                    if (value != null) {
-                        row.put(key, value);
+                } else {
+                    // flattern each entry in the row as a list of single 
Map<key, value> elements
+                    Map newData = transformMap(row);
+                    for (Object obj : newData.entrySet()) {
+                        Map.Entry entry = (Map.Entry) obj;
+                        Map<String, String> newRow = new LinkedHashMap<>();
+                        newRow.put(entry.getKey().toString(), 
entry.getValue().toString());
+                        answer.add(newRow);
                     }
-                    // reset
-                    key = null;
                 }
             }
-            if (!row.isEmpty()) {
-                answer.add(row);
+        }
+
+        return answer;
+    }
+
+    private static Map<String, String> transformMap(Map jsonMap) {
+        Map<String, String> answer = new LinkedHashMap<>();
+
+        for (Object rowObj : jsonMap.entrySet()) {
+            Map.Entry rowEntry = (Map.Entry) rowObj;
+            // if its a list type then its an enum, and we need to parse it as 
a single line separated with comma
+            // to be backwards compatible
+            Object newValue = rowEntry.getValue();
+            if (newValue instanceof List) {
+                List list = (List) newValue;
+                CollectionStringBuffer csb = new CollectionStringBuffer(",");
+                for (Object line : list) {
+                    csb.append(line);
+                }
+                newValue = csb.toString();
             }
+            answer.put(rowEntry.getKey().toString(), newValue.toString());
         }
 
         return answer;

http://git-wip-us.apache.org/repos/asf/camel/blob/d0f31f18/tooling/maven/camel-package-maven-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-package-maven-plugin/pom.xml 
b/tooling/maven/camel-package-maven-plugin/pom.xml
index d9ad4cf..7405c23 100644
--- a/tooling/maven/camel-package-maven-plugin/pom.xml
+++ b/tooling/maven/camel-package-maven-plugin/pom.xml
@@ -46,6 +46,13 @@
 
   <dependencies>
 
+    <!-- json parser -->
+    <dependency>
+      <groupId>com.github.cliftonlabs</groupId>
+      <artifactId>json-simple</artifactId>
+      <version>${json-simple2-version}</version>
+    </dependency>
+
     <dependency>
       <groupId>org.mvel</groupId>
       <artifactId>mvel2</artifactId>

http://git-wip-us.apache.org/repos/asf/camel/blob/d0f31f18/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/CollectionStringBuffer.java
----------------------------------------------------------------------
diff --git 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/CollectionStringBuffer.java
 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/CollectionStringBuffer.java
new file mode 100644
index 0000000..00c49f8
--- /dev/null
+++ 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/CollectionStringBuffer.java
@@ -0,0 +1,58 @@
+/**
+ * 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.camel.maven.packaging;
+
+/**
+ * A little helper class for converting a collection of values to a (usually 
comma separated) string.
+ */
+public class CollectionStringBuffer {
+
+    private final StringBuilder buffer = new StringBuilder();
+    private String separator;
+    private boolean first = true;
+
+    public CollectionStringBuffer() {
+        this(", ");
+    }
+
+    public CollectionStringBuffer(String separator) {
+        this.separator = separator;
+    }
+
+    @Override
+    public String toString() {
+        return buffer.toString();
+    }
+
+    public void append(Object value) {
+        if (first) {
+            first = false;
+        } else {
+            buffer.append(separator);
+        }
+        buffer.append(value);
+    }
+
+    public String getSeparator() {
+        return separator;
+    }
+
+    public void setSeparator(String separator) {
+        this.separator = separator;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/d0f31f18/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/JSonSchemaHelper.java
----------------------------------------------------------------------
diff --git 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/JSonSchemaHelper.java
 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/JSonSchemaHelper.java
index 96f3b3c..feafe5c 100644
--- 
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/JSonSchemaHelper.java
+++ 
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/JSonSchemaHelper.java
@@ -20,14 +20,11 @@ import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
-public final class JSonSchemaHelper {
+import org.json.simple.JsonObject;
+import org.json.simple.Jsoner;
 
-    // 0 = text, 1 = enum, 2 = boolean, 3 = integer or number
-    private static final Pattern PATTERN = 
Pattern.compile("\"(.+?)\"|\\[(.+)\\]|(true|false)|(-?\\d+\\.?\\d*)");
-    private static final String QUOT = "&quot;";
+public final class JSonSchemaHelper {
 
     private JSonSchemaHelper() {
     }
@@ -39,93 +36,65 @@ public final class JSonSchemaHelper {
      * @param json the json
      * @return a list of all the rows, where each row is a set of key value 
pairs with metadata
      */
+    @SuppressWarnings("unchecked")
     public static List<Map<String, String>> parseJsonSchema(String group, 
String json, boolean parseProperties) {
-        List<Map<String, String>> answer = new ArrayList<Map<String, 
String>>();
+        List<Map<String, String>> answer = new ArrayList<>();
         if (json == null) {
             return answer;
         }
 
-        boolean found = false;
-
-        // parse line by line
-        String[] lines = json.split("\n");
-        for (String line : lines) {
-            // we need to find the group first
-            if (!found) {
-                String s = line.trim();
-                found = s.startsWith("\"" + group + "\":") && s.endsWith("{");
-                continue;
-            }
-
-            // we should stop when we end the group
-            if (line.equals("  },") || line.equals("  }")) {
-                break;
-            }
-
-            // need to safe encode \" so we can parse the line
-            line = line.replaceAll("\"\\\\\"\"", '"' + QUOT + '"');
-
-            Map<String, String> row = new LinkedHashMap<String, String>();
-            Matcher matcher = PATTERN.matcher(line);
-
-            String key;
-            if (parseProperties) {
-                // when parsing properties the first key is given as name, so 
the first parsed token is the value of the name
-                key = "name";
-            } else {
-                key = null;
-            }
-            while (matcher.find()) {
-                if (key == null) {
-                    key = matcher.group(1);
-                } else {
-                    String value = matcher.group(1);
-                    if (value != null) {
-                        // its text based
-                        value = value.trim();
-                        // decode
-                        value = value.replaceAll(QUOT, "\"");
-                        value = decodeJson(value);
-                    }
-                    if (value == null) {
-                        // not text then its maybe an enum?
-                        value = matcher.group(2);
-                        if (value != null) {
-                            // its an enum so strip out " and trim spaces 
after comma
-                            value = value.replaceAll("\"", "");
-                            value = value.replaceAll(", ", ",");
-                            value = value.trim();
-                        }
-                    }
-                    if (value == null) {
-                        // not text then its maybe a boolean?
-                        value = matcher.group(3);
+        // convert into a List<Map<String, String>> structure which is 
expected as output from this parser
+        JsonObject output = Jsoner.deserialize(json, new JsonObject());
+        for (String key : output.keySet()) {
+            Map row = output.getMap(key);
+            if (key.equals(group)) {
+                if (parseProperties) {
+                    // flattern each entry in the row with name as they key, 
and its value as the content (its a map also)
+                    for (Object obj : row.entrySet()) {
+                        Map.Entry entry = (Map.Entry) obj;
+                        Map<String, String> newRow = new LinkedHashMap();
+                        newRow.put("name", entry.getKey().toString());
+
+                        Map newData = transformMap((Map) entry.getValue());
+                        newRow.putAll(newData);
+                        answer.add(newRow);
                     }
-                    if (value == null) {
-                        // not text then its maybe a integer?
-                        value = matcher.group(4);
-                    }
-                    if (value != null) {
-                        row.put(key, value);
+                } else {
+                    // flattern each entry in the row as a list of single 
Map<key, value> elements
+                    Map newData = transformMap(row);
+                    for (Object obj : newData.entrySet()) {
+                        Map.Entry entry = (Map.Entry) obj;
+                        Map<String, String> newRow = new LinkedHashMap<>();
+                        newRow.put(entry.getKey().toString(), 
entry.getValue().toString());
+                        answer.add(newRow);
                     }
-                    // reset
-                    key = null;
                 }
             }
-            if (!row.isEmpty()) {
-                answer.add(row);
-            }
         }
 
         return answer;
     }
 
-    private static String decodeJson(String value) {
-        // json encodes a \ as \\ so we need to decode from \\ back to \
-        if ("\\\\".equals(value)) {
-            value = "\\";
+    private static Map<String, String> transformMap(Map jsonMap) {
+        Map<String, String> answer = new LinkedHashMap<>();
+
+        for (Object rowObj : jsonMap.entrySet()) {
+            Map.Entry rowEntry = (Map.Entry) rowObj;
+            // if its a list type then its an enum, and we need to parse it as 
a single line separated with comma
+            // to be backwards compatible
+            Object newValue = rowEntry.getValue();
+            if (newValue instanceof List) {
+                List list = (List) newValue;
+                CollectionStringBuffer csb = new CollectionStringBuffer(",");
+                for (Object line : list) {
+                    csb.append(line);
+                }
+                newValue = csb.toString();
+            }
+            answer.put(rowEntry.getKey().toString(), newValue.toString());
         }
-        return value;
+
+        return answer;
     }
 
     /**

Reply via email to