[DMAAP-48] Initial code import
[dmaap/datarouter.git] / datarouter-prov / src / main / java / org / json / XMLTokener.java
diff --git a/datarouter-prov/src/main/java/org/json/XMLTokener.java b/datarouter-prov/src/main/java/org/json/XMLTokener.java
new file mode 100644 (file)
index 0000000..bdb5466
--- /dev/null
@@ -0,0 +1,390 @@
+/*******************************************************************************\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
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+/*\r
+Copyright (c) 2002 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
+/**\r
+ * The XMLTokener extends the JSONTokener to provide additional methods\r
+ * for the parsing of XML texts.\r
+ * @author JSON.org\r
+ * @version 2012-11-13\r
+ */\r
+public class XMLTokener extends JSONTokener {\r
+\r
+\r
+   /** The table of entity values. It initially contains Character values for\r
+    * amp, apos, gt, lt, quot.\r
+    */\r
+   public static final Map<String,Character> entity;\r
+\r
+   static {\r
+       entity = new HashMap<String,Character>(8);\r
+       entity.put("amp",  XML.AMP);\r
+       entity.put("apos", XML.APOS);\r
+       entity.put("gt",   XML.GT);\r
+       entity.put("lt",   XML.LT);\r
+       entity.put("quot", XML.QUOT);\r
+   }\r
+\r
+    /**\r
+     * Construct an XMLTokener from a string.\r
+     * @param s A source string.\r
+     */\r
+    public XMLTokener(String s) {\r
+        super(s);\r
+    }\r
+\r
+    /**\r
+     * Get the text in the CDATA block.\r
+     * @return The string up to the <code>]]&gt;</code>.\r
+     * @throws JSONException If the <code>]]&gt;</code> is not found.\r
+     */\r
+    public String nextCDATA() throws JSONException {\r
+        char         c;\r
+        int          i;\r
+        StringBuffer sb = new StringBuffer();\r
+        for (;;) {\r
+            c = next();\r
+            if (end()) {\r
+                throw syntaxError("Unclosed CDATA");\r
+            }\r
+            sb.append(c);\r
+            i = sb.length() - 3;\r
+            if (i >= 0 && sb.charAt(i) == ']' &&\r
+                          sb.charAt(i + 1) == ']' && sb.charAt(i + 2) == '>') {\r
+                sb.setLength(i);\r
+                return sb.toString();\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * Get the next XML outer token, trimming whitespace. There are two kinds\r
+     * of tokens: the '<' character which begins a markup tag, and the content\r
+     * text between markup tags.\r
+     *\r
+     * @return  A string, or a '<' Character, or null if there is no more\r
+     * source text.\r
+     * @throws JSONException\r
+     */\r
+    public Object nextContent() throws JSONException {\r
+        char         c;\r
+        StringBuffer sb;\r
+        do {\r
+            c = next();\r
+        } while (Character.isWhitespace(c));\r
+        if (c == 0) {\r
+            return null;\r
+        }\r
+        if (c == '<') {\r
+            return XML.LT;\r
+        }\r
+        sb = new StringBuffer();\r
+        for (;;) {\r
+            if (c == '<' || c == 0) {\r
+                back();\r
+                return sb.toString().trim();\r
+            }\r
+            if (c == '&') {\r
+                sb.append(nextEntity(c));\r
+            } else {\r
+                sb.append(c);\r
+            }\r
+            c = next();\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * Return the next entity. These entities are translated to Characters:\r
+     *     <code>&amp;  &apos;  &gt;  &lt;  &quot;</code>.\r
+     * @param ampersand An ampersand character.\r
+     * @return  A Character or an entity String if the entity is not recognized.\r
+     * @throws JSONException If missing ';' in XML entity.\r
+     */\r
+    public Object nextEntity(char ampersand) throws JSONException {\r
+        StringBuffer sb = new StringBuffer();\r
+        for (;;) {\r
+            char c = next();\r
+            if (Character.isLetterOrDigit(c) || c == '#') {\r
+                sb.append(Character.toLowerCase(c));\r
+            } else if (c == ';') {\r
+                break;\r
+            } else {\r
+                throw syntaxError("Missing ';' in XML entity: &" + sb);\r
+            }\r
+        }\r
+        String string = sb.toString();\r
+        Object object = entity.get(string);\r
+        return object != null ? object : ampersand + string + ";";\r
+    }\r
+\r
+\r
+    /**\r
+     * Returns the next XML meta token. This is used for skipping over <!...>\r
+     * and <?...?> structures.\r
+     * @return Syntax characters (<code>< > / = ! ?</code>) are returned as\r
+     *  Character, and strings and names are returned as Boolean. We don't care\r
+     *  what the values actually are.\r
+     * @throws JSONException If a string is not properly closed or if the XML\r
+     *  is badly structured.\r
+     */\r
+    public Object nextMeta() throws JSONException {\r
+        char c;\r
+        char q;\r
+        do {\r
+            c = next();\r
+        } while (Character.isWhitespace(c));\r
+        switch (c) {\r
+        case 0:\r
+            throw syntaxError("Misshaped meta tag");\r
+        case '<':\r
+            return XML.LT;\r
+        case '>':\r
+            return XML.GT;\r
+        case '/':\r
+            return XML.SLASH;\r
+        case '=':\r
+            return XML.EQ;\r
+        case '!':\r
+            return XML.BANG;\r
+        case '?':\r
+            return XML.QUEST;\r
+        case '"':\r
+        case '\'':\r
+            q = c;\r
+            for (;;) {\r
+                c = next();\r
+                if (c == 0) {\r
+                    throw syntaxError("Unterminated string");\r
+                }\r
+                if (c == q) {\r
+                    return Boolean.TRUE;\r
+                }\r
+            }\r
+        default:\r
+            for (;;) {\r
+                c = next();\r
+                if (Character.isWhitespace(c)) {\r
+                    return Boolean.TRUE;\r
+                }\r
+                switch (c) {\r
+                case 0:\r
+                case '<':\r
+                case '>':\r
+                case '/':\r
+                case '=':\r
+                case '!':\r
+                case '?':\r
+                case '"':\r
+                case '\'':\r
+                    back();\r
+                    return Boolean.TRUE;\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * Get the next XML Token. These tokens are found inside of angle\r
+     * brackets. It may be one of these characters: <code>/ > = ! ?</code> or it\r
+     * may be a string wrapped in single quotes or double quotes, or it may be a\r
+     * name.\r
+     * @return a String or a Character.\r
+     * @throws JSONException If the XML is not well formed.\r
+     */\r
+    public Object nextToken() throws JSONException {\r
+        char c;\r
+        char q;\r
+        StringBuffer sb;\r
+        do {\r
+            c = next();\r
+        } while (Character.isWhitespace(c));\r
+        switch (c) {\r
+        case 0:\r
+            throw syntaxError("Misshaped element");\r
+        case '<':\r
+            throw syntaxError("Misplaced '<'");\r
+        case '>':\r
+            return XML.GT;\r
+        case '/':\r
+            return XML.SLASH;\r
+        case '=':\r
+            return XML.EQ;\r
+        case '!':\r
+            return XML.BANG;\r
+        case '?':\r
+            return XML.QUEST;\r
+\r
+// Quoted string\r
+\r
+        case '"':\r
+        case '\'':\r
+            q = c;\r
+            sb = new StringBuffer();\r
+            for (;;) {\r
+                c = next();\r
+                if (c == 0) {\r
+                    throw syntaxError("Unterminated string");\r
+                }\r
+                if (c == q) {\r
+                    return sb.toString();\r
+                }\r
+                if (c == '&') {\r
+                    sb.append(nextEntity(c));\r
+                } else {\r
+                    sb.append(c);\r
+                }\r
+            }\r
+        default:\r
+\r
+// Name\r
+\r
+            sb = new StringBuffer();\r
+            for (;;) {\r
+                sb.append(c);\r
+                c = next();\r
+                if (Character.isWhitespace(c)) {\r
+                    return sb.toString();\r
+                }\r
+                switch (c) {\r
+                case 0:\r
+                    return sb.toString();\r
+                case '>':\r
+                case '/':\r
+                case '=':\r
+                case '!':\r
+                case '?':\r
+                case '[':\r
+                case ']':\r
+                    back();\r
+                    return sb.toString();\r
+                case '<':\r
+                case '"':\r
+                case '\'':\r
+                    throw syntaxError("Bad character in a name");\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * Skip characters until past the requested string.\r
+     * If it is not found, we are left at the end of the source with a result of false.\r
+     * @param to A string to skip past.\r
+     * @throws JSONException\r
+     */\r
+    public boolean skipPast(String to) throws JSONException {\r
+        boolean b;\r
+        char c;\r
+        int i;\r
+        int j;\r
+        int offset = 0;\r
+        int length = to.length();\r
+        char[] circle = new char[length];\r
+\r
+        /*\r
+         * First fill the circle buffer with as many characters as are in the\r
+         * to string. If we reach an early end, bail.\r
+         */\r
+\r
+        for (i = 0; i < length; i += 1) {\r
+            c = next();\r
+            if (c == 0) {\r
+                return false;\r
+            }\r
+            circle[i] = c;\r
+        }\r
+\r
+        /* We will loop, possibly for all of the remaining characters. */\r
+\r
+        for (;;) {\r
+            j = offset;\r
+            b = true;\r
+\r
+            /* Compare the circle buffer with the to string. */\r
+\r
+            for (i = 0; i < length; i += 1) {\r
+                if (circle[j] != to.charAt(i)) {\r
+                    b = false;\r
+                    break;\r
+                }\r
+                j += 1;\r
+                if (j >= length) {\r
+                    j -= length;\r
+                }\r
+            }\r
+\r
+            /* If we exit the loop with b intact, then victory is ours. */\r
+\r
+            if (b) {\r
+                return true;\r
+            }\r
+\r
+            /* Get the next character. If there isn't one, then defeat is ours. */\r
+\r
+            c = next();\r
+            if (c == 0) {\r
+                return false;\r
+            }\r
+            /*\r
+             * Shove the character in the circle buffer and advance the\r
+             * circle offset. The offset is mod n.\r
+             */\r
+            circle[offset] = c;\r
+            offset += 1;\r
+            if (offset >= length) {\r
+                offset -= length;\r
+            }\r
+        }\r
+    }\r
+}\r