[Practicalxml-commits] SF.net SVN: practicalxml:[126] branches/dev-1.1/src
Brought to you by:
kdgregory
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-11 17:43:40
|
Revision: 126
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=126&view=rev
Author: kdgregory
Date: 2009-09-11 17:43:24 +0000 (Fri, 11 Sep 2009)
Log Message:
-----------
implement JSON -> XML conversion
Added Paths:
-----------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/JsonUtil.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJson2XmlConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonUtil.java
Added: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java 2009-09-11 17:43:24 UTC (rev 126)
@@ -0,0 +1,262 @@
+// Copyright 2008-2009 severally by the contributors
+//
+// 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.
+
+package net.sf.practicalxml.converter.json;
+
+import org.w3c.dom.Element;
+
+import net.sf.practicalxml.DomUtil;
+import net.sf.practicalxml.converter.ConversionException;
+
+
+/**
+ * This class contains a hand-written recursive-descent parser for JSON
+ * strings. Instances are constructed around a source string, and used
+ * only once (thus thread-safety is not an issue).
+ * <p>
+ * See <a href="http://www.json.org/">json.org</a> for the JSON grammar.
+ * <p>
+ * The current implementation creates a child element for each element
+ * of an array, producing output similar to that from the Bean->XML
+ * conversion.
+ */
+public class Json2XmlConverter
+{
+ private String _src; // we pull substrings from the base string
+ private int _curPos; // position of current token (start of substring)
+ private int _nextPos; // position of next token (end of substring)
+
+
+ public Json2XmlConverter(String src)
+ {
+ _src = src;
+ }
+
+
+ /**
+ * Creates a new XML <code>Document</code> from the passed JSON string
+ * (which must contain an object definition and nothing else). The root
+ * element will be named "data".
+ */
+ public Element convert()
+ {
+ Element root = DomUtil.newDocument("data");
+ parse(root);
+ return root;
+ }
+
+
+//----------------------------------------------------------------------------
+// Internals
+//----------------------------------------------------------------------------
+
+ /**
+ * Top-level parser entry: expects the string to be a single object
+ * definition, without anything before or after the outer brace pair.
+ */
+ private void parse(Element parent)
+ {
+ expect("{");
+ parseObject(parent);
+ if (nextToken().length() > 0)
+ throw new ConversionException(commonExceptionText(
+ "unexpected content after closing brace"));
+ }
+
+
+ /**
+ * Called when the next token is expected to represent a value (of
+ * any type), to dispatch and append that value to the parent element.
+ * Returns the subsequent token.
+ */
+ private String valueDispatch(String next, Element parent)
+ {
+ if (next.equals("{"))
+ parseObject(parent);
+ else if (next.equals("["))
+ parseArray(parent);
+ else if (next.equals("\""))
+ DomUtil.setText(parent, parseString());
+ else
+ DomUtil.setText(parent, next);
+
+ return nextToken();
+ }
+
+
+ private void parseObject(Element parent)
+ {
+ String next = nextToken();
+ if (atEndOfSequence(next, "}", false))
+ return;
+
+ while (true)
+ {
+ Element child = appendChild(parent, next);
+ expect(":");
+
+ next = valueDispatch(nextToken(), child);
+ if (atEndOfSequence(next, "}", true))
+ return;
+ next = nextToken();
+ }
+ }
+
+
+ private void parseArray(Element parent)
+ {
+ String next = nextToken();
+ if (atEndOfSequence(next, "]", false))
+ return;
+
+ while (true)
+ {
+ Element child = DomUtil.appendChild(parent, "data");
+ next = valueDispatch(next, child);
+ if (atEndOfSequence(next, "]", true))
+ return;
+ next = nextToken();
+ }
+ }
+
+
+ private String parseString()
+ {
+ try
+ {
+ for (_curPos = _nextPos ; _nextPos < _src.length() ; _nextPos++)
+ {
+ char c = _src.charAt(_nextPos);
+ if (c == '"')
+ return JsonUtil.unescape(_src.substring(_curPos, _nextPos++));
+ if (c == '\\')
+ _nextPos++;
+ }
+ throw new ConversionException(commonExceptionText("unterminated string"));
+ }
+ catch (IllegalArgumentException ee)
+ {
+ throw new ConversionException(commonExceptionText("invalid string"), ee);
+ }
+ }
+
+
+ /**
+ * Reads the next token and verifies that it contains the expected value.
+ */
+ private String expect(String expected)
+ {
+ String next = nextToken();
+ if (next.equals(expected))
+ return next;
+
+ throw new ConversionException(commonExceptionText("unexpected token"));
+ }
+
+
+ /**
+ * Checks the next token (passed) to see if it represents the end of a
+ * sequence, a contination (","), or something unexpected.
+ */
+ private boolean atEndOfSequence(String next, String expectedEnd, boolean throwIfSomethingElse)
+ {
+ if (next.equals(expectedEnd))
+ return true;
+ else if (next.equals(","))
+ return false;
+ else if (next.equals(""))
+ throw new ConversionException(commonExceptionText("unexpected end of input"));
+ else if (throwIfSomethingElse)
+ throw new ConversionException(commonExceptionText("unexpected token"));
+ return false;
+ }
+
+
+ /**
+ * Extracts the next token from the string, skipping any initial whitespace.
+ * Tokens consist of a set of specific single-character strings, or any other
+ * sequence of non-whitespace characters.
+ */
+ private String nextToken()
+ {
+ final int len = _src.length();
+
+ _curPos = _nextPos;
+ while ((_curPos < len) && Character.isWhitespace(_src.charAt(_curPos)))
+ _curPos++;
+
+ if (_curPos == len)
+ return "";
+
+ _nextPos = _curPos + 1;
+ if (!isDelimiter(_src.charAt(_curPos)))
+ {
+ while ((_nextPos < len)
+ && !Character.isWhitespace(_src.charAt(_nextPos))
+ && !isDelimiter(_src.charAt(_nextPos)))
+ _nextPos++;
+ }
+
+ return _src.substring(_curPos, _nextPos);
+ }
+
+
+ private boolean isDelimiter(char c)
+ {
+ switch (c)
+ {
+ case '{' :
+ case '}' :
+ case '[' :
+ case ']' :
+ case ':' :
+ case ',' :
+ case '"' :
+ return true;
+ default :
+ return false;
+ }
+ }
+
+
+ private String commonExceptionText(String preamble)
+ {
+ String excerpt = (_curPos + 20) > _src.length()
+ ? _src.substring(_curPos)
+ : _src.substring(_curPos, _curPos + 20) + "[...]";
+ return preamble + " at position " + _curPos + ": \"" + excerpt + "\"";
+ }
+
+
+ /**
+ * A wrapper around DomUtil.appendChild() that applies some validation
+ * on the name, and replaces the DOM exception with ConversionException.
+ */
+ private Element appendChild(Element parent, String name)
+ {
+ if (name.equals(""))
+ throw new ConversionException(commonExceptionText("unexpected end of input"));
+ if (isDelimiter(name.charAt(0)))
+ throw new ConversionException(commonExceptionText("invalid token"));
+ try
+ {
+ return DomUtil.appendChild(parent, name);
+ }
+ catch (Exception e)
+ {
+ throw new ConversionException(commonExceptionText("invalid element name"), e);
+ }
+ }
+
+}
Property changes on: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java
___________________________________________________________________
Added: svn:executable
+ *
Added: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/JsonUtil.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/JsonUtil.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/JsonUtil.java 2009-09-11 17:43:24 UTC (rev 126)
@@ -0,0 +1,103 @@
+// Copyright 2008-2009 severally by the contributors
+//
+// 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.
+
+package net.sf.practicalxml.converter.json;
+
+import net.sf.practicalxml.internal.StringUtils;
+
+
+/**
+ * Static utility methods for working with JSON content. Mostly duplicates
+ * methods from Jakarta Commons.
+ */
+public class JsonUtil
+{
+ /**
+ * Unescapes a string, replacing "slash-sequences" by actual characters.
+ * Null is converted to empty string.
+ *
+ * @throws IllegalArgumentException on any failure
+ */
+ public static String unescape(String src)
+ {
+ if (src == null)
+ return "";
+
+ StringBuffer buf = new StringBuffer(src.length());
+ for (int ii = 0 ; ii < src.length() ; )
+ {
+ char c = src.charAt(ii++);
+ if (c == '\\')
+ {
+ if (ii == src.length())
+ throw new IllegalArgumentException("escape extends past end of string");
+ c = src.charAt(ii++);
+ switch (c)
+ {
+ case '"' :
+ case '\\' :
+ case '/' :
+ // do nothing, simple escape
+ break;
+ case 'b' :
+ c = '\b';
+ break;
+ case 'f' :
+ c = '\f';
+ break;
+ case 'n' :
+ c = '\n';
+ break;
+ case 'r' :
+ c = '\r';
+ break;
+ case 't' :
+ c = '\t';
+ break;
+ case 'U' :
+ case 'u' :
+ c = unescapeUnicode(src, ii);
+ ii += 4;
+ break;
+ default :
+ throw new IllegalArgumentException("invalid escape character: " + c);
+ }
+ }
+ buf.append(c);
+ }
+ return buf.toString();
+ }
+
+
+//----------------------------------------------------------------------------
+// Internals
+//----------------------------------------------------------------------------
+
+ private static char unescapeUnicode(String src, int idx)
+ {
+ if (idx + 4 > src.length())
+ throw new IllegalArgumentException("unicode escape extends past end of string");
+
+ int value = 0;
+ for (int ii = 0 ; ii < 4 ; ii++)
+ {
+ int digit = StringUtils.parseDigit(src.charAt(idx + ii), 16);
+ if (digit < 0)
+ throw new IllegalArgumentException(
+ "invalid unicode escape: " + src.substring(idx, idx + 4));
+ value = value * 16 + digit;
+ }
+ return (char)value;
+ }
+}
Added: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJson2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJson2XmlConverter.java (rev 0)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJson2XmlConverter.java 2009-09-11 17:43:24 UTC (rev 126)
@@ -0,0 +1,435 @@
+// Copyright 2008-2009 severally by the contributors
+//
+// 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.
+
+package net.sf.practicalxml.converter.json;
+
+import org.w3c.dom.Element;
+
+import net.sf.practicalxml.DomUtil;
+import net.sf.practicalxml.converter.AbstractConversionTestCase;
+import net.sf.practicalxml.converter.ConversionException;
+
+
+public class TestJson2XmlConverter
+extends AbstractConversionTestCase
+{
+ public TestJson2XmlConverter(String testName)
+ {
+ super(testName);
+ }
+
+
+//----------------------------------------------------------------------------
+// Test Cases
+// ----
+// Note that in some place we call Node.getChildNodes(), in others we call
+// DomUtil.getChildren. This is intentional: in the former case we want to
+// ensure that the converter isn't inserting extraneous text, in the latter
+// we want to ensure it isn't inserting extraneous elements (but we don't
+// care how many nodes it uses to build the text content).
+//----------------------------------------------------------------------------
+
+ public void testConvertEmpty() throws Exception
+ {
+ String src = "{}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(0, root.getChildNodes().getLength());
+ }
+
+
+ public void testConvertEmptyWithWhitespace() throws Exception
+ {
+ String src = " {\t}\n";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(0, root.getChildNodes().getLength());
+ }
+
+
+ public void testFailContentBeforeInitialBrace() throws Exception
+ {
+ String src = "test = {}";
+
+ try
+ {
+ new Json2XmlConverter(src).convert();
+ fail();
+ }
+ catch (ConversionException ee)
+ {
+ // success
+ }
+ }
+
+
+ public void testFailContentAfterTerminalBrace() throws Exception
+ {
+ String src = "{};";
+
+ try
+ {
+ new Json2XmlConverter(src).convert();
+ fail();
+ }
+ catch (ConversionException ee)
+ {
+ // success
+ }
+ }
+
+
+ public void testFailMissingTerminalBrace() throws Exception
+ {
+ String src = " { ";
+
+ try
+ {
+ new Json2XmlConverter(src).convert();
+ fail();
+ }
+ catch (ConversionException ee)
+ {
+ // success
+ }
+ }
+
+
+ public void testConvertSingleElementNumeric() throws Exception
+ {
+ String src = "{foo: 123}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertEquals("123", DomUtil.getText(child));
+ assertEquals(0, DomUtil.getChildren(child).size());
+ }
+
+
+ public void testConvertSingleElementString() throws Exception
+ {
+ String src = "{foo: \"bar\"}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertEquals("bar", DomUtil.getText(child));
+ assertEquals(0, DomUtil.getChildren(child).size());
+ }
+
+
+ public void testConvertEmptyString() throws Exception
+ {
+ String src = "{foo: \"\"}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertEquals("", DomUtil.getText(child));
+ assertEquals(0, DomUtil.getChildren(child).size());
+ }
+
+
+ public void testConvertStringWithEmbeddedEscape() throws Exception
+ {
+ String src = "{foo: \"b\\\"\\u0061r\"}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertEquals("b\"ar", DomUtil.getText(child));
+ assertEquals(0, DomUtil.getChildren(child).size());
+ }
+
+
+ public void testFailUnterminatedString() throws Exception
+ {
+ String src = "{foo: \"bar}";
+
+ try
+ {
+ new Json2XmlConverter(src).convert();
+ fail();
+ }
+ catch (ConversionException ee)
+ {
+ // success
+ }
+ }
+
+
+ public void testFailInvalidEscapeAtEndOfString() throws Exception
+ {
+ String src = "{foo: \"bar\\u123\"}";
+
+ try
+ {
+ new Json2XmlConverter(src).convert();
+ fail();
+ }
+ catch (ConversionException ee)
+ {
+ // success
+ }
+ }
+
+
+ public void testConvertTwoElementNumeric() throws Exception
+ {
+ String src = "{foo: 123, bar: 456}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(2, root.getChildNodes().getLength());
+
+ Element child1 = (Element)root.getFirstChild();
+ assertEquals("foo", child1.getNodeName());
+ assertEquals("123", DomUtil.getText(child1));
+ assertEquals(0, DomUtil.getChildren(child1).size());
+
+ Element child2 = (Element)child1.getNextSibling();
+ assertEquals("bar", child2.getNodeName());
+ assertEquals("456", DomUtil.getText(child2));
+ assertEquals(0, DomUtil.getChildren(child2).size());
+ }
+
+
+ public void testConvertTwoElementStringWithWhitespace() throws Exception
+ {
+ String src = "{foo : \"123\" , bar\t: \"456\" }";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(2, root.getChildNodes().getLength());
+
+ Element child1 = (Element)root.getFirstChild();
+ assertEquals("foo", child1.getNodeName());
+ assertEquals("123", DomUtil.getText(child1));
+ assertEquals(0, DomUtil.getChildren(child1).size());
+
+ Element child2 = (Element)child1.getNextSibling();
+ assertEquals("bar", child2.getNodeName());
+ assertEquals("456", DomUtil.getText(child2));
+ assertEquals(0, DomUtil.getChildren(child2).size());
+ }
+
+
+ public void testFailObjectMissingCommaBetweenTerms() throws Exception
+ {
+ String src = "{foo: 123 bar: 456}";
+
+ try
+ {
+ new Json2XmlConverter(src).convert();
+ fail();
+ }
+ catch (ConversionException e)
+ {
+ // success
+ }
+ }
+
+
+ public void testFailObjectMissingElement() throws Exception
+ {
+ String src = "{foo: 123, , bar: 456}";
+
+ try
+ {
+ new Json2XmlConverter(src).convert();
+ fail();
+ }
+ catch (ConversionException ee)
+ {
+ // success
+ }
+ }
+
+
+ public void testConvertNested() throws Exception
+ {
+ String src = "{foo: {bar: 123, baz:456}}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertNull(DomUtil.getText(child));
+ assertEquals(2, child.getChildNodes().getLength());
+
+ Element grandchild1 = (Element)child.getFirstChild();
+ assertEquals("bar", grandchild1.getNodeName());
+ assertEquals("123", DomUtil.getText(grandchild1));
+ assertEquals(0, DomUtil.getChildren(grandchild1).size());
+
+ Element grandchild2 = (Element)grandchild1.getNextSibling();
+ assertEquals("baz", grandchild2.getNodeName());
+ assertEquals("456", DomUtil.getText(grandchild2));
+ assertEquals(0, DomUtil.getChildren(grandchild2).size());
+ }
+
+
+ public void testConvertNestedEmpty() throws Exception
+ {
+ String src = "{foo: {}}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertNull(DomUtil.getText(child));
+ assertEquals(0, child.getChildNodes().getLength());
+ }
+
+
+ public void testConvertEmptyArray() throws Exception
+ {
+ String src = "{foo: []}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertNull(DomUtil.getText(child));
+ assertEquals(0, child.getChildNodes().getLength());
+ }
+
+
+ public void testConvertSingleElementNumericArray() throws Exception
+ {
+ String src = "{foo: [123]}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertNull(DomUtil.getText(child));
+ assertEquals(1, child.getChildNodes().getLength());
+
+ Element grandchild = (Element)child.getFirstChild();
+ assertEquals("data", grandchild.getNodeName());
+ assertEquals("123", DomUtil.getText(grandchild));
+ assertEquals(0, DomUtil.getChildren(grandchild).size());
+ }
+
+
+ public void testConvertMultiElementNumericArray() throws Exception
+ {
+ String src = "{foo: [123, 456]}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertNull(DomUtil.getText(child));
+ assertEquals(2, child.getChildNodes().getLength());
+
+ Element grandchild1 = (Element)child.getFirstChild();
+ assertEquals("data", grandchild1.getNodeName());
+ assertEquals("123", DomUtil.getText(grandchild1));
+ assertEquals(0, DomUtil.getChildren(grandchild1).size());
+
+ Element grandchild2 = (Element)grandchild1.getNextSibling();
+ assertEquals("data", grandchild2.getNodeName());
+ assertEquals("456", DomUtil.getText(grandchild2));
+ assertEquals(0, DomUtil.getChildren(grandchild2).size());
+ }
+
+
+ public void testConvertMultiElementMixedArray() throws Exception
+ {
+ String src = "{foo: [123, \"bar\", 456]}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertNull(DomUtil.getText(child));
+ assertEquals(3, child.getChildNodes().getLength());
+
+ Element grandchild1 = (Element)child.getFirstChild();
+ assertEquals("data", grandchild1.getNodeName());
+ assertEquals("123", DomUtil.getText(grandchild1));
+ assertEquals(0, DomUtil.getChildren(grandchild1).size());
+
+ Element grandchild2 = (Element)grandchild1.getNextSibling();
+ assertEquals("data", grandchild2.getNodeName());
+ assertEquals("bar", DomUtil.getText(grandchild2));
+ assertEquals(0, DomUtil.getChildren(grandchild2).size());
+
+ Element grandchild3 = (Element)grandchild2.getNextSibling();
+ assertEquals("data", grandchild3.getNodeName());
+ assertEquals("456", DomUtil.getText(grandchild3));
+ assertEquals(0, DomUtil.getChildren(grandchild3).size());
+ }
+
+
+ public void testFailConvertUnterminatedArray() throws Exception
+ {
+ String src = "{foo: [123, 456";
+
+ try
+ {
+ new Json2XmlConverter(src).convert();
+ fail();
+ }
+ catch (ConversionException ee)
+ {
+ // success
+ }
+ }
+
+
+ public void testFailConvertArrayMissingElement() throws Exception
+ {
+ String src = "{foo: [123 , , 456]}";
+
+ try
+ {
+ new Json2XmlConverter(src).convert();
+ fail();
+ }
+ catch (ConversionException ee)
+ {
+ // success
+ }
+ }
+}
Property changes on: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJson2XmlConverter.java
___________________________________________________________________
Added: svn:executable
+ *
Added: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonUtil.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonUtil.java (rev 0)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonUtil.java 2009-09-11 17:43:24 UTC (rev 126)
@@ -0,0 +1,118 @@
+// Copyright 2008-2009 severally by the contributors
+//
+// 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.
+
+package net.sf.practicalxml.converter.json;
+
+import junit.framework.TestCase;
+
+public class TestJsonUtil extends TestCase
+{
+ public void testUnescapeNullAndEmpty() throws Exception
+ {
+ assertEquals("", JsonUtil.unescape(null));
+ assertEquals("", JsonUtil.unescape(""));
+ }
+
+
+ public void testUnescapeNormalString() throws Exception
+ {
+ assertEquals("f", JsonUtil.unescape("f"));
+ assertEquals("fo", JsonUtil.unescape("fo"));
+ assertEquals("foo", JsonUtil.unescape("foo"));
+ }
+
+
+ public void testUnescapeSingleCharSlashes() throws Exception
+ {
+ assertEquals("\"", JsonUtil.unescape("\\\""));
+ assertEquals("\\", JsonUtil.unescape("\\\\"));
+ assertEquals("/", JsonUtil.unescape("\\/"));
+ assertEquals("\b", JsonUtil.unescape("\\b"));
+ assertEquals("\f", JsonUtil.unescape("\\f"));
+ assertEquals("\n", JsonUtil.unescape("\\n"));
+ assertEquals("\r", JsonUtil.unescape("\\r"));
+ assertEquals("\t", JsonUtil.unescape("\\t"));
+
+ // and a couple of tests to ensure that we don't overstep
+ assertEquals("ba\rbaz", JsonUtil.unescape("ba\\rbaz"));
+ assertEquals("\r\n", JsonUtil.unescape("\\r\\n"));
+ }
+
+
+ public void testUnescapeUnicode() throws Exception
+ {
+ assertEquals("A", JsonUtil.unescape("\\u0041"));
+ assertEquals("A", JsonUtil.unescape("\\U0041"));
+
+ // verify that we correctly index subsequent chars
+ assertEquals("BAR", JsonUtil.unescape("B\\U0041R"));
+ }
+
+
+ public void testUnescapeFailEndOfString() throws Exception
+ {
+ try
+ {
+ JsonUtil.unescape("foo\\");
+ fail("completed for escape at end of string");
+ }
+ catch (IllegalArgumentException e)
+ {
+ // success
+ }
+ }
+
+
+ public void testUnescapeFailInvalidChar() throws Exception
+ {
+ try
+ {
+ JsonUtil.unescape("foo\\q");
+ fail("completed for invalid escape sequence");
+ }
+ catch (IllegalArgumentException e)
+ {
+ // success
+ }
+ }
+
+
+ public void testUnescapeFailIncompleteUnicodeEscape() throws Exception
+ {
+ try
+ {
+ JsonUtil.unescape("foo\\u12");
+ fail("completed for invalid escape sequence");
+ }
+ catch (IllegalArgumentException e)
+ {
+ // success
+ }
+ }
+
+
+ public void testUnescapeFailInvalidUnicodeEscape() throws Exception
+ {
+ try
+ {
+ JsonUtil.unescape("\\u0foo");
+ fail("completed for invalid escape sequence");
+ }
+ catch (IllegalArgumentException e)
+ {
+ // success
+ }
+ }
+
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|