diff options
Diffstat (limited to 'ncomp-utils-java/src/main/java/org/json/XML.java')
-rw-r--r-- | ncomp-utils-java/src/main/java/org/json/XML.java | 458 |
1 files changed, 458 insertions, 0 deletions
diff --git a/ncomp-utils-java/src/main/java/org/json/XML.java b/ncomp-utils-java/src/main/java/org/json/XML.java new file mode 100644 index 0000000..c3719af --- /dev/null +++ b/ncomp-utils-java/src/main/java/org/json/XML.java @@ -0,0 +1,458 @@ + +/*- + * ============LICENSE_START========================================== + * OPENECOMP - DCAE + * =================================================================== + * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Licensed 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. + * ============LICENSE_END============================================ + */ + +package org.json; + +/* +Copyright (c) 2002 JSON.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +import java.util.Iterator; + + +/** + * This provides static methods to convert an XML text into a JSONObject, + * and to covert a JSONObject into an XML text. + * @author JSON.org + * @version 2008-10-14 + */ +public class XML { + + /** The Character '&'. */ + public static final Character AMP = new Character('&'); + + /** The Character '''. */ + public static final Character APOS = new Character('\''); + + /** The Character '!'. */ + public static final Character BANG = new Character('!'); + + /** The Character '='. */ + public static final Character EQ = new Character('='); + + /** The Character '>'. */ + public static final Character GT = new Character('>'); + + /** The Character '<'. */ + public static final Character LT = new Character('<'); + + /** The Character '?'. */ + public static final Character QUEST = new Character('?'); + + /** The Character '"'. */ + public static final Character QUOT = new Character('"'); + + /** The Character '/'. */ + public static final Character SLASH = new Character('/'); + + /** + * Replace special characters with XML escapes: + * <pre> + * & <small>(ampersand)</small> is replaced by &amp; + * < <small>(less than)</small> is replaced by &lt; + * > <small>(greater than)</small> is replaced by &gt; + * " <small>(double quote)</small> is replaced by &quot; + * </pre> + * @param string The string to be escaped. + * @return The escaped string. + */ + public static String escape(String string) { + StringBuffer sb = new StringBuffer(); + for (int i = 0, len = string.length(); i < len; i++) { + char c = string.charAt(i); + switch (c) { + case '&': + sb.append("&"); + break; + case '<': + sb.append("<"); + break; + case '>': + sb.append(">"); + break; + case '"': + sb.append("""); + break; + default: + sb.append(c); + } + } + return sb.toString(); + } + + /** + * Throw an exception if the string contains whitespace. + * Whitespace is not allowed in tagNames and attributes. + * @param string + * @throws JSONException + */ + public static void noSpace(String string) throws JSONException { + int i, length = string.length(); + if (length == 0) { + throw new JSONException("Empty string."); + } + for (i = 0; i < length; i += 1) { + if (Character.isWhitespace(string.charAt(i))) { + throw new JSONException("'" + string + + "' contains a space character."); + } + } + } + + /** + * Scan the content following the named tag, attaching it to the context. + * @param x The XMLTokener containing the source string. + * @param context The JSONObject that will include the new material. + * @param name The tag name. + * @return true if the close tag is processed. + * @throws JSONException + */ + private static boolean parse(XMLTokener x, JSONObject context, + String name) throws JSONException { + char c; + int i; + String n; + JSONObject o = null; + String s; + Object t; + +// Test for and skip past these forms: +// <!-- ... --> +// <! ... > +// <![ ... ]]> +// <? ... ?> +// Report errors for these forms: +// <> +// <= +// << + + t = x.nextToken(); + +// <! + + if (t == BANG) { + c = x.next(); + if (c == '-') { + if (x.next() == '-') { + x.skipPast("-->"); + return false; + } + x.back(); + } else if (c == '[') { + t = x.nextToken(); + if (t.equals("CDATA")) { + if (x.next() == '[') { + s = x.nextCDATA(); + if (s.length() > 0) { + context.accumulate("content", s); + } + return false; + } + } + throw x.syntaxError("Expected 'CDATA['"); + } + i = 1; + do { + t = x.nextMeta(); + if (t == null) { + throw x.syntaxError("Missing '>' after '<!'."); + } else if (t == LT) { + i += 1; + } else if (t == GT) { + i -= 1; + } + } while (i > 0); + return false; + } else if (t == QUEST) { + +// <? + + x.skipPast("?>"); + return false; + } else if (t == SLASH) { + +// Close tag </ + + t = x.nextToken(); + if (name == null) { + throw x.syntaxError("Mismatched close tag" + t); + } + if (!t.equals(name)) { + throw x.syntaxError("Mismatched " + name + " and " + t); + } + if (x.nextToken() != GT) { + throw x.syntaxError("Misshaped close tag"); + } + return true; + + } else if (t instanceof Character) { + throw x.syntaxError("Misshaped tag"); + +// Open tag < + + } else { + n = (String)t; + t = null; + o = new JSONObject(); + for (;;) { + if (t == null) { + t = x.nextToken(); + } + +// attribute = value + + if (t instanceof String) { + s = (String)t; + t = x.nextToken(); + if (t == EQ) { + t = x.nextToken(); + if (!(t instanceof String)) { + throw x.syntaxError("Missing value"); + } + o.accumulate(s, JSONObject.stringToValue((String)t)); + t = null; + } else { + o.accumulate(s, ""); + } + +// Empty tag <.../> + + } else if (t == SLASH) { + if (x.nextToken() != GT) { + throw x.syntaxError("Misshaped tag"); + } + context.accumulate(n, o); + return false; + +// Content, between <...> and </...> + + } else if (t == GT) { + for (;;) { + t = x.nextContent(); + if (t == null) { + if (n != null) { + throw x.syntaxError("Unclosed tag " + n); + } + return false; + } else if (t instanceof String) { + s = (String)t; + if (s.length() > 0) { + o.accumulate("content", JSONObject.stringToValue(s)); + } + +// Nested element + + } else if (t == LT) { + if (parse(x, o, n)) { + if (o.length() == 0) { + context.accumulate(n, ""); + } else if (o.length() == 1 && + o.opt("content") != null) { + context.accumulate(n, o.opt("content")); + } else { + context.accumulate(n, o); + } + return false; + } + } + } + } else { + throw x.syntaxError("Misshaped tag"); + } + } + } + } + + + /** + * Convert a well-formed (but not necessarily valid) XML string into a + * JSONObject. Some information may be lost in this transformation + * because JSON is a data format and XML is a document format. XML uses + * elements, attributes, and content text, while JSON uses unordered + * collections of name/value pairs and arrays of values. JSON does not + * does not like to distinguish between elements and attributes. + * Sequences of similar elements are represented as JSONArrays. Content + * text may be placed in a "content" member. Comments, prologs, DTDs, and + * <code><[ [ ]]></code> are ignored. + * @param string The source string. + * @return A JSONObject containing the structured data from the XML string. + * @throws JSONException + */ + public static JSONObject toJSONObject(String string) throws JSONException { + JSONObject o = new JSONObject(); + XMLTokener x = new XMLTokener(string); + while (x.more() && x.skipPast("<")) { + parse(x, o, null); + } + return o; + } + + + /** + * Convert a JSONObject into a well-formed, element-normal XML string. + * @param o A JSONObject. + * @return A string. + * @throws JSONException + */ + public static String toString(Object o) throws JSONException { + return toString(o, null); + } + + + /** + * Convert a JSONObject into a well-formed, element-normal XML string. + * @param o A JSONObject. + * @param tagName The optional name of the enclosing tag. + * @return A string. + * @throws JSONException + */ + public static String toString(Object o, String tagName) + throws JSONException { + StringBuffer b = new StringBuffer(); + int i; + JSONArray ja; + JSONObject jo; + String k; + Iterator<String> keys; + int len; + String s; + Object v; + if (o instanceof JSONObject) { + +// Emit <tagName> + + if (tagName != null) { + b.append('<'); + b.append(tagName); + b.append('>'); + } + +// Loop thru the keys. + + jo = (JSONObject)o; + keys = jo.keys(); + while (keys.hasNext()) { + k = keys.next().toString(); + v = jo.opt(k); + if (v == null) { + v = ""; + } + if (v instanceof String) { + s = (String)v; + } else { + s = null; + } + +// Emit content in body + + if (k.equals("content")) { + if (v instanceof JSONArray) { + ja = (JSONArray)v; + len = ja.length(); + for (i = 0; i < len; i += 1) { + if (i > 0) { + b.append('\n'); + } + b.append(escape(ja.get(i).toString())); + } + } else { + b.append(escape(v.toString())); + } + +// Emit an array of similar keys + + } else if (v instanceof JSONArray) { + ja = (JSONArray)v; + len = ja.length(); + for (i = 0; i < len; i += 1) { + v = ja.get(i); + if (v instanceof JSONArray) { + b.append('<'); + b.append(k); + b.append('>'); + b.append(toString(v)); + b.append("</"); + b.append(k); + b.append('>'); + } else { + b.append(toString(v, k)); + } + } + } else if (v.equals("")) { + b.append('<'); + b.append(k); + b.append("/>"); + +// Emit a new tag <k> + + } else { + b.append(toString(v, k)); + } + } + if (tagName != null) { + +// Emit the </tagname> close tag + + b.append("</"); + b.append(tagName); + b.append('>'); + } + return b.toString(); + +// XML does not have good support for arrays. If an array appears in a place +// where XML is lacking, synthesize an <array> element. + + } else if (o instanceof JSONArray) { + ja = (JSONArray)o; + len = ja.length(); + for (i = 0; i < len; ++i) { + v = ja.opt(i); + b.append(toString(v, (tagName == null) ? "array" : tagName)); + } + return b.toString(); + } else { + s = (o == null) ? "null" : escape(o.toString()); + return (tagName == null) ? "\"" + s + "\"" : + (s.length() == 0) ? "<" + tagName + "/>" : + "<" + tagName + ">" + s + "</" + tagName + ">"; + } + } +}
\ No newline at end of file |