[DMAAP-48] Initial code import
[dmaap/datarouter.git] / datarouter-prov / src / main / java / org / json / JSONML.java
diff --git a/datarouter-prov/src/main/java/org/json/JSONML.java b/datarouter-prov/src/main/java/org/json/JSONML.java
new file mode 100644 (file)
index 0000000..5afb599
--- /dev/null
@@ -0,0 +1,489 @@
+/*******************************************************************************\r
+ * ============LICENSE_START==================================================\r
+ * * org.onap.dmaap\r
+ * * ===========================================================================\r
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
+ * * ===========================================================================\r
+ * * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * * you may not use this file except in compliance with the License.\r
+ * * You may obtain a copy of the License at\r
+ * * \r
+ *  *      http://www.apache.org/licenses/LICENSE-2.0\r
+ * * \r
+ *  * Unless required by applicable law or agreed to in writing, software\r
+ * * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * * See the License for the specific language governing permissions and\r
+ * * limitations under the License.\r
+ * * ============LICENSE_END====================================================\r
+ * *\r
+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
+ * *\r
+ ******************************************************************************/\r
+package org.json;\r
+\r
+/*\r
+Copyright (c) 2008 JSON.org\r
+\r
+Permission is hereby granted, free of charge, to any person obtaining a copy\r
+of this software and associated documentation files (the "Software"), to deal\r
+in the Software without restriction, including without limitation the rights\r
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+copies of the Software, and to permit persons to whom the Software is\r
+furnished to do so, subject to the following conditions:\r
+\r
+The above copyright notice and this permission notice shall be included in all\r
+copies or substantial portions of the Software.\r
+\r
+The Software shall be used for Good, not Evil.\r
+\r
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+SOFTWARE.\r
+*/\r
+\r
+import java.util.Iterator;\r
+\r
+\r
+/**\r
+ * This provides static methods to convert an XML text into a JSONArray or\r
+ * JSONObject, and to covert a JSONArray or JSONObject into an XML text using\r
+ * the JsonML transform.\r
+ *\r
+ * @author JSON.org\r
+ * @version 2012-03-28\r
+ */\r
+public class JSONML {\r
+\r
+    /**\r
+     * Parse XML values and store them in a JSONArray.\r
+     * @param x       The XMLTokener containing the source string.\r
+     * @param arrayForm true if array form, false if object form.\r
+     * @param ja      The JSONArray that is containing the current tag or null\r
+     *     if we are at the outermost level.\r
+     * @return A JSONArray if the value is the outermost tag, otherwise null.\r
+     * @throws JSONException\r
+     */\r
+    private static Object parse(\r
+        XMLTokener x,\r
+        boolean    arrayForm,\r
+        JSONArray  ja\r
+    ) throws JSONException {\r
+        String     attribute;\r
+        char       c;\r
+        String       closeTag = null;\r
+        int        i;\r
+        JSONArray  newja = null;\r
+        JSONObject newjo = null;\r
+        Object     token;\r
+        String       tagName = null;\r
+\r
+// Test for and skip past these forms:\r
+//      <!-- ... -->\r
+//      <![  ... ]]>\r
+//      <!   ...   >\r
+//      <?   ...  ?>\r
+\r
+        while (true) {\r
+            if (!x.more()) {\r
+                throw x.syntaxError("Bad XML");\r
+            }\r
+            token = x.nextContent();\r
+            if (token == XML.LT) {\r
+                token = x.nextToken();\r
+                if (token instanceof Character) {\r
+                    if (token == XML.SLASH) {\r
+\r
+// Close tag </\r
+\r
+                        token = x.nextToken();\r
+                        if (!(token instanceof String)) {\r
+                            throw new JSONException(\r
+                                    "Expected a closing name instead of '" +\r
+                                    token + "'.");\r
+                        }\r
+                        if (x.nextToken() != XML.GT) {\r
+                            throw x.syntaxError("Misshaped close tag");\r
+                        }\r
+                        return token;\r
+                    } else if (token == XML.BANG) {\r
+\r
+// <!\r
+\r
+                        c = x.next();\r
+                        if (c == '-') {\r
+                            if (x.next() == '-') {\r
+                                x.skipPast("-->");\r
+                            } else {\r
+                                x.back();\r
+                            }\r
+                        } else if (c == '[') {\r
+                            token = x.nextToken();\r
+                            if (token.equals("CDATA") && x.next() == '[') {\r
+                                if (ja != null) {\r
+                                    ja.put(x.nextCDATA());\r
+                                }\r
+                            } else {\r
+                                throw x.syntaxError("Expected 'CDATA['");\r
+                            }\r
+                        } else {\r
+                            i = 1;\r
+                            do {\r
+                                token = x.nextMeta();\r
+                                if (token == null) {\r
+                                    throw x.syntaxError("Missing '>' after '<!'.");\r
+                                } else if (token == XML.LT) {\r
+                                    i += 1;\r
+                                } else if (token == XML.GT) {\r
+                                    i -= 1;\r
+                                }\r
+                            } while (i > 0);\r
+                        }\r
+                    } else if (token == XML.QUEST) {\r
+\r
+// <?\r
+\r
+                        x.skipPast("?>");\r
+                    } else {\r
+                        throw x.syntaxError("Misshaped tag");\r
+                    }\r
+\r
+// Open tag <\r
+\r
+                } else {\r
+                    if (!(token instanceof String)) {\r
+                        throw x.syntaxError("Bad tagName '" + token + "'.");\r
+                    }\r
+                    tagName = (String)token;\r
+                    newja = new JSONArray();\r
+                    newjo = new JSONObject();\r
+                    if (arrayForm) {\r
+                        newja.put(tagName);\r
+                        if (ja != null) {\r
+                            ja.put(newja);\r
+                        }\r
+                    } else {\r
+                        newjo.put("tagName", tagName);\r
+                        if (ja != null) {\r
+                            ja.put(newjo);\r
+                        }\r
+                    }\r
+                    token = null;\r
+                    for (;;) {\r
+                        if (token == null) {\r
+                            token = x.nextToken();\r
+                        }\r
+                        if (token == null) {\r
+                            throw x.syntaxError("Misshaped tag");\r
+                        }\r
+                        if (!(token instanceof String)) {\r
+                            break;\r
+                        }\r
+\r
+// attribute = value\r
+\r
+                        attribute = (String)token;\r
+                        if (!arrayForm && ("tagName".equals(attribute) || "childNode".equals(attribute))) {\r
+                            throw x.syntaxError("Reserved attribute.");\r
+                        }\r
+                        token = x.nextToken();\r
+                        if (token == XML.EQ) {\r
+                            token = x.nextToken();\r
+                            if (!(token instanceof String)) {\r
+                                throw x.syntaxError("Missing value");\r
+                            }\r
+                            newjo.accumulate(attribute, XML.stringToValue((String)token));\r
+                            token = null;\r
+                        } else {\r
+                            newjo.accumulate(attribute, "");\r
+                        }\r
+                    }\r
+                    if (arrayForm && newjo.length() > 0) {\r
+                        newja.put(newjo);\r
+                    }\r
+\r
+// Empty tag <.../>\r
+\r
+                    if (token == XML.SLASH) {\r
+                        if (x.nextToken() != XML.GT) {\r
+                            throw x.syntaxError("Misshaped tag");\r
+                        }\r
+                        if (ja == null) {\r
+                            if (arrayForm) {\r
+                                return newja;\r
+                            } else {\r
+                                return newjo;\r
+                            }\r
+                        }\r
+\r
+// Content, between <...> and </...>\r
+\r
+                    } else {\r
+                        if (token != XML.GT) {\r
+                            throw x.syntaxError("Misshaped tag");\r
+                        }\r
+                        closeTag = (String)parse(x, arrayForm, newja);\r
+                        if (closeTag != null) {\r
+                            if (!closeTag.equals(tagName)) {\r
+                                throw x.syntaxError("Mismatched '" + tagName +\r
+                                        "' and '" + closeTag + "'");\r
+                            }\r
+                            tagName = null;\r
+                            if (!arrayForm && newja.length() > 0) {\r
+                                newjo.put("childNodes", newja);\r
+                            }\r
+                            if (ja == null) {\r
+                                if (arrayForm) {\r
+                                    return newja;\r
+                                } else {\r
+                                    return newjo;\r
+                                }\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+            } else {\r
+                if (ja != null) {\r
+                    ja.put(token instanceof String\r
+                        ? XML.stringToValue((String)token)\r
+                        : token);\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * Convert a well-formed (but not necessarily valid) XML string into a\r
+     * JSONArray using the JsonML transform. Each XML tag is represented as\r
+     * a JSONArray in which the first element is the tag name. If the tag has\r
+     * attributes, then the second element will be JSONObject containing the\r
+     * name/value pairs. If the tag contains children, then strings and\r
+     * JSONArrays will represent the child tags.\r
+     * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.\r
+     * @param string The source string.\r
+     * @return A JSONArray containing the structured data from the XML string.\r
+     * @throws JSONException\r
+     */\r
+    public static JSONArray toJSONArray(String string) throws JSONException {\r
+        return toJSONArray(new XMLTokener(string));\r
+    }\r
+\r
+\r
+    /**\r
+     * Convert a well-formed (but not necessarily valid) XML string into a\r
+     * JSONArray using the JsonML transform. Each XML tag is represented as\r
+     * a JSONArray in which the first element is the tag name. If the tag has\r
+     * attributes, then the second element will be JSONObject containing the\r
+     * name/value pairs. If the tag contains children, then strings and\r
+     * JSONArrays will represent the child content and tags.\r
+     * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.\r
+     * @param x An XMLTokener.\r
+     * @return A JSONArray containing the structured data from the XML string.\r
+     * @throws JSONException\r
+     */\r
+    public static JSONArray toJSONArray(XMLTokener x) throws JSONException {\r
+        return (JSONArray)parse(x, true, null);\r
+    }\r
+\r
+\r
+    /**\r
+     * Convert a well-formed (but not necessarily valid) XML string into a\r
+     * JSONObject using the JsonML transform. Each XML tag is represented as\r
+     * a JSONObject with a "tagName" property. If the tag has attributes, then\r
+     * the attributes will be in the JSONObject as properties. If the tag\r
+     * contains children, the object will have a "childNodes" property which\r
+     * will be an array of strings and JsonML JSONObjects.\r
+\r
+     * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.\r
+     * @param x An XMLTokener of the XML source text.\r
+     * @return A JSONObject containing the structured data from the XML string.\r
+     * @throws JSONException\r
+     */\r
+    public static JSONObject toJSONObject(XMLTokener x) throws JSONException {\r
+           return (JSONObject)parse(x, false, null);\r
+    }\r
+\r
+\r
+    /**\r
+     * Convert a well-formed (but not necessarily valid) XML string into a\r
+     * JSONObject using the JsonML transform. Each XML tag is represented as\r
+     * a JSONObject with a "tagName" property. If the tag has attributes, then\r
+     * the attributes will be in the JSONObject as properties. If the tag\r
+     * contains children, the object will have a "childNodes" property which\r
+     * will be an array of strings and JsonML JSONObjects.\r
+\r
+     * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.\r
+     * @param string The XML source text.\r
+     * @return A JSONObject containing the structured data from the XML string.\r
+     * @throws JSONException\r
+     */\r
+    public static JSONObject toJSONObject(String string) throws JSONException {\r
+        return toJSONObject(new XMLTokener(string));\r
+    }\r
+\r
+\r
+    /**\r
+     * Reverse the JSONML transformation, making an XML text from a JSONArray.\r
+     * @param ja A JSONArray.\r
+     * @return An XML string.\r
+     * @throws JSONException\r
+     */\r
+    public static String toString(JSONArray ja) throws JSONException {\r
+        int             i;\r
+        JSONObject   jo;\r
+        String       key;\r
+        Iterator<String> keys;\r
+        int             length;\r
+        Object         object;\r
+        StringBuffer sb = new StringBuffer();\r
+        String       tagName;\r
+        String       value;\r
+\r
+// Emit <tagName\r
+\r
+        tagName = ja.getString(0);\r
+        XML.noSpace(tagName);\r
+        tagName = XML.escape(tagName);\r
+        sb.append('<');\r
+        sb.append(tagName);\r
+\r
+        object = ja.opt(1);\r
+        if (object instanceof JSONObject) {\r
+            i = 2;\r
+            jo = (JSONObject)object;\r
+\r
+// Emit the attributes\r
+\r
+            keys = jo.keys();\r
+            while (keys.hasNext()) {\r
+                key = keys.next().toString();\r
+                XML.noSpace(key);\r
+                value = jo.optString(key);\r
+                if (value != null) {\r
+                    sb.append(' ');\r
+                    sb.append(XML.escape(key));\r
+                    sb.append('=');\r
+                    sb.append('"');\r
+                    sb.append(XML.escape(value));\r
+                    sb.append('"');\r
+                }\r
+            }\r
+        } else {\r
+            i = 1;\r
+        }\r
+\r
+//Emit content in body\r
+\r
+        length = ja.length();\r
+        if (i >= length) {\r
+            sb.append('/');\r
+            sb.append('>');\r
+        } else {\r
+            sb.append('>');\r
+            do {\r
+                object = ja.get(i);\r
+                i += 1;\r
+                if (object != null) {\r
+                    if (object instanceof String) {\r
+                        sb.append(XML.escape(object.toString()));\r
+                    } else if (object instanceof JSONObject) {\r
+                        sb.append(toString((JSONObject)object));\r
+                    } else if (object instanceof JSONArray) {\r
+                        sb.append(toString((JSONArray)object));\r
+                    }\r
+                }\r
+            } while (i < length);\r
+            sb.append('<');\r
+            sb.append('/');\r
+            sb.append(tagName);\r
+            sb.append('>');\r
+        }\r
+        return sb.toString();\r
+    }\r
+\r
+    /**\r
+     * Reverse the JSONML transformation, making an XML text from a JSONObject.\r
+     * The JSONObject must contain a "tagName" property. If it has children,\r
+     * then it must have a "childNodes" property containing an array of objects.\r
+     * The other properties are attributes with string values.\r
+     * @param jo A JSONObject.\r
+     * @return An XML string.\r
+     * @throws JSONException\r
+     */\r
+    public static String toString(JSONObject jo) throws JSONException {\r
+        StringBuffer sb = new StringBuffer();\r
+        int          i;\r
+        JSONArray    ja;\r
+        String       key;\r
+        Iterator<String> keys;\r
+        int          length;\r
+        Object         object;\r
+        String       tagName;\r
+        String       value;\r
+\r
+//Emit <tagName\r
+\r
+        tagName = jo.optString("tagName");\r
+        if (tagName == null) {\r
+            return XML.escape(jo.toString());\r
+        }\r
+        XML.noSpace(tagName);\r
+        tagName = XML.escape(tagName);\r
+        sb.append('<');\r
+        sb.append(tagName);\r
+\r
+//Emit the attributes\r
+\r
+        keys = jo.keys();\r
+        while (keys.hasNext()) {\r
+            key = keys.next().toString();\r
+            if (!"tagName".equals(key) && !"childNodes".equals(key)) {\r
+                XML.noSpace(key);\r
+                value = jo.optString(key);\r
+                if (value != null) {\r
+                    sb.append(' ');\r
+                    sb.append(XML.escape(key));\r
+                    sb.append('=');\r
+                    sb.append('"');\r
+                    sb.append(XML.escape(value));\r
+                    sb.append('"');\r
+                }\r
+            }\r
+        }\r
+\r
+//Emit content in body\r
+\r
+        ja = jo.optJSONArray("childNodes");\r
+        if (ja == null) {\r
+            sb.append('/');\r
+            sb.append('>');\r
+        } else {\r
+            sb.append('>');\r
+            length = ja.length();\r
+            for (i = 0; i < length; i += 1) {\r
+                object = ja.get(i);\r
+                if (object != null) {\r
+                    if (object instanceof String) {\r
+                        sb.append(XML.escape(object.toString()));\r
+                    } else if (object instanceof JSONObject) {\r
+                        sb.append(toString((JSONObject)object));\r
+                    } else if (object instanceof JSONArray) {\r
+                        sb.append(toString((JSONArray)object));\r
+                    } else {\r
+                        sb.append(object.toString());\r
+                    }\r
+                }\r
+            }\r
+            sb.append('<');\r
+            sb.append('/');\r
+            sb.append(tagName);\r
+            sb.append('>');\r
+        }\r
+        return sb.toString();\r
+    }\r
+}\r