diff --git a/CHANGELOG.md b/CHANGELOG.md index d6b7965e..84d4a775 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # OSGL Tool Change Log +1.26.2 - 01/Jan/2021 +* Improve XML to JSON convert logic #243 + 1.26.1 - 26/Dec/2020 * Drop `javax.xml.bind` dependency #242 * OS util cannot detect `Mac OS X` #241 diff --git a/src/main/java/org/osgl/Lang.java b/src/main/java/org/osgl/Lang.java index 22983b24..8028d821 100644 --- a/src/main/java/org/osgl/Lang.java +++ b/src/main/java/org/osgl/Lang.java @@ -47,7 +47,6 @@ import java.nio.charset.StandardCharsets; import java.security.SecureRandom; import java.sql.ResultSet; -import java.sql.Timestamp; import java.text.*; import java.util.*; import java.util.concurrent.*; @@ -3214,13 +3213,11 @@ public String convert(Document document, Object hint) { } }; - public static final TypeConverter XML_DOCUMENT_TO_JSON = new XmlDocumentToJsonObject(); + public static final TypeConverter XML_DOCUMENT_TO_JSON = new XmlToJson(); - public static final TypeConverter XML_DOCUMENT_TO_JSON_ARRAY = new XmlDocumentToJsonArray(); + public static final TypeConverter JSON_OBJECT_TO_XML_DOCUMENT = new JsonObjectToXml(); - public static final TypeConverter JSON_OBJECT_TO_XML_DOCUMENT = new JsonObjectToXmlDocument(); - - public static final TypeConverter JSON_ARRAY_TO_XML_DOCUMENT = new JsonArrayToXmlDocument(); + public static final TypeConverter JSON_ARRAY_TO_XML_DOCUMENT = new JsonArrayToXml(); public static final TypeConverter ANY_TO_JSON_OBJECT = new TypeConverter() { @Override diff --git a/src/main/java/org/osgl/util/converter/JsonArrayToXmlDocument.java b/src/main/java/org/osgl/util/converter/JsonArrayToXml.java similarity index 94% rename from src/main/java/org/osgl/util/converter/JsonArrayToXmlDocument.java rename to src/main/java/org/osgl/util/converter/JsonArrayToXml.java index b1126dee..ede6de18 100644 --- a/src/main/java/org/osgl/util/converter/JsonArrayToXmlDocument.java +++ b/src/main/java/org/osgl/util/converter/JsonArrayToXml.java @@ -25,7 +25,7 @@ import org.osgl.util.S; import org.w3c.dom.Document; -public class JsonArrayToXmlDocument extends Lang.TypeConverter { +public class JsonArrayToXml extends Lang.TypeConverter { @Override public Document convert(JSONArray array) { return JsonXmlConvertHint.convert(array, OsglConfig.xmlRootTag(), OsglConfig.xmlListItemTag()); diff --git a/src/main/java/org/osgl/util/converter/JsonObjectToXmlDocument.java b/src/main/java/org/osgl/util/converter/JsonObjectToXml.java similarity index 94% rename from src/main/java/org/osgl/util/converter/JsonObjectToXmlDocument.java rename to src/main/java/org/osgl/util/converter/JsonObjectToXml.java index dbe71b1f..84f8836d 100644 --- a/src/main/java/org/osgl/util/converter/JsonObjectToXmlDocument.java +++ b/src/main/java/org/osgl/util/converter/JsonObjectToXml.java @@ -25,7 +25,7 @@ import org.osgl.util.S; import org.w3c.dom.Document; -public class JsonObjectToXmlDocument extends Lang.TypeConverter { +public class JsonObjectToXml extends Lang.TypeConverter { @Override public Document convert(JSONObject json) { return JsonXmlConvertHint.convert(json, OsglConfig.xmlRootTag(), OsglConfig.xmlListItemTag()); diff --git a/src/main/java/org/osgl/util/converter/XmlDocumentToJsonArray.java b/src/main/java/org/osgl/util/converter/XmlDocumentToJsonArray.java deleted file mode 100644 index 0742e4dd..00000000 --- a/src/main/java/org/osgl/util/converter/XmlDocumentToJsonArray.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.osgl.util.converter; - -/*- - * #%L - * Java Tool - * %% - * Copyright (C) 2014 - 2018 OSGL (Open Source General Library) - * %% - * 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. - * #L% - */ - -import com.alibaba.fastjson.*; -import org.osgl.*; -import org.osgl.util.IO; -import org.osgl.util.XML; -import org.w3c.dom.Document; - -import java.io.StringWriter; - -public class XmlDocumentToJsonArray extends Lang.TypeConverter { - @Override - public JSONArray convert(Document document) { - return convert(document, null); - } - - @Override - public JSONArray convert(Document document, Object hint) { - String rootTag = OsglConfig.xmlRootTag(); - String listItemTag = OsglConfig.xmlListItemTag(); - if (hint instanceof JsonXmlConvertHint) { - JsonXmlConvertHint hint1 = $.cast(hint); - rootTag = hint1.rootTag; - listItemTag = hint1.listItemTag; - } else if (hint instanceof String) { - rootTag = $.cast(hint); - } - return (JSONArray) XmlDocumentToJsonUtil.convert(document, rootTag, listItemTag, true); - } - - private static void foo() { - String s = "\n\t\n\t\tx\n1y2"; - Document document = XML.read(s); - StringWriter w = new StringWriter(); - IO.write(document).pretty().to(w); - System.out.println(s); - //System.out.println(w.toString()); - //System.out.println($.convert(document).hint(XML.HINT_PRETTY).toString()); - JSONObject json = $.convert(document).to(JSONObject.class); - System.out.println(JSON.toJSONString(json, true)); - Document doc2 = $.convert(json).to(Document.class); - System.out.println($.convert(doc2).hint(XML.HINT_PRETTY).toString()); - } - - private static void wx() { - String s = "\n" + - " \n" + - " \n" + - " `1348831860`\n" + - " \n" + - " \n" + - " `1234567890123456`\n" + - ""; - Document document = XML.read(s); - JSONObject json = $.convert(document).to(JSONObject.class); - System.out.println(JSON.toJSONString(json, true)); - } - - public static void main(String[] args) { - wx(); - } -} diff --git a/src/main/java/org/osgl/util/converter/XmlDocumentToJsonObject.java b/src/main/java/org/osgl/util/converter/XmlDocumentToJsonObject.java deleted file mode 100644 index 0759d4b1..00000000 --- a/src/main/java/org/osgl/util/converter/XmlDocumentToJsonObject.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.osgl.util.converter; - -/*- - * #%L - * Java Tool - * %% - * Copyright (C) 2014 - 2018 OSGL (Open Source General Library) - * %% - * 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. - * #L% - */ - -import com.alibaba.fastjson.JSONObject; -import org.osgl.*; -import org.w3c.dom.Document; - -public class XmlDocumentToJsonObject extends Lang.TypeConverter { - @Override - public JSONObject convert(Document document) { - return convert(document, null); - } - - @Override - public JSONObject convert(Document document, Object hint) { - String rootTag = OsglConfig.xmlRootTag(); - String listItemTag = OsglConfig.xmlListItemTag(); - if (hint instanceof JsonXmlConvertHint) { - JsonXmlConvertHint hint1 = $.cast(hint); - rootTag = hint1.rootTag; - listItemTag = hint1.listItemTag; - } else if (hint instanceof String) { - rootTag = $.cast(hint); - } - return (JSONObject) XmlDocumentToJsonUtil.convert(document, rootTag, listItemTag, false); - } -} diff --git a/src/main/java/org/osgl/util/converter/XmlDocumentToJsonUtil.java b/src/main/java/org/osgl/util/converter/XmlDocumentToJsonUtil.java deleted file mode 100644 index 34c30708..00000000 --- a/src/main/java/org/osgl/util/converter/XmlDocumentToJsonUtil.java +++ /dev/null @@ -1,155 +0,0 @@ -package org.osgl.util.converter; - -/*- - * #%L - * Java Tool - * %% - * Copyright (C) 2014 - 2018 OSGL (Open Source General Library) - * %% - * 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. - * #L% - */ - -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import org.osgl.$; -import org.osgl.util.C; -import org.osgl.util.E; -import org.osgl.util.S; -import org.w3c.dom.*; - -import java.math.BigInteger; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -class XmlDocumentToJsonUtil { - - static Object convert(Document document, String rootTag, String listItemTag, boolean array) { - NodeList list = document.getChildNodes(); - if (0 == list.getLength()) { - return array ? new JSONArray() : new JSONObject(); - } - Node root = list.item(0); - return convert(root.getChildNodes(), listItemTag); - } - - static Object convert(Node node, String listItemTag) { - switch (node.getNodeType()) { - case Node.CDATA_SECTION_NODE: - case Node.TEXT_NODE: - return convert(node.getTextContent()); - case Node.ELEMENT_NODE: - Object ret = convert(node.getChildNodes(), listItemTag); - if (ret instanceof JSONObject) { - ((JSONObject) ret).putAll(convertAttributes(node)); - } else { - ((JSONArray) ret).add(C.Map("_attributes", convertAttributes(node))); - } - return ret; - default: - return null; - } - } - - static Map convertAttributes(Node node) { - NamedNodeMap attributes = node.getAttributes(); - if (null == attributes) return C.EMPTY_MAP; - Map ret = new HashMap<>(); - for (int i = attributes.getLength() - 1; i >= 0; --i) { - Node attribute = attributes.item(i); - ret.put(attribute.getNodeName(), attribute.getNodeValue()); - } - return ret; - } - - private static Object convert(NodeList list, String listItemTag) { - int size = list.getLength(); - if (1 == size) { - Node node = list.item(0); - short nodeType = node.getNodeType(); - if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) { - return convert(node.getTextContent()); - } - } - JSONObject json = new JSONObject(); - List array = null; - boolean retArray = false; - for (int i = 0; i < size; ++i) { - Node node = list.item(i); - if (node.getNodeType() == Node.TEXT_NODE) { - continue; - } - String name = nameOf(node); - if (listItemTag.equals(name)) { - retArray = true; - if (null == array) { - array = new JSONArray(); - } - array.add(convert(node, listItemTag)); - } else if (json.containsKey(name)) { - Object o = json.get(name); - if (o instanceof List) { - array = (List)o; - } else { - array = new JSONArray(); - array.add(o); - } - array.add(convert(node, listItemTag)); - json.put(name, array); - } else { - json.put(name, convert(node, listItemTag)); - } - } - return retArray ? array : json; - } - - static Object convert(String s) { - if ("true".equals(s)) { - return Boolean.TRUE; - } else if ("false".equals(s)) { - return Boolean.FALSE; - } else if (S.isInt(s)) { - if (9 >= s.length()) { - return Integer.parseInt(s); - } else if (19 >= s.length()) { - long l = Long.parseLong(s); - if (l <= Integer.MAX_VALUE) { - return (int)l; - } - return l; - } else { - try { - return Long.parseLong(s); - } catch (NumberFormatException e) { - return new BigInteger(s); - } - } - } else { - try { - return Double.parseDouble(s); - } catch (NumberFormatException e) { - return s; - } - } - } - - static String nameOf(Node node) { - String name = node.getLocalName(); - if (null == name) { - name = node.getNodeName(); - } - return name; - } - -} diff --git a/src/main/java/org/osgl/util/converter/XmlToJson.java b/src/main/java/org/osgl/util/converter/XmlToJson.java new file mode 100644 index 00000000..43acca0d --- /dev/null +++ b/src/main/java/org/osgl/util/converter/XmlToJson.java @@ -0,0 +1,314 @@ +package org.osgl.util.converter; + +/*- + * #%L + * Java Tool + * %% + * Copyright (C) 2014 - 2021 OSGL (Open Source General Library) + * %% + * 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. + * #L% + */ + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import org.osgl.$; +import org.osgl.Lang; +import org.osgl.util.S; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + +public class XmlToJson extends Lang.TypeConverter { + + public static final int HINT_MERGE_MAP = 0x00001000; + + public static final String INNER_VALUE = "innerValue"; + + @Override + public JSONObject convert(Document document) { + return convert(document, (Object)0); + } + + @Override + public JSONObject convert(Document document, Object hint) { + Node root = rootNode(document); + if (null == root) { + return new JSONObject(); + } + int theHint = hint instanceof Integer ? (int)hint : 0; + return convert(root.getChildNodes(), new JSONObject(), theHint); + } + + private JSONObject convert(NodeList nodeList, JSONObject bag, int hint) { + int len = nodeList.getLength(); + for (int i = 0; i < len; ++i) { + Node node = nodeList.item(i); + merge(node, bag, hint); + } + return bag; + } + + private void merge(Node node, JSONObject bag, int hint) { + String nodeName = nameOf(node); + Object existing = bag.get(nodeName); + Object innerValue = convertNodeInner(node, hint); + Object merged = merge(innerValue, existing, hint); + if (null != merged) { + bag.put(nodeName, merged); + } + } + + private Object convertNodeInner(Node node, int hint) { + NodeList children = node.getChildNodes(); + NamedNodeMap attributes = node.getAttributes(); + boolean hasChild = null != children && children.getLength() > 0; + boolean hasAttribute = null != attributes && attributes.getLength() > 0; + if (!hasChild && !hasAttribute) { + return null; + } + JSONObject convertedAttributes = convert(attributes); + Object convertedChildren = convert(children, hint); + if (null == convertedChildren) { + return convertedAttributes; + } + if ($.bool(convertedAttributes)) { + if (convertedChildren instanceof JSONObject) { + convertedAttributes.putAll((JSONObject) convertedChildren); + } else { + convertedAttributes.put(INNER_VALUE, convertedChildren); + } + return convertedAttributes; + } + return convertedChildren; + } + + private Object convert(NodeList children, int hint) { + int len = null == children ? 0 : children.getLength(); + if (0 == len) { + return null; + } + Object prev = null; + for (int i = 0; i < len; ++i) { + Object cur = convert(children.item(i), hint); + prev = merge(cur, prev, hint); + } + return prev; + } + + private Object convert(Node node, int hint) { + switch (node.getNodeType()) { + case Node.TEXT_NODE: + case Node.CDATA_SECTION_NODE: + return convert(node.getNodeValue()); + case Node.ELEMENT_NODE: + JSONObject bag = new JSONObject(); + bag.put(node.getNodeName(), convertNodeInner(node, hint)); + return bag; + default: + return null; + } + } + + private JSONObject convert(NamedNodeMap attributes) { + int len = null == attributes ? 0 : attributes.getLength(); + if (0 == len) { + return null; + } + JSONObject bag = new JSONObject(); + for (int i = 0; i < len; ++i) { + Node attribute = attributes.item(i); + bag.put(attribute.getNodeName(), convert(attribute.getNodeValue())); + } + return bag; + } + + private static Object merge(Object value, Object existing, int hint) { + if (null == existing) { + return value; + } else if (null == value) { + return existing; + } + if (doMergeMap(hint)) { + if (value instanceof JSONObject) { + if (existing instanceof JSONObject) { + return mergeMap((JSONObject) value, (JSONObject) existing); + } else { + JSONObject map = (JSONObject) value; + Object innerValue = map.get(INNER_VALUE); + if (null == innerValue) { + innerValue = value; + } else { + if (innerValue instanceof JSONArray) { + ((JSONArray) innerValue).add(existing); + } else { + JSONArray array = new JSONArray(); + array.add(existing); + array.add(innerValue); + innerValue = array; + } + } + if (innerValue instanceof JSONObject) { + map.putAll((JSONObject) innerValue); + } else { + map.put(INNER_VALUE, innerValue); + } + return map; + } + } else { + if (existing instanceof JSONObject) { + JSONObject map = (JSONObject) existing; + Object innerValue = map.get(INNER_VALUE); + if (null == innerValue) { + innerValue = value; + } else { + if (innerValue instanceof JSONArray) { + ((JSONArray) innerValue).add(value); + } else { + JSONArray array = new JSONArray(); + array.add(innerValue); + array.add(value); + innerValue = array; + } + } + if (innerValue instanceof JSONObject) { + map.putAll((JSONObject) innerValue); + } else { + map.put(INNER_VALUE, innerValue); + } + return map; + } else { + if (existing instanceof JSONArray) { + ((JSONArray) existing).add(value); + return existing; + } else { + JSONArray array = new JSONArray(); + array.add(existing); + array.add(value); + return array; + } + } + } + } else { + if (existing instanceof List) { + ((List) existing).add(value); + return existing; + } + List list = new JSONArray(); + list.add(existing); + list.add(value); + return list; + } + } + + private static JSONObject mergeMap(JSONObject value, JSONObject existing) { + for (Map.Entry entry: value.entrySet()) { + String key = entry.getKey(); + Object valueValue = entry.getValue(); + Object existingValue = existing.get(key); + if (null != existingValue) { + existing.put(key, merge(valueValue, existingValue, HINT_MERGE_MAP)); + } else { + existing.put(key, valueValue); + } + } + return existing; + } + + private static String nameOf(Node node) { + String name = node.getLocalName(); + if (null == name) { + name = node.getNodeName(); + } + return name; + } + + private static Object convert(String s) { + if (null == s) { + return null; + } + s = s.trim(); + if ("".equals(s)) { + return null; + } + if ("true".equals(s)) { + return Boolean.TRUE; + } else if ("false".equals(s)) { + return Boolean.FALSE; + } else if (S.isInt(s)) { + if (9 >= s.length()) { + return Integer.parseInt(s); + } else if (19 >= s.length()) { + long l = Long.parseLong(s); + if (l <= Integer.MAX_VALUE) { + return (int)l; + } + return l; + } else { + try { + return Long.parseLong(s); + } catch (NumberFormatException e) { + return new BigInteger(s); + } + } + } else if (isNumeric(s)) { + return Double.parseDouble(s); + } else { + return s; + } + } + + private static boolean isNumeric(String s) { + int len = s.length(); + if (len == 0) { + return false; + } + int dotCount = 0; + for (int i = 0; i < len; ++i) { + char c = s.charAt(i); + if (dotCount < 1 && c == '.') { + dotCount++; + continue; + } + if (!isNumeric(c)) { + return false; + } + } + return true; + } + + private static boolean isNumeric(char c) { + return (c >= '0' && c <= '9'); + } + + private static Node rootNode(Document document) { + NodeList children = document.getChildNodes(); + for (int i = children.getLength() - 1; i >= 0; --i) { + Node node = children.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE) { + return node; + } + } + return null; + } + + public static boolean doMergeMap(int hint) { + return (hint & HINT_MERGE_MAP) != 0; + } + +} diff --git a/src/test/java/org/osgl/TestBase.java b/src/test/java/org/osgl/TestBase.java index a793323c..2e0c7cc5 100644 --- a/src/test/java/org/osgl/TestBase.java +++ b/src/test/java/org/osgl/TestBase.java @@ -21,6 +21,7 @@ */ import org.junit.runner.JUnitCore; +import org.osgl.util.IO; import org.osgl.util.S; import java.util.Random; @@ -41,4 +42,8 @@ protected static void println(String tmpl, Object... args) { protected static String newRandStr() { return S.random(new Random().nextInt(30) + 15); } + + protected String loadFileAsString(String path) { + return IO.read(getClass().getClassLoader().getResource(path)).toString(); + } } diff --git a/src/test/java/org/osgl/util/XMLTest.java b/src/test/java/org/osgl/util/XMLTest.java new file mode 100644 index 00000000..d92da6c4 --- /dev/null +++ b/src/test/java/org/osgl/util/XMLTest.java @@ -0,0 +1,138 @@ +package org.osgl.util; + +/*- + * #%L + * Java Tool + * %% + * Copyright (C) 2014 - 2017 OSGL (Open Source General Library) + * %% + * 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. + * #L% + */ + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import org.junit.Test; +import org.osgl.$; +import org.osgl.TestBase; +import org.osgl.util.converter.XmlToJson; +import org.w3c.dom.Document; + +public class XMLTest extends TestBase { + + @Test + public void testConvertValueOnly() { + String s = "x"; + Document doc = XML.read(s); + JSONObject json = $.convert(doc).to(JSONObject.class); + yes(json.isEmpty()); + } + + @Test + public void testConvertXmlToJsonSimple() { + String s = "x5"; + Document doc = XML.read(s); + JSONObject json = $.convert(doc).to(JSONObject.class); + eq("x", json.getString("name")); + eq(5, json.getInteger("id")); + } + + @Test + public void testConvertXmlToJsonWithAttributes() { + String s = "5"; + Document doc = XML.read(s); + JSONObject json = $.convert(doc).to(JSONObject.class); + JSONObject id = json.getJSONObject("id"); + eq(3, id.getInteger("len")); + eq(5, id.getInteger(XmlToJson.INNER_VALUE)); + } + + @Test + public void testConvertXmlToJsonEhCacheConfigMergeMap() { + String s = loadFileAsString("ehcache.xml"); + Document doc = XML.read(s); + JSONObject json = $.convert(doc).hint(XmlToJson.HINT_MERGE_MAP).to(JSONObject.class); + notNull(json); + JSONObject cache = json.getJSONObject("cache"); + eq(8, cache.size()); + JSONArray timeToLiveSeconds = cache.getJSONArray("timeToLiveSeconds"); + eq(45, timeToLiveSeconds.size()); + eq(20, timeToLiveSeconds.getInteger(0)); + eq("charityCache", cache.getJSONArray("name").getString(0)); + JSONObject persistence = cache.getJSONObject("persistence"); + JSONArray strategy = persistence.getJSONArray("strategy"); + eq(45, strategy.size()); + eq("none", strategy.getString(0)); + } + + @Test + public void testConvertXmlToJsonEhCacheConfigNoMerge() { + String s = loadFileAsString("ehcache.xml"); + Document doc = XML.read(s); + JSONObject json = $.convert(doc).to(JSONObject.class); + notNull(json); + JSONArray caches = json.getJSONArray("cache"); + eq(45, caches.size()); + JSONObject obj = caches.getJSONObject(0); + eq(8, obj.size()); + eq(20, obj.getInteger("timeToLiveSeconds")); + no(obj.getBoolean("eternal")); + eq("off", obj.getString("transactionalMode")); + JSONObject persistence = obj.getJSONObject("persistence"); + notNull(persistence); + eq("none", persistence.getString("strategy")); + } + + @Test + public void testCase1_1() { + test("1_1"); + } + + @Test + public void testCase1_2() { + test("1_2"); + } + + @Test + public void testCase1_3() { + test("1_3"); + } + + @Test + public void testCase2_1() { + test("2_1"); + } + + @Test + public void testCase3_1() { + test("3_1"); + } + + private void test(String caseName) { + test(caseName, 0); + test(caseName, XmlToJson.HINT_MERGE_MAP); + } + + private void test(String caseName, int hint) { + String xmlFile = "xml_json/" + caseName + ".xml"; + String jsonFile = "xml_json/" + caseName + suffix(hint) + ".json"; + Document doc = XML.read(loadFileAsString(xmlFile)); + JSONObject json = JSON.parseObject(loadFileAsString(jsonFile)); + eq(json, $.convert(doc).hint(hint).to(JSONObject.class)); + } + + private static String suffix(int hint) { + return XmlToJson.doMergeMap(hint) ? "_merge_map" : ""; + } +} diff --git a/src/test/resources/xmlWithAttributes.xml b/src/test/resources/xmlWithAttributes.xml new file mode 100644 index 00000000..7b1ea80e --- /dev/null +++ b/src/test/resources/xmlWithAttributes.xml @@ -0,0 +1,26 @@ + + + + + + 5 + + diff --git a/src/test/resources/xml_json/1_1.json b/src/test/resources/xml_json/1_1.json new file mode 100644 index 00000000..d701ed5d --- /dev/null +++ b/src/test/resources/xml_json/1_1.json @@ -0,0 +1,24 @@ +/*- + * #%L + * Java Tool + * %% + * Copyright (C) 2014 - 2021 OSGL (Open Source General Library) + * %% + * 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. + * #L% + */ +{ + "parent": { + "child": 123 + } +} diff --git a/src/test/resources/xml_json/1_1.xml b/src/test/resources/xml_json/1_1.xml new file mode 100644 index 00000000..5ad01118 --- /dev/null +++ b/src/test/resources/xml_json/1_1.xml @@ -0,0 +1,24 @@ + + + + 123 + + diff --git a/src/test/resources/xml_json/1_1_merge_map.json b/src/test/resources/xml_json/1_1_merge_map.json new file mode 100644 index 00000000..cf90bcbe --- /dev/null +++ b/src/test/resources/xml_json/1_1_merge_map.json @@ -0,0 +1,24 @@ +/*- + * #%L + * Java Tool + * %% + * Copyright (C) 2014 - 2021 OSGL (Open Source General Library) + * %% + * 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. + * #L% + */ +{ + "parent": { + "child": 123 + } +} \ No newline at end of file diff --git a/src/test/resources/xml_json/1_2.json b/src/test/resources/xml_json/1_2.json new file mode 100644 index 00000000..6e868dfa --- /dev/null +++ b/src/test/resources/xml_json/1_2.json @@ -0,0 +1,29 @@ +/*- + * #%L + * Java Tool + * %% + * Copyright (C) 2014 - 2021 OSGL (Open Source General Library) + * %% + * 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. + * #L% + */ +{ + "parent": [ + { + "child": 123 + }, + { + "child": 456 + } + ] +} diff --git a/src/test/resources/xml_json/1_2.xml b/src/test/resources/xml_json/1_2.xml new file mode 100644 index 00000000..ca7a0316 --- /dev/null +++ b/src/test/resources/xml_json/1_2.xml @@ -0,0 +1,27 @@ + + + + 123 + + + 456 + + diff --git a/src/test/resources/xml_json/1_2_merge_map.json b/src/test/resources/xml_json/1_2_merge_map.json new file mode 100644 index 00000000..e110b5df --- /dev/null +++ b/src/test/resources/xml_json/1_2_merge_map.json @@ -0,0 +1,27 @@ +/*- + * #%L + * Java Tool + * %% + * Copyright (C) 2014 - 2021 OSGL (Open Source General Library) + * %% + * 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. + * #L% + */ +{ + "parent": { + "child": [ + 123, + 456 + ] + } +} diff --git a/src/test/resources/xml_json/1_3.json b/src/test/resources/xml_json/1_3.json new file mode 100644 index 00000000..6ef55676 --- /dev/null +++ b/src/test/resources/xml_json/1_3.json @@ -0,0 +1,33 @@ +/*- + * #%L + * Java Tool + * %% + * Copyright (C) 2014 - 2021 OSGL (Open Source General Library) + * %% + * 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. + * #L% + */ +{ + "parent": [ + { + "child": 123 + }, + { + "child": 456 + } + ], + "parent2": { + "child": 789 + }, + "someone": "abc" +} diff --git a/src/test/resources/xml_json/1_3.xml b/src/test/resources/xml_json/1_3.xml new file mode 100644 index 00000000..9afae9c9 --- /dev/null +++ b/src/test/resources/xml_json/1_3.xml @@ -0,0 +1,32 @@ + + + + 123 + + + 456 + + + 789 + + abc + + diff --git a/src/test/resources/xml_json/1_3_merge_map.json b/src/test/resources/xml_json/1_3_merge_map.json new file mode 100644 index 00000000..4eabc464 --- /dev/null +++ b/src/test/resources/xml_json/1_3_merge_map.json @@ -0,0 +1,31 @@ +/*- + * #%L + * Java Tool + * %% + * Copyright (C) 2014 - 2021 OSGL (Open Source General Library) + * %% + * 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. + * #L% + */ +{ + "parent": { + "child": [ + 123, + 456 + ] + }, + "parent2": { + "child": 789 + }, + "someone": "abc" +} diff --git a/src/test/resources/xml_json/2_1.json b/src/test/resources/xml_json/2_1.json new file mode 100644 index 00000000..8d16846c --- /dev/null +++ b/src/test/resources/xml_json/2_1.json @@ -0,0 +1,26 @@ +/*- + * #%L + * Java Tool + * %% + * Copyright (C) 2014 - 2021 OSGL (Open Source General Library) + * %% + * 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. + * #L% + */ +{ + "parent": { + "child": { + "value": 123 + } + } +} diff --git a/src/test/resources/xml_json/2_1.xml b/src/test/resources/xml_json/2_1.xml new file mode 100644 index 00000000..8952647d --- /dev/null +++ b/src/test/resources/xml_json/2_1.xml @@ -0,0 +1,24 @@ + + + + + + diff --git a/src/test/resources/xml_json/2_1_merge_map.json b/src/test/resources/xml_json/2_1_merge_map.json new file mode 100644 index 00000000..8d16846c --- /dev/null +++ b/src/test/resources/xml_json/2_1_merge_map.json @@ -0,0 +1,26 @@ +/*- + * #%L + * Java Tool + * %% + * Copyright (C) 2014 - 2021 OSGL (Open Source General Library) + * %% + * 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. + * #L% + */ +{ + "parent": { + "child": { + "value": 123 + } + } +} diff --git a/src/test/resources/xml_json/3_1.json b/src/test/resources/xml_json/3_1.json new file mode 100644 index 00000000..cf94bb41 --- /dev/null +++ b/src/test/resources/xml_json/3_1.json @@ -0,0 +1,27 @@ +/*- + * #%L + * Java Tool + * %% + * Copyright (C) 2014 - 2021 OSGL (Open Source General Library) + * %% + * 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. + * #L% + */ +{ + "parent": { + "child": { + "innerValue": "abc", + "value": 123 + } + } +} diff --git a/src/test/resources/xml_json/3_1.xml b/src/test/resources/xml_json/3_1.xml new file mode 100644 index 00000000..a2cb0c37 --- /dev/null +++ b/src/test/resources/xml_json/3_1.xml @@ -0,0 +1,24 @@ + + + + abc + + diff --git a/src/test/resources/xml_json/3_1_merge_map.json b/src/test/resources/xml_json/3_1_merge_map.json new file mode 100644 index 00000000..cf94bb41 --- /dev/null +++ b/src/test/resources/xml_json/3_1_merge_map.json @@ -0,0 +1,27 @@ +/*- + * #%L + * Java Tool + * %% + * Copyright (C) 2014 - 2021 OSGL (Open Source General Library) + * %% + * 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. + * #L% + */ +{ + "parent": { + "child": { + "innerValue": "abc", + "value": 123 + } + } +}