practicalxml-commits Mailing List for Practical XML (Page 7)
Brought to you by:
kdgregory
You can subscribe to this list here.
| 2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(6) |
Nov
(4) |
Dec
(35) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2009 |
Jan
(5) |
Feb
|
Mar
|
Apr
(7) |
May
|
Jun
|
Jul
(12) |
Aug
(24) |
Sep
(39) |
Oct
(16) |
Nov
(4) |
Dec
(7) |
| 2010 |
Jan
(10) |
Feb
|
Mar
(2) |
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
(4) |
Dec
(3) |
| 2011 |
Jan
(1) |
Feb
|
Mar
(1) |
Apr
(1) |
May
(3) |
Jun
|
Jul
|
Aug
(1) |
Sep
(10) |
Oct
(1) |
Nov
(1) |
Dec
(7) |
| 2012 |
Jan
(1) |
Feb
|
Mar
|
Apr
(1) |
May
(9) |
Jun
|
Jul
(5) |
Aug
(6) |
Sep
|
Oct
(1) |
Nov
|
Dec
|
| 2013 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(16) |
Jul
|
Aug
(6) |
Sep
(10) |
Oct
|
Nov
(2) |
Dec
|
| 2014 |
Jan
(5) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
(6) |
Nov
|
Dec
|
| 2015 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(5) |
| 2016 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-24 19:13:37
|
Revision: 160
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=160&view=rev
Author: kdgregory
Date: 2009-09-24 19:13:30 +0000 (Thu, 24 Sep 2009)
Log Message:
-----------
JsonConverter: add method to convert to JSON using existing buffer
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/JsonConverter.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/JsonConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/JsonConverter.java 2009-09-24 17:52:00 UTC (rev 159)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/JsonConverter.java 2009-09-24 19:13:30 UTC (rev 160)
@@ -94,7 +94,25 @@
*/
public static String convertToJson(Element root, Xml2JsonOptions... options)
{
- return new Xml2JsonConverter().convert(root, new StringBuilder(256))
- .toString();
+ return convertToJson(root, new StringBuilder(256), options).toString();
}
+
+
+ /**
+ * Creates a new JSON string from the the passed <code>Element</code>, and
+ * appends that string to the passed buffer (the buffer is actually passed
+ * into the JSON construction code).
+ *
+ * @param dom The source element -- this may or may not be the
+ * root element of its document.
+ * @param buf A buffer to which the JSON is appended.
+ * @param options Conversion options.
+ *
+ * @return The buffer, as a convenience for chained calls.
+ */
+ public static StringBuilder convertToJson(
+ Element root, StringBuilder buf, Xml2JsonOptions... options)
+ {
+ return new Xml2JsonConverter(options).convert(root,buf);
+ }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-24 17:52:15
|
Revision: 159
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=159&view=rev
Author: kdgregory
Date: 2009-09-24 17:52:00 +0000 (Thu, 24 Sep 2009)
Log Message:
-----------
xml -> json: make quoted fieldnames the default
Modified 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/Xml2JsonConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.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/TestJsonConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java
Modified: 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 2009-09-24 17:05:17 UTC (rev 158)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java 2009-09-24 17:52:00 UTC (rev 159)
@@ -142,11 +142,12 @@
String next = nextToken();
if (atEndOfSequence(next, "}", false))
return;
- if (next.equals("\""))
- next = parseString();
while (true)
{
+ if (next.equals("\""))
+ next = parseString();
+
Element child = appendChild(parent, next);
expect(":");
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java 2009-09-24 17:05:17 UTC (rev 158)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java 2009-09-24 17:52:00 UTC (rev 159)
@@ -167,12 +167,16 @@
private StringBuilder appendFieldName(StringBuilder buf, String name)
{
- if (_options.contains(Xml2JsonOptions.QUOTE_FIELD_NAMES))
+ if (_options.contains(Xml2JsonOptions.UNQUOTED_FIELD_NAMES))
+ {
+ buf.append(name);
+ }
+ else
+ {
buf.append('"')
.append(name)
.append('"');
- else
- buf.append(name);
+ }
buf.append(": ");
return buf;
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java 2009-09-24 17:05:17 UTC (rev 158)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java 2009-09-24 17:52:00 UTC (rev 159)
@@ -21,12 +21,15 @@
public enum Xml2JsonOptions
{
/**
- * If enabled, field names will be quoted. This is required by the
- * <a href="http://www.json.org/">JSON spec</a>, so should be used
- * if you expect to use the result anywhere but in a browser. It is
- * not required by <code>eval()</code>, nor for explicit scripting.
+ * If enabled, field names will not be quoted. This violates the
+ * <a href="http://www.json.org/">JSON spec</a>, which defines the
+ * production "pair" as "string : value" (and "string" is quoted).
+ * However, literal Java objects do not quote the field names, so
+ * if you use this converter to create explicit scripts, you won't
+ * want to follow the spec (and, not surprisingly, <code>eval()</code>
+ * doesn't require quoted names either).
*/
- QUOTE_FIELD_NAMES,
+ UNQUOTED_FIELD_NAMES,
/**
* If enabled, the entire string is wrapped by parentheses. This is
Modified: 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 2009-09-24 17:05:17 UTC (rev 158)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJson2XmlConverter.java 2009-09-24 17:52:00 UTC (rev 159)
@@ -255,6 +255,27 @@
}
+ // regression test!
+ public void testConvertTwoElementWithQuotedFieldNames() 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 testFailObjectMissingCommaBetweenTerms() throws Exception
{
String src = "{foo: 123 bar: 456}";
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonConverter.java 2009-09-24 17:05:17 UTC (rev 158)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonConverter.java 2009-09-24 17:52:00 UTC (rev 159)
@@ -111,6 +111,20 @@
}
+ public void testUnquotedFieldnames() throws Exception
+ {
+ Element src = element("data",
+ element("foo", text("bar")),
+ element("argle", text("bargle")))
+ .toDOM().getDocumentElement();
+ String json = JsonConverter.convertToJson(src, Xml2JsonOptions.UNQUOTED_FIELD_NAMES);
+ Element dst = JsonConverter.convertToXml(json, "test")
+ .getDocumentElement();
+
+ assertChildren(src, dst);
+ }
+
+
public void testRepeatedElements() throws Exception
{
Element src = element("data",
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java 2009-09-24 17:05:17 UTC (rev 158)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java 2009-09-24 17:52:00 UTC (rev 159)
@@ -59,7 +59,7 @@
public void testSingleChild() throws Exception
{
convertAndAssert(
- "{foo: \"bar\"}",
+ "{\"foo\": \"bar\"}",
element("data",
element("foo", text("bar"))));
}
@@ -68,7 +68,7 @@
public void testTwoChildren() throws Exception
{
convertAndAssert(
- "{foo: \"bar\", argle: \"bargle\"}",
+ "{\"foo\": \"bar\", \"argle\": \"bargle\"}",
element("data",
element("foo", text("bar")),
element("argle", text("bargle"))));
@@ -78,7 +78,7 @@
public void testChildAndGrandchildren() throws Exception
{
convertAndAssert(
- "{foo: \"bar\", argle: {biz: \"baz\", fizz: \"buzz\"}}",
+ "{\"foo\": \"bar\", \"argle\": {\"biz\": \"baz\", \"fizz\": \"buzz\"}}",
element("data",
element("foo", text("bar")),
element("argle",
@@ -91,7 +91,7 @@
{
// note that "argle" elements are not adjacent, must become adjacent
convertAndAssert(
- "{foo: \"bar\", argle: [\"bargle\", \"wargle\"], baz: \"bar\"}",
+ "{\"foo\": \"bar\", \"argle\": [\"bargle\", \"wargle\"], \"baz\": \"bar\"}",
element("data",
element("foo", text("bar")),
element("argle", text("bargle")),
@@ -103,7 +103,7 @@
public void testArrayWithNestedObject() throws Exception
{
convertAndAssert(
- "{foo: \"bar\", argle: [\"bargle\", {foo: \"bar\", bar: \"baz\"}]}",
+ "{\"foo\": \"bar\", \"argle\": [\"bargle\", {\"foo\": \"bar\", \"bar\": \"baz\"}]}",
element("data",
element("foo", text("bar")),
element("argle", text("bargle")),
@@ -117,7 +117,7 @@
public void testMixedContentWithWhitespace() throws Exception
{
convertAndAssert(
- "{foo: \"bar\"}",
+ "{\"foo\": \"bar\"}",
element("data",
text(" "),
element("foo", text("bar")),
@@ -128,26 +128,26 @@
public void testWhitespace() throws Exception
{
convertAndAssert(
- "{foo: \" \"}",
+ "{\"foo\": \" \"}",
element("data",
element("foo", text(" "))));
}
- public void testQuotedFieldnames() throws Exception
+ public void testUnquotedFieldnames() throws Exception
{
convertAndAssert(
- "{\"foo\": \"bar\"}",
+ "{foo: \"bar\"}",
element("data",
element("foo", text("bar"))),
- Xml2JsonOptions.QUOTE_FIELD_NAMES);
+ Xml2JsonOptions.UNQUOTED_FIELD_NAMES);
}
public void testWrapWithParens() throws Exception
{
convertAndAssert(
- "({foo: \"bar\"})",
+ "({\"foo\": \"bar\"})",
element("data",
element("foo", text("bar"))),
Xml2JsonOptions.WRAP_WITH_PARENS);
@@ -156,6 +156,8 @@
public void testStringEscaping() throws Exception
{
+ // I'm using unquoted field names here because there are already
+ // far too many escape sequences for the test to be readable
convertAndAssert(
"{backslash: \"\\\\\", "
+ "quote: \"\\\"\", "
@@ -165,6 +167,7 @@
element("backslash", text("\\")),
element("quote", text("\"")),
element("nonprint", text("\b\f\n\r\t")),
- element("unicode", text("b\u00e4r"))));
+ element("unicode", text("b\u00e4r"))),
+ Xml2JsonOptions.UNQUOTED_FIELD_NAMES);
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-24 17:05:30
|
Revision: 158
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=158&view=rev
Author: kdgregory
Date: 2009-09-24 17:05:17 +0000 (Thu, 24 Sep 2009)
Log Message:
-----------
xml -> json: add option to wrap output in parens
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java 2009-09-24 16:58:59 UTC (rev 157)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java 2009-09-24 17:05:17 UTC (rev 158)
@@ -63,7 +63,15 @@
*/
public StringBuilder convert(Element elem, StringBuilder buf)
{
- return append(buf, elem);
+ if (_options.contains(Xml2JsonOptions.WRAP_WITH_PARENS))
+ {
+ buf.append("(");
+ append(buf, elem);
+ buf.append(")");
+ }
+ else
+ append(buf, elem);
+ return buf;
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java 2009-09-24 16:58:59 UTC (rev 157)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java 2009-09-24 17:05:17 UTC (rev 158)
@@ -26,5 +26,13 @@
* if you expect to use the result anywhere but in a browser. It is
* not required by <code>eval()</code>, nor for explicit scripting.
*/
- QUOTE_FIELD_NAMES
+ QUOTE_FIELD_NAMES,
+
+ /**
+ * If enabled, the entire string is wrapped by parentheses. This is
+ * needed for strings that will be passed to <code>eval()</code>.
+ * Note that the resulting string is not acceptable to {@link
+ * Json2XmlConverter}.
+ */
+ WRAP_WITH_PARENS
}
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java 2009-09-24 16:58:59 UTC (rev 157)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java 2009-09-24 17:05:17 UTC (rev 158)
@@ -144,6 +144,16 @@
}
+ public void testWrapWithParens() throws Exception
+ {
+ convertAndAssert(
+ "({foo: \"bar\"})",
+ element("data",
+ element("foo", text("bar"))),
+ Xml2JsonOptions.WRAP_WITH_PARENS);
+ }
+
+
public void testStringEscaping() throws Exception
{
convertAndAssert(
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-24 16:59:08
|
Revision: 157
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=157&view=rev
Author: kdgregory
Date: 2009-09-24 16:58:59 +0000 (Thu, 24 Sep 2009)
Log Message:
-----------
xml -> json: support quoted fieldnames
Modified 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/Xml2JsonConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.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/TestXml2JsonConverter.java
Modified: 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 2009-09-24 01:21:05 UTC (rev 156)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java 2009-09-24 16:58:59 UTC (rev 157)
@@ -29,6 +29,8 @@
* only once (thus thread-safety is not an issue).
* <p>
* See <a href="http://www.json.org/">json.org</a> for the JSON grammar.
+ * This implementation will also accept strings that do not quote their
+ * field names.
* <p>
* The current implementation creates a child element for each element
* of an array, producing output similar to that from the Bean->XML
@@ -140,6 +142,8 @@
String next = nextToken();
if (atEndOfSequence(next, "}", false))
return;
+ if (next.equals("\""))
+ next = parseString();
while (true)
{
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java 2009-09-24 01:21:05 UTC (rev 156)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java 2009-09-24 16:58:59 UTC (rev 157)
@@ -31,12 +31,12 @@
*/
public class Xml2JsonConverter
{
- private EnumSet<Json2XmlOptions> _options = EnumSet.noneOf(Json2XmlOptions.class);
+ private EnumSet<Xml2JsonOptions> _options = EnumSet.noneOf(Xml2JsonOptions.class);
- public Xml2JsonConverter(Json2XmlOptions... options)
+ public Xml2JsonConverter(Xml2JsonOptions... options)
{
- for (Json2XmlOptions option : options)
+ for (Xml2JsonOptions option : options)
_options.add(option);
}
@@ -85,15 +85,6 @@
}
- private StringBuilder appendText(StringBuilder buf, String text)
- {
- buf.append('"')
- .append(JsonUtil.escape(text))
- .append('"');
- return buf;
- }
-
-
private StringBuilder appendObject(StringBuilder buf, List<Element> children)
{
List<String> names = new ArrayList<String>();
@@ -105,7 +96,7 @@
for (Iterator<String> itx = names.iterator() ; itx.hasNext() ; )
{
String name = itx.next();
- buf.append(name).append(": ");
+ appendFieldName(buf, name);
if (arrays.containsKey(name))
appendArray(buf, arrays.get(name));
else
@@ -164,4 +155,27 @@
}
}
}
+
+
+ private StringBuilder appendFieldName(StringBuilder buf, String name)
+ {
+ if (_options.contains(Xml2JsonOptions.QUOTE_FIELD_NAMES))
+ buf.append('"')
+ .append(name)
+ .append('"');
+ else
+ buf.append(name);
+
+ buf.append(": ");
+ return buf;
+ }
+
+
+ private StringBuilder appendText(StringBuilder buf, String text)
+ {
+ buf.append('"')
+ .append(JsonUtil.escape(text))
+ .append('"');
+ return buf;
+ }
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java 2009-09-24 01:21:05 UTC (rev 156)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java 2009-09-24 16:58:59 UTC (rev 157)
@@ -20,5 +20,11 @@
*/
public enum Xml2JsonOptions
{
- // nothing here right now
+ /**
+ * If enabled, field names will be quoted. This is required by the
+ * <a href="http://www.json.org/">JSON spec</a>, so should be used
+ * if you expect to use the result anywhere but in a browser. It is
+ * not required by <code>eval()</code>, nor for explicit scripting.
+ */
+ QUOTE_FIELD_NAMES
}
Modified: 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 2009-09-24 01:21:05 UTC (rev 156)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJson2XmlConverter.java 2009-09-24 16:58:59 UTC (rev 157)
@@ -168,6 +168,21 @@
}
+ public void testConvertSingleElementWithQuotedFieldname() 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 testFailUnterminatedString() throws Exception
{
String src = "{foo: \"bar}";
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java 2009-09-24 01:21:05 UTC (rev 156)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java 2009-09-24 16:58:59 UTC (rev 157)
@@ -34,10 +34,12 @@
// Support Code
//----------------------------------------------------------------------------
- public void convertAndAssert(String expected, ElementNode rootNode)
+ public void convertAndAssert(
+ String expected, ElementNode rootNode,
+ Xml2JsonOptions... options)
{
Element root = rootNode.toDOM().getDocumentElement();
- String json = new Xml2JsonConverter().convert(root);
+ String json = new Xml2JsonConverter(options).convert(root);
assertEquals(expected, json);
}
@@ -132,6 +134,16 @@
}
+ public void testQuotedFieldnames() throws Exception
+ {
+ convertAndAssert(
+ "{\"foo\": \"bar\"}",
+ element("data",
+ element("foo", text("bar"))),
+ Xml2JsonOptions.QUOTE_FIELD_NAMES);
+ }
+
+
public void testStringEscaping() throws Exception
{
convertAndAssert(
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-24 01:21:23
|
Revision: 156
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=156&view=rev
Author: kdgregory
Date: 2009-09-24 01:21:05 +0000 (Thu, 24 Sep 2009)
Log Message:
-----------
update BeanConverter package docs
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/package.html
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/package.html
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/package.html 2009-09-23 23:42:59 UTC (rev 155)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/package.html 2009-09-24 01:21:05 UTC (rev 156)
@@ -29,51 +29,83 @@
<p>
Additional conversion rules are as follows:
-<table border="1">
+<table border="1" >
<tr><th>Java Object Type
- <th>{@link #convertToXml}
- <th>{@link #convertToJava}
+ <th>Java to XML
+ <th>XML to Java
+<tr><td>Null Values
+ <td>By default, any field containing a null value is ignored and not
+ written to the output.
+ <td>By default, any element that does not contain a Text child is treated
+ as <code>null</code>, and ignored (because bean fields should already
+ be null at construction). Optionally requires an <code>xsi:nil</code>
+ attribute for values that are legally null, and throws if an empty
+ element appears without it.
<tr><td>Primitives, Wrapper objects, and String
- <td>
- <td>
+ <td>By default, calls <code>toString()</code> on the object; optionally
+ uses a Schema-compliant formatter (only applies to dates and floating
+ point numbers).
+ <td>Uses the built-in parsers for the destination type, except where
+ instructed to use Schema-compliant parsing.
<tr><td>Arrays
- <td>Elements of the array are written in sequence to the DOM, using the
- element name "<code>data</code>". Elements are given an attribute
- named "<code>index</code>", which contains the element's position
- within the array.
- <td>Elements of the array are processed in sequence, ignoring both
- element name and "index" attribute.
+ <td>By default, arrays are converted using one "container" element to
+ represent the array, and multiple children of that container to
+ represent the elements in the array. The container element is named
+ after the field being converted. By default, the child elements are
+ named "data", but optionally may be named after the field or a
+ depluralized version of the field (eg, if the field is named "widgets"
+ the child elements may be named "widgets" or "widget" depending on
+ options).
+ <p>
+ An alternate option is to output the array's elements directly, as
+ repeated elements named after the field, without a "container" element
+ (eg, if a bean has a field named "widgets" with 3 elements, then the
+ XML produced from that bean will have three Elements named "widgets",
+ each of which contains the data from the corresponding array element).
+ <p>
+ Elements may also be given an "index" attribute, holding their index
+ within the array (numbered from 0). This attribute is not output by
+ default, as its chief use is self-documenting data.
+ <td>The DOM must have a "container" element; the children of this element
+ become the elements of the array. The names of the children are ignored,
+ as is any "index" attribute. The children are converted according to the
+ base element type of the array.
<tr><td>Lists and Sets
- <td>The collection is iterated, and elements are written in sequence to
- the DOM, using the element name "<code>data</code>". Elements are
- given an attribute named "<code>index</code>", which contains the
- element's position within the iteration (meaningful only for lists).
- <td>Elements of the are processed in sequence, ignoring both element
- name and "index" attribute.
+ <td>The collection is written as if it were an array (qv). Child elements are
+ output in iterator order.
+ <td>The collection is processed as it if were an array (qv), with one (major)
+ difference: since all collections inherently contain Objects, there is no
+ type information to drive conversion. If an <code>xsi:type</code> attribute
+ is present, it will be used to drive conversion. Otherwise, the element will
+ be converted as a <code>String</code> (which will fail for complex types,
+ because string conversion assumes a single text node).
<p>
- If an <code>xsi:type</code> attribute is present, it will be used
- to drive conversion of the element. Otherwise, the element will be
- converted as a <code>String</code> (which will fail for complex
- types, because string conversion assumes a single text node).
- <p>
Where the caller specifies an interface as the conversion class, the
converter will choose an appropriate implementation class:
<ul>
<li> <code>ArrayList</code> for <code>List</code> or <code>Collection</code>
<li> <code>TreeSet</code> for <code>SortedSet</code>
- <li> <code>HashSet</code> for <code>Set</code>
+ <li> <code>HashSet</code> for all other <code>Set</code>s
</ul>
<tr><td>Maps
- <td>The collection is iterated, and elements are written in sequence to
- the DOM. Depending on the output options, either the entry key will
- be used as the element name, or the name will be "<code>data</code>"
- and the key stored in an attribute named "<code>key</code>". The
- former option is only permitted if all keys in the map are valid
- XML element names; otherwise the converter will throw.
- <td>Elements are processed in sequence. The converter first looks for
- a "<code>key</code>" attribute, and will use it as the entry key
- if found. Otherwise, it will use the element name. If your maps
- are being reduced to a single entry, look for a missing attribute.
+ <td>The map itself is represented by a "container" element, which holds one
+ child per map entry. The map's entry-set is iterated, and children are
+ emitted in the order of this iteration.
+ <p>
+ By default, child elements have the name "<code>data</code>", with an
+ attribute "<code>key</code>" that contains the key used to reference
+ the item in the map. Optionally, the map key may be used as the element
+ name, meaning that the output of a map is indistinguishable from that
+ of a bean. However, if this option is used, all map keys must be valid
+ XML element names, or the converter will throw.
+ <td>The converter expects a "container" element with one child per map
+ entry. Elements are processed in sequence, which means that later
+ elements with the same key value will overwrite earlier elements.
+ <p>
+ When processing an element, the converter first looks for an attribute
+ named "<code>key</code>", and will use it as the entry key if found.
+ Otherwise, it will use the element name. If your maps are being reduced
+ to a single entry, look for a missing attribute.
<p>
If an <code>xsi:type</code> attribute is present, it will be used
to drive conversion of the element. Otherwise, the element will be
@@ -82,11 +114,21 @@
<p>
Where the caller specifies an interface as the conversion class,
the converter will choose an appropriate implementation class:
- <code>TreeMap</code> for <code>SortedMap</code>, and <code>HashMap
- </code> for <code>Map</code>.
+ <ul>
+ <li> <code>TreeMap</code> for <code>SortedMap</code>
+ <li> <code>HashMap</code> for all other <code>Map</code>s
+ </ul>
<tr><td>Bean-structured Objects
<td>The object is introspected, and properties are written in the order
- provided by the <code>Introspector</code>.
+ provided by the <code>Introspector</code>. Note that this means you
+ can't validate beans against a schema, as the order of elements may
+ change.
+ <p>
+ <strong>Warning</strong>:
+ Bean-to-XML conversion uses <code>java.beans.Introspector</code>, which
+ holds a cache of introspected objects. If you use this conversion in an
+ app-server you should call <code>Introspector.flushCaches()</code> during
+ deploy.
<td>The bean class must provide a no-argument constructor (otherwise it
doesn't follow the bean spec, and we can't use it).
<p>
@@ -109,11 +151,5 @@
<td>not supported
</table>
-<strong>Warning</strong>:
-Bean-to-XML conversion uses <code>java.beans.Introspector</code>, which
-holds a cache of introspected objects. If you use this conversion in an
-app-server you should call <code>Introspector.flushCaches()</code> during
-deploy.
-
</body>
</html>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-23 23:43:13
|
Revision: 155
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=155&view=rev
Author: kdgregory
Date: 2009-09-23 23:42:59 +0000 (Wed, 23 Sep 2009)
Log Message:
-----------
bean->xml conversion now supports writing arrays/lists/sets as repeated siblings
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-09-23 21:46:18 UTC (rev 154)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-09-23 23:42:59 UTC (rev 155)
@@ -167,11 +167,15 @@
if (!array.getClass().isArray())
return false;
- Element parent = appender.appendContainer(name, DomUtilToo.getXsiTypeForJavaObject(array));
- Appender childAppender = new IndexedAppender(parent, _options);
String childName = determineChildNameForSequence(name);
+ Appender childAppender = appender;
+ if (!_options.contains(Bean2XmlOptions.SEQUENCE_AS_REPEATED_ELEMENTS))
+ {
+ Element parent = appender.appendContainer(name, DomUtilToo.getXsiTypeForJavaObject(array));
+ childAppender = new IndexedAppender(parent, _options);
+ }
+
int length = Array.getLength(array);
-
for (int idx = 0 ; idx < length ; idx++)
{
Object value = Array.get(array, idx);
@@ -201,10 +205,14 @@
if (!(obj instanceof Collection))
return false;
- Element parent = appender.appendContainer(name, DomUtilToo.getXsiTypeForJavaObject(obj));
- Appender childAppender = new IndexedAppender(parent, _options);
String childName = determineChildNameForSequence(name);
-
+ Appender childAppender = appender;
+ if (!_options.contains(Bean2XmlOptions.SEQUENCE_AS_REPEATED_ELEMENTS))
+ {
+ Element parent = appender.appendContainer(name, DomUtilToo.getXsiTypeForJavaObject(obj));
+ childAppender = new IndexedAppender(parent, _options);
+ }
+
for (Object value : (Collection<?>)obj)
{
convert(value, childName, childAppender);
@@ -255,18 +263,22 @@
else
convert(value, name, appender);
}
-
+
private String determineChildNameForSequence(String parentName)
{
if (StringUtils.isEmpty(parentName))
return ConversionStrings.EL_COLLECTION_ITEM;
-
+
+ if (_options.contains(Bean2XmlOptions.SEQUENCE_AS_REPEATED_ELEMENTS))
+ return parentName;
+
if (!_options.contains(Bean2XmlOptions.SEQUENCE_NAMED_BY_PARENT))
- return ConversionStrings.EL_COLLECTION_ITEM;
-
+ return ConversionStrings.EL_COLLECTION_ITEM;
+
if (parentName.endsWith("s") || parentName.endsWith("S"))
return parentName.substring(0, parentName.length() - 1);
+
return parentName;
}
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java 2009-09-23 21:46:18 UTC (rev 154)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java 2009-09-23 23:42:59 UTC (rev 155)
@@ -28,7 +28,17 @@
*/
INTROSPECT_MAPS,
+
/**
+ * Will create sequences (arrays, lists, and sets) as repeated elements
+ * rather than a parent-children construct. This option is invalid when
+ * converting an array as the top-level object, as it would cause the
+ * creation of multiple root elements. It also produces output that can
+ * not, at this time, be processed correctly by {@link Xml2BeanConverter}.
+ */
+ SEQUENCE_AS_REPEATED_ELEMENTS,
+
+ /**
* Will add an <code>index</code> attribute to the child elements of
* sequences (arrays, lists, sets); the value of this attribute is the
* element's position in the sequence (numbered from 0). This index is
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java 2009-09-23 21:46:18 UTC (rev 154)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java 2009-09-23 23:42:59 UTC (rev 155)
@@ -651,16 +651,15 @@
public void testConvertCompoundBeanDefault() throws Exception
{
- // at this point, I'm convinced the type output works, so we'll do default
- // output and then use XPath for all assertions ... but note nulls in data
- Bean2XmlConverter driver = new Bean2XmlConverter();
-
- CompoundBean bean = new CompoundBean(
+ CompoundBean data = new CompoundBean(
new SimpleBean("zippy", 123, null, true),
new int[] { 1, 2, 3 },
Arrays.asList("foo", null, "baz"));
- Element root = driver.convert(bean, "test");
+ // at this point, I'm convinced the type output works, so we'll do default
+ // output and then use XPath for all assertions ... but note nulls in data
+ Element root = new Bean2XmlConverter()
+ .convert(data, "test");
// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
DomAsserts.assertEquals("zippy", root, "/test/simple/sval");
@@ -676,6 +675,48 @@
}
+ public void testConvertSequenceAsRepeatedElements() throws Exception
+ {
+ // since we can't just pass an array into this conversion (because it
+ // would try to make multiple root elements), we'll use a compound bean
+ // and validate its components (and we'll leave a null in to verify
+ // that we ignore it)
+
+ CompoundBean data = new CompoundBean(
+ null,
+ new int[] { 1, 2, 3 },
+ Arrays.asList("foo", null, "baz"));
+
+ Element root = new Bean2XmlConverter(
+ Bean2XmlOptions.SEQUENCE_AS_REPEATED_ELEMENTS)
+ .convert(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ DomAsserts.assertEquals("1", root, "/test/primArray[1]");
+ DomAsserts.assertEquals("2", root, "/test/primArray[2]");
+ DomAsserts.assertEquals("3", root, "/test/primArray[3]");
+
+ DomAsserts.assertEquals("foo", root, "/test/stringList[1]");
+ DomAsserts.assertEquals("baz", root, "/test/stringList[2]");
+ }
+
+
+ public void testFailSequenceAsRepeatedElementsAtRoot() throws Exception
+ {
+ int[] data = new int[] { 1, 2, 3 };
+
+ try
+ {
+ new Bean2XmlConverter(Bean2XmlOptions.SEQUENCE_AS_REPEATED_ELEMENTS)
+ .convert(data, "test");
+ }
+ catch (ConversionException ee)
+ {
+ // success
+ }
+ }
+
+
public void testNamespacedConversion() throws Exception
{
Bean2XmlConverter driver = new Bean2XmlConverter();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-23 21:46:31
|
Revision: 154
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=154&view=rev
Author: kdgregory
Date: 2009-09-23 21:46:18 +0000 (Wed, 23 Sep 2009)
Log Message:
-----------
change child naming code for sequences (bugfix)
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java 2009-09-23 21:25:10 UTC (rev 153)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java 2009-09-23 21:46:18 UTC (rev 154)
@@ -157,24 +157,17 @@
extends BasicAppender
{
private int _index = 0;
- private String _elementName = ConversionStrings.EL_COLLECTION_ITEM;
public IndexedAppender(Element parent, EnumSet<Bean2XmlOptions> options)
{
super(parent, options);
- if (options.contains(Bean2XmlOptions.SEQUENCE_NAMED_BY_PARENT))
- {
- _elementName = DomUtil.getLocalName(parent);
- if (_elementName.endsWith("s") || _elementName.endsWith("S"))
- _elementName = _elementName.substring(0, _elementName.length() - 1);
- }
}
@Override
public Element appendValue(String name, String type, String value)
{
- Element child = super.appendValue(_elementName, type, value);
+ Element child = super.appendValue(name, type, value);
if ((child != null) && isOptionSet(Bean2XmlOptions.SEQUENCE_INDEXES))
child.setAttribute(ConversionStrings.AT_ARRAY_INDEX, String.valueOf(_index++));
return child;
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-09-23 21:25:10 UTC (rev 153)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-09-23 21:46:18 UTC (rev 154)
@@ -32,6 +32,7 @@
import net.sf.practicalxml.converter.internal.ConversionStrings;
import net.sf.practicalxml.converter.internal.DomUtilToo;
import net.sf.practicalxml.converter.internal.PrimitiveConversionHelper;
+import net.sf.practicalxml.internal.StringUtils;
/**
@@ -77,7 +78,7 @@
{
Element root = DomUtil.newDocument(nsUri, rootName);
doXsiNamespaceHack(root);
- convert(obj, "", new DirectAppender(root, _options));
+ convert(obj, rootName, new DirectAppender(root, _options));
return root;
}
@@ -168,11 +169,13 @@
Element parent = appender.appendContainer(name, DomUtilToo.getXsiTypeForJavaObject(array));
Appender childAppender = new IndexedAppender(parent, _options);
+ String childName = determineChildNameForSequence(name);
int length = Array.getLength(array);
+
for (int idx = 0 ; idx < length ; idx++)
{
Object value = Array.get(array, idx);
- convert(value, ConversionStrings.EL_COLLECTION_ITEM, childAppender);
+ convert(value, childName, childAppender);
}
return true;
}
@@ -200,9 +203,11 @@
Element parent = appender.appendContainer(name, DomUtilToo.getXsiTypeForJavaObject(obj));
Appender childAppender = new IndexedAppender(parent, _options);
+ String childName = determineChildNameForSequence(name);
+
for (Object value : (Collection<?>)obj)
{
- convert(value, ConversionStrings.EL_COLLECTION_ITEM, childAppender);
+ convert(value, childName, childAppender);
}
return true;
}
@@ -250,4 +255,18 @@
else
convert(value, name, appender);
}
+
+
+ private String determineChildNameForSequence(String parentName)
+ {
+ if (StringUtils.isEmpty(parentName))
+ return ConversionStrings.EL_COLLECTION_ITEM;
+
+ if (!_options.contains(Bean2XmlOptions.SEQUENCE_NAMED_BY_PARENT))
+ return ConversionStrings.EL_COLLECTION_ITEM;
+
+ if (parentName.endsWith("s") || parentName.endsWith("S"))
+ return parentName.substring(0, parentName.length() - 1);
+ return parentName;
+ }
}
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java 2009-09-23 21:25:10 UTC (rev 153)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java 2009-09-23 21:46:18 UTC (rev 154)
@@ -160,8 +160,6 @@
{
Element root = DomUtil.newDocument("root");
- // note: index shouldn't increment on null value, so put the
- // null entry between not-null entries
Appender appender = new IndexedAppender(root, useOptions());
Element child0 = appender.appendValue("foo", "bar", "baz");
Element childX = appender.appendValue("bing", "bang", null);
@@ -174,10 +172,7 @@
assertNull(childX);
assertNameTypeValue(child0, "foo", "", "baz");
- assertEquals("0", child0.getAttribute("index"));
-
assertNameTypeValue(child1, "argle", "", "wargle");
- assertEquals("1", child1.getAttribute("index"));
}
@@ -201,10 +196,34 @@
assertXsiNil(child2, true);
assertNameTypeValue(child2, "bing", "", null);
- assertEquals("2", child2.getAttribute("index"));
}
+ public void testIndexedAppenderWithIndexOption() throws Exception
+ {
+ Element root = DomUtil.newDocument("root");
+
+ // note: index shouldn't increment on null value, so put the
+ // null entry between not-null entries
+ Appender appender = new IndexedAppender(root, useOptions(Bean2XmlOptions.SEQUENCE_INDEXES));
+ Element child0 = appender.appendValue("foo", "bar", "baz");
+ Element childX = appender.appendValue("bing", "bang", null);
+ Element child1 = appender.appendValue("argle", "bargle", "wargle");
+
+ List<Element> children = DomUtil.getChildren(root);
+ assertEquals(2, children.size());
+ assertSame(child0, children.get(0));
+ assertSame(child1, children.get(1));
+ assertNull(childX);
+
+ assertNameTypeValue(child0, "foo", "", "baz");
+ assertEquals("0", child0.getAttribute("index"));
+
+ assertNameTypeValue(child1, "argle", "", "wargle");
+ assertEquals("1", child1.getAttribute("index"));
+ }
+
+
public void testMapAppenderDefault() throws Exception
{
Element root = DomUtil.newDocument("root");
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-23 21:25:41
|
Revision: 153
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=153&view=rev
Author: kdgregory
Date: 2009-09-23 21:25:10 +0000 (Wed, 23 Sep 2009)
Log Message:
-----------
Bean2XmlOptions: renames
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java 2009-09-23 18:58:50 UTC (rev 152)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java 2009-09-23 21:25:10 UTC (rev 153)
@@ -93,7 +93,7 @@
protected void setType(Element elem, String type)
{
- if (isOptionSet(Bean2XmlOptions.ADD_XSI_TYPE))
+ if (isOptionSet(Bean2XmlOptions.XSI_TYPE))
DomUtilToo.setXsiType(elem, type);
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-09-23 18:58:50 UTC (rev 152)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-09-23 21:25:10 UTC (rev 153)
@@ -114,7 +114,7 @@
private boolean shouldUseXsdFormatting()
{
return _options.contains(Bean2XmlOptions.XSD_FORMAT)
- || _options.contains(Bean2XmlOptions.ADD_XSI_TYPE);
+ || _options.contains(Bean2XmlOptions.XSI_TYPE);
}
@@ -137,7 +137,7 @@
private void doXsiNamespaceHack(Element root)
{
if (_options.contains(Bean2XmlOptions.XSI_NIL)
- && !_options.contains(Bean2XmlOptions.ADD_XSI_TYPE))
+ && !_options.contains(Bean2XmlOptions.XSI_TYPE))
{
DomUtilToo.setXsiNil(root, false);
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java 2009-09-23 18:58:50 UTC (rev 152)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java 2009-09-23 21:25:10 UTC (rev 153)
@@ -22,17 +22,6 @@
public enum Bean2XmlOptions
{
/**
- * Will add an <code>xsi:type</code> attribute to each element. For values
- * covered by the XML Schema simple types, this attribute's value will be
- * "<code>xsd:TYPE</code>", where TYPE is the XSD type name. For complex
- * types, this attribute's value will be "<code>java:TYPE</code>", where
- * TYPE is the fully-qualified classname.
- * <p>
- * <em>This option implies {@link #XSD_FORMAT} for simple types</em>.
- */
- ADD_XSI_TYPE,
-
- /**
* Output maps in an "introspected" format, where the name of each item
* is the map key (rather than "data"), and the "key" attribute is omitted.
* If any key is not a valid XML identifier, the converter will throw.
@@ -57,6 +46,14 @@
SEQUENCE_NAMED_BY_PARENT,
/**
+ * Outputs values using formats defined by XML Schema, rather than Java's
+ * <code>String.valueOf()</code> method. Note that these formats are not
+ * flagged in the element, so sender and receiver will have to agree on
+ * the format.
+ */
+ XSD_FORMAT,
+
+ /**
* Add null values into the tree, as an element without content, with the
* attribute <code>xsi:nil</code> set to "true". If not present, null
* values are ignored, and not added to DOM tree.
@@ -64,10 +61,13 @@
XSI_NIL,
/**
- * Outputs values using formats defined by XML Schema, rather than Java's
- * <code>String.valueOf()</code> method. Note that these formats are not
- * flagged in the element, so sender and receiver will have to agree on
- * the format.
+ * Will add an <code>xsi:type</code> attribute to each element. For values
+ * covered by the XML Schema simple types, this attribute's value will be
+ * "<code>xsd:TYPE</code>", where TYPE is the XSD type name. For complex
+ * types, this attribute's value will be "<code>java:TYPE</code>", where
+ * TYPE is the fully-qualified classname.
+ * <p>
+ * <em>This option implies {@link #XSD_FORMAT} for simple types</em>.
*/
- XSD_FORMAT
+ XSI_TYPE
}
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java 2009-09-23 18:58:50 UTC (rev 152)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java 2009-09-23 21:25:10 UTC (rev 153)
@@ -72,7 +72,7 @@
{
Element root = DomUtil.newDocument("root");
- Appender appender = new BasicAppender(root, useOptions(Bean2XmlOptions.ADD_XSI_TYPE));
+ Appender appender = new BasicAppender(root, useOptions(Bean2XmlOptions.XSI_TYPE));
Element child = appender.appendValue("foo", "bar", "baz");
assertNull(child.getNamespaceURI());
@@ -128,7 +128,7 @@
{
Element root = DomUtil.newDocument("root");
- Appender appender = new BasicAppender(root, useOptions(Bean2XmlOptions.ADD_XSI_TYPE));
+ Appender appender = new BasicAppender(root, useOptions(Bean2XmlOptions.XSI_TYPE));
Element child0 = appender.appendContainer("foo", "bar");
Element child1 = appender.appendContainer("argle", "bargle");
@@ -297,7 +297,7 @@
{
Element root = DomUtil.newDocument("root");
- Appender appender = new DirectAppender(root, useOptions(Bean2XmlOptions.ADD_XSI_TYPE));
+ Appender appender = new DirectAppender(root, useOptions(Bean2XmlOptions.XSI_TYPE));
Element child = appender.appendValue("foo", "bar", "baz");
assertSame(root, child);
@@ -361,7 +361,7 @@
{
Element root = DomUtil.newDocument("root");
- Appender appender = new DirectAppender(root, useOptions(Bean2XmlOptions.ADD_XSI_TYPE));
+ Appender appender = new DirectAppender(root, useOptions(Bean2XmlOptions.XSI_TYPE));
Element child0 = appender.appendContainer("foo", "bar");
assertSame(root, child0);
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java 2009-09-23 18:58:50 UTC (rev 152)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java 2009-09-23 21:25:10 UTC (rev 153)
@@ -142,7 +142,7 @@
public void testConvertPrimitivesWithXsiType() throws Exception
{
- Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.ADD_XSI_TYPE);
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.XSI_TYPE);
for (int idx = 0 ; idx < PRIMITIVE_VALUES.length ; idx++)
{
PrimitiveValue value = PRIMITIVE_VALUES[idx];
@@ -198,7 +198,7 @@
public void testConvertArrayWithXsiType() throws Exception
{
- Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.ADD_XSI_TYPE);
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.XSI_TYPE);
Object[] data = new Object[] { Integer.valueOf(1), new BigDecimal("2"), "3" };
Element root = driver.convert(data, "test");
@@ -297,7 +297,7 @@
public void testConvertListWithXsiType() throws Exception
{
- Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.ADD_XSI_TYPE);
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.XSI_TYPE);
List<String> data = Arrays.asList("foo", "bar", "baz");
@@ -409,7 +409,7 @@
public void testConvertSetWithXsiType() throws Exception
{
- Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.ADD_XSI_TYPE);
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.XSI_TYPE);
// TreeSet will order output
Set<String> data = new TreeSet<String>();
@@ -481,7 +481,7 @@
public void testConvertMapDefaultWithXsiType() throws Exception
{
- Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.ADD_XSI_TYPE);
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.XSI_TYPE);
// TreeMap means that the data will be re-ordered
Map<String,Integer> data = new TreeMap<String,Integer>();
@@ -506,7 +506,7 @@
public void testConvertMapIntrospectWithXsiType() throws Exception
{
- Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.INTROSPECT_MAPS, Bean2XmlOptions.ADD_XSI_TYPE);
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.INTROSPECT_MAPS, Bean2XmlOptions.XSI_TYPE);
// TreeMap means that the data will be re-ordered
Map<String,Integer> data = new TreeMap<String,Integer>();
@@ -560,7 +560,7 @@
public void testConvertSimpleBeanWithXsiType() throws Exception
{
- Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.ADD_XSI_TYPE);
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.XSI_TYPE);
SimpleBean bean = new SimpleBean("zippy", 123, new BigDecimal("456.78"), true);
Element root = driver.convert(bean, "test");
@@ -608,7 +608,7 @@
public void testConvertSimpleBeanXsiNilAndXsiType() throws Exception
{
- Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.XSI_NIL, Bean2XmlOptions.ADD_XSI_TYPE);
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.XSI_NIL, Bean2XmlOptions.XSI_TYPE);
SimpleBean bean = new SimpleBean(null, 123, null, true);
Element root = driver.convert(bean, "test");
@@ -624,7 +624,7 @@
public void testConvertBeanArrayWithXsiType() throws Exception
{
- Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.ADD_XSI_TYPE);
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.XSI_TYPE);
SimpleBean bean1 = new SimpleBean("foo", 123, new BigDecimal("456.789"), true);
SimpleBean bean2 = new SimpleBean("bar", 456, new BigDecimal("0.0"), false);
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java 2009-09-23 18:58:50 UTC (rev 152)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java 2009-09-23 21:25:10 UTC (rev 153)
@@ -202,7 +202,7 @@
List<Integer> data = Arrays.asList(1, 2, 3);
assertTrue(data.get(0) instanceof Integer);
- Document dom = BeanConverter.convertToXml(data, "test", Bean2XmlOptions.ADD_XSI_TYPE);
+ Document dom = BeanConverter.convertToXml(data, "test", Bean2XmlOptions.XSI_TYPE);
// System.out.println(OutputUtil.compactString(dom));
List<?> result = BeanConverter.convertToJava(dom, List.class);
@@ -306,7 +306,7 @@
{
SimpleBean data = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
- Document valid = BeanConverter.convertToXml(data, "test", Bean2XmlOptions.ADD_XSI_TYPE);
+ Document valid = BeanConverter.convertToXml(data, "test", Bean2XmlOptions.XSI_TYPE);
// System.out.println(OutputUtil.compactString(valid));
SimpleBean result = BeanConverter.convertToJava(valid, SimpleBean.class, Xml2BeanOptions.REQUIRE_XSI_TYPE);
@@ -327,7 +327,7 @@
SimpleBean bean2 = new SimpleBean("zyx", 987, null, false);
List<SimpleBean> data = Arrays.asList(bean1, bean2);
- Document dom = BeanConverter.convertToXml(data, "test", Bean2XmlOptions.ADD_XSI_TYPE);
+ Document dom = BeanConverter.convertToXml(data, "test", Bean2XmlOptions.XSI_TYPE);
// System.out.println(OutputUtil.compactString(dom));
List<SimpleBean> result = BeanConverter.convertToJava(dom, List.class);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-23 18:59:02
|
Revision: 152
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=152&view=rev
Author: kdgregory
Date: 2009-09-23 18:58:50 +0000 (Wed, 23 Sep 2009)
Log Message:
-----------
Sequence conversion: indexes are optional, child elements may be named after parent
Tests: minor renames
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java 2009-09-23 15:19:55 UTC (rev 151)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java 2009-09-23 18:58:50 UTC (rev 152)
@@ -156,19 +156,26 @@
public static class IndexedAppender
extends BasicAppender
{
- int _index = 0;
+ private int _index = 0;
+ private String _elementName = ConversionStrings.EL_COLLECTION_ITEM;
public IndexedAppender(Element parent, EnumSet<Bean2XmlOptions> options)
{
super(parent, options);
+ if (options.contains(Bean2XmlOptions.SEQUENCE_NAMED_BY_PARENT))
+ {
+ _elementName = DomUtil.getLocalName(parent);
+ if (_elementName.endsWith("s") || _elementName.endsWith("S"))
+ _elementName = _elementName.substring(0, _elementName.length() - 1);
+ }
}
@Override
public Element appendValue(String name, String type, String value)
{
- Element child = super.appendValue(name, type, value);
- if (child != null)
+ Element child = super.appendValue(_elementName, type, value);
+ if ((child != null) && isOptionSet(Bean2XmlOptions.SEQUENCE_INDEXES))
child.setAttribute(ConversionStrings.AT_ARRAY_INDEX, String.valueOf(_index++));
return child;
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java 2009-09-23 15:19:55 UTC (rev 151)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java 2009-09-23 18:58:50 UTC (rev 152)
@@ -40,6 +40,23 @@
INTROSPECT_MAPS,
/**
+ * Will add an <code>index</code> attribute to the child elements of
+ * sequences (arrays, lists, sets); the value of this attribute is the
+ * element's position in the sequence (numbered from 0). This index is
+ * not terribly useful, so is no longer default behavior.
+ */
+ SEQUENCE_INDEXES,
+
+ /**
+ * Sequences (arrays, lists, sets) will name their elements according to
+ * the parent element, with any trailing "s" removed. For example, if the
+ * parent is named "products", each child will be named "product", rather
+ * than the default "data". If the parent is named "foo", each child will
+ * also be named "foo" (since there's no "s" to remove).
+ */
+ SEQUENCE_NAMED_BY_PARENT,
+
+ /**
* Add null values into the tree, as an element without content, with the
* attribute <code>xsi:nil</code> set to "true". If not present, null
* values are ignored, and not added to DOM tree.
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java 2009-09-23 15:19:55 UTC (rev 151)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java 2009-09-23 18:58:50 UTC (rev 152)
@@ -15,7 +15,6 @@
package net.sf.practicalxml.converter.bean;
import java.math.BigDecimal;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -171,17 +170,37 @@
assertNameTypeValue("child 2", children.get(1), "data", "", "2");
assertNameTypeValue("child 3", children.get(2), "data", "", "3");
+ assertEquals("", children.get(0).getAttribute("index"));
+ assertEquals("", children.get(1).getAttribute("index"));
+ assertEquals("", children.get(2).getAttribute("index"));
+ }
+
+
+ public void testConvertArrayWithSequenceNumbers() throws Exception
+ {
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.SEQUENCE_INDEXES);
+
+ int[] data = new int[] { 1, 2, 3 };
+ Element root = driver.convert(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ List<Element> children = DomUtil.getChildren(root);
+ assertEquals("child count", 3, children.size());
+ assertNameTypeValue("child 1", children.get(0), "data", "", "1");
+ assertNameTypeValue("child 2", children.get(1), "data", "", "2");
+ assertNameTypeValue("child 3", children.get(2), "data", "", "3");
+
assertEquals("0", children.get(0).getAttribute("index"));
assertEquals("1", children.get(1).getAttribute("index"));
assertEquals("2", children.get(2).getAttribute("index"));
}
- public void testConvertPrimitiveArrayWithXsiType() throws Exception
+ public void testConvertArrayWithXsiType() throws Exception
{
Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.ADD_XSI_TYPE);
- int[] data = new int[] { 1, 2, 3 };
+ Object[] data = new Object[] { Integer.valueOf(1), new BigDecimal("2"), "3" };
Element root = driver.convert(data, "test");
// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
@@ -191,21 +210,97 @@
assertEquals("child count", 3, children.size());
assertNameTypeValue("child 1", children.get(0), "data", "xsd:int", "1");
+ assertNameTypeValue("child 2", children.get(1), "data", "xsd:decimal", "2");
+ assertNameTypeValue("child 3", children.get(2), "data", "xsd:string", "3");
+ }
+
+
+ public void testConvertArrayWithSimpleParentName() throws Exception
+ {
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.SEQUENCE_NAMED_BY_PARENT);
+
+ String[] data = new String[] {"foo", "bar", "baz"};
+
+ Element root = driver.convert(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ List<Element> children = DomUtil.getChildren(root);
+ assertEquals("child count", 3, children.size());
+
+ assertNameTypeValue("child 1", children.get(0), "test", "", "foo");
+ assertNameTypeValue("child 2", children.get(1), "test", "", "bar");
+ assertNameTypeValue("child 3", children.get(2), "test", "", "baz");
+ }
+
+
+ public void testConvertArrayWithDepluralizedParentName() throws Exception
+ {
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.SEQUENCE_NAMED_BY_PARENT);
+
+ String[] data = new String[] {"foo", "bar", "baz"};
+
+ Element root = driver.convert(data, "tests");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ List<Element> children = DomUtil.getChildren(root);
+ assertEquals("child count", 3, children.size());
+
+ assertNameTypeValue("child 1", children.get(0), "test", "", "foo");
+ assertNameTypeValue("child 2", children.get(1), "test", "", "bar");
+ assertNameTypeValue("child 3", children.get(2), "test", "", "baz");
+ }
+
+
+ public void testConvertListDefault() throws Exception
+ {
+ Bean2XmlConverter driver = new Bean2XmlConverter();
+
+ List<String> data = Arrays.asList("foo", "bar", "baz");
+
+ Element root = driver.convert(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ List<Element> children = DomUtil.getChildren(root);
+ assertEquals("child count", 3, children.size());
+
+ assertNameTypeValue("child 1", children.get(0), "data", "", "foo");
+ assertNameTypeValue("child 2", children.get(1), "data", "", "bar");
+ assertNameTypeValue("child 3", children.get(2), "data", "", "baz");
+
+ assertEquals("", children.get(0).getAttribute("index"));
+ assertEquals("", children.get(1).getAttribute("index"));
+ assertEquals("", children.get(2).getAttribute("index"));
+ }
+
+
+ public void testConvertListWithSequenceNumbers() throws Exception
+ {
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.SEQUENCE_INDEXES);
+
+ List<String> data = Arrays.asList("foo", "bar", "baz");
+
+ Element root = driver.convert(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ List<Element> children = DomUtil.getChildren(root);
+ assertEquals("child count", 3, children.size());
+
+ assertNameTypeValue("child 1", children.get(0), "data", "", "foo");
+ assertNameTypeValue("child 2", children.get(1), "data", "", "bar");
+ assertNameTypeValue("child 3", children.get(2), "data", "", "baz");
+
assertEquals("0", children.get(0).getAttribute("index"));
-
- assertNameTypeValue("child 2", children.get(1), "data", "xsd:int", "2");
assertEquals("1", children.get(1).getAttribute("index"));
-
- assertNameTypeValue("child 3", children.get(2), "data", "xsd:int", "3");
assertEquals("2", children.get(2).getAttribute("index"));
}
- public void testConvertStringArrayWithXsiType() throws Exception
+ public void testConvertListWithXsiType() throws Exception
{
Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.ADD_XSI_TYPE);
- String[] data = new String[] { "foo", "bar", "baz" };
+ List<String> data = Arrays.asList("foo", "bar", "baz");
+
Element root = driver.convert(data, "test");
// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
@@ -215,21 +310,57 @@
assertEquals("child count", 3, children.size());
assertNameTypeValue("child 1", children.get(0), "data", "xsd:string", "foo");
- assertEquals("0", children.get(0).getAttribute("index"));
-
assertNameTypeValue("child 2", children.get(1), "data", "xsd:string", "bar");
- assertEquals("1", children.get(1).getAttribute("index"));
+ assertNameTypeValue("child 3", children.get(2), "data", "xsd:string", "baz");
- assertNameTypeValue("child 3", children.get(2), "data", "xsd:string", "baz");
- assertEquals("2", children.get(2).getAttribute("index"));
+ assertEquals("", children.get(0).getAttribute("index"));
+ assertEquals("", children.get(1).getAttribute("index"));
+ assertEquals("", children.get(2).getAttribute("index"));
}
- public void testConvertStringListWithXsiType() throws Exception
+ public void testConvertListWithSimpleParentName() throws Exception
{
- Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.ADD_XSI_TYPE);
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.SEQUENCE_NAMED_BY_PARENT);
- List<String> data = new ArrayList<String>();
+ List<String> data = Arrays.asList("foo", "bar", "baz");
+
+ Element root = driver.convert(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ List<Element> children = DomUtil.getChildren(root);
+ assertEquals("child count", 3, children.size());
+
+ assertNameTypeValue("child 1", children.get(0), "test", "", "foo");
+ assertNameTypeValue("child 2", children.get(1), "test", "", "bar");
+ assertNameTypeValue("child 3", children.get(2), "test", "", "baz");
+ }
+
+
+ public void testConvertListWithDepluralizedParentName() throws Exception
+ {
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.SEQUENCE_NAMED_BY_PARENT);
+
+ List<String> data = Arrays.asList("foo", "bar", "baz");
+
+ Element root = driver.convert(data, "tests");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ List<Element> children = DomUtil.getChildren(root);
+ assertEquals("child count", 3, children.size());
+
+ assertNameTypeValue("child 1", children.get(0), "test", "", "foo");
+ assertNameTypeValue("child 2", children.get(1), "test", "", "bar");
+ assertNameTypeValue("child 3", children.get(2), "test", "", "baz");
+ }
+
+
+ public void testConvertSetDefault() throws Exception
+ {
+ Bean2XmlConverter driver = new Bean2XmlConverter();
+
+ // TreeSet will order output
+ Set<String> data = new TreeSet<String>();
data.add("foo");
data.add("bar");
data.add("baz");
@@ -237,27 +368,50 @@
Element root = driver.convert(data, "test");
// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
- assertJavaXsiType("root", root, data);
+ List<Element> children = DomUtil.getChildren(root);
+ assertEquals("child count", 3, children.size());
+ assertNameTypeValue("child 1", children.get(0), "data", "", "bar");
+ assertNameTypeValue("child 2", children.get(1), "data", "", "baz");
+ assertNameTypeValue("child 3", children.get(2), "data", "", "foo");
+
+ assertEquals("", children.get(0).getAttribute("index"));
+ assertEquals("", children.get(1).getAttribute("index"));
+ assertEquals("", children.get(2).getAttribute("index"));
+ }
+
+
+ public void testConvertSetWithSequenceNumbers() throws Exception
+ {
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.SEQUENCE_INDEXES);
+
+ // TreeSet will order output
+ Set<String> data = new TreeSet<String>();
+ data.add("foo");
+ data.add("bar");
+ data.add("baz");
+
+ Element root = driver.convert(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
List<Element> children = DomUtil.getChildren(root);
assertEquals("child count", 3, children.size());
- assertNameTypeValue("child 1", children.get(0), "data", "xsd:string", "foo");
+ assertNameTypeValue("child 1", children.get(0), "data", "", "bar");
+ assertNameTypeValue("child 2", children.get(1), "data", "", "baz");
+ assertNameTypeValue("child 3", children.get(2), "data", "", "foo");
+
assertEquals("0", children.get(0).getAttribute("index"));
-
- assertNameTypeValue("child 2", children.get(1), "data", "xsd:string", "bar");
assertEquals("1", children.get(1).getAttribute("index"));
-
- assertNameTypeValue("child 3", children.get(2), "data", "xsd:string", "baz");
assertEquals("2", children.get(2).getAttribute("index"));
}
- public void testConvertStringSetWithXsiType() throws Exception
+ public void testConvertSetWithXsiType() throws Exception
{
Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.ADD_XSI_TYPE);
- // TreeSet means that the data will be re-ordered
+ // TreeSet will order output
Set<String> data = new TreeSet<String>();
data.add("foo");
data.add("bar");
@@ -272,16 +426,59 @@
assertEquals("child count", 3, children.size());
assertNameTypeValue("child 1", children.get(0), "data", "xsd:string", "bar");
- assertEquals("0", children.get(0).getAttribute("index"));
-
assertNameTypeValue("child 2", children.get(1), "data", "xsd:string", "baz");
- assertEquals("1", children.get(1).getAttribute("index"));
+ assertNameTypeValue("child 3", children.get(2), "data", "xsd:string", "foo");
- assertNameTypeValue("child 3", children.get(2), "data", "xsd:string", "foo");
- assertEquals("2", children.get(2).getAttribute("index"));
+ assertEquals("", children.get(0).getAttribute("index"));
+ assertEquals("", children.get(1).getAttribute("index"));
+ assertEquals("", children.get(2).getAttribute("index"));
}
+ public void testConvertSetWithSimpleParentName() throws Exception
+ {
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.SEQUENCE_NAMED_BY_PARENT);
+
+ // TreeSet will order output
+ Set<String> data = new TreeSet<String>();
+ data.add("foo");
+ data.add("bar");
+ data.add("baz");
+
+ Element root = driver.convert(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ List<Element> children = DomUtil.getChildren(root);
+ assertEquals("child count", 3, children.size());
+
+ assertNameTypeValue("child 1", children.get(0), "test", "", "bar");
+ assertNameTypeValue("child 2", children.get(1), "test", "", "baz");
+ assertNameTypeValue("child 3", children.get(2), "test", "", "foo");
+ }
+
+
+ public void testConvertSetWithDepluralizedParentName() throws Exception
+ {
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.SEQUENCE_NAMED_BY_PARENT);
+
+ // TreeSet will order output
+ Set<String> data = new TreeSet<String>();
+ data.add("foo");
+ data.add("bar");
+ data.add("baz");
+
+ Element root = driver.convert(data, "tests");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ List<Element> children = DomUtil.getChildren(root);
+ assertEquals("child count", 3, children.size());
+
+ assertNameTypeValue("child 1", children.get(0), "test", "", "bar");
+ assertNameTypeValue("child 2", children.get(1), "test", "", "baz");
+ assertNameTypeValue("child 3", children.get(2), "test", "", "foo");
+ }
+
+
public void testConvertMapDefaultWithXsiType() throws Exception
{
Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.ADD_XSI_TYPE);
@@ -332,7 +529,7 @@
}
- public void testConvertMapIntrospectWithInvalidKey() throws Exception
+ public void testFailMapIntrospectWithInvalidKey() throws Exception
{
Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.INTROSPECT_MAPS);
@@ -452,7 +649,7 @@
}
- public void testDispatchCompoundBeanDefault() throws Exception
+ public void testConvertCompoundBeanDefault() throws Exception
{
// at this point, I'm convinced the type output works, so we'll do default
// output and then use XPath for all assertions ... but note nulls in data
@@ -474,10 +671,6 @@
DomAsserts.assertEquals("2", root, "/test/primArray/data[2]");
DomAsserts.assertEquals("3", root, "/test/primArray/data[3]");
- DomAsserts.assertEquals("0", root, "/test/primArray/data[1]/@index");
- DomAsserts.assertEquals("1", root, "/test/primArray/data[2]/@index");
- DomAsserts.assertEquals("2", root, "/test/primArray/data[3]/@index");
-
DomAsserts.assertEquals("foo", root, "/test/stringList/data[1]");
DomAsserts.assertEquals("baz", root, "/test/stringList/data[2]");
}
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java 2009-09-23 15:19:55 UTC (rev 151)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java 2009-09-23 18:58:50 UTC (rev 152)
@@ -144,7 +144,7 @@
}
- public void testConvertNullFailureRequireXsiNil() throws Exception
+ public void testFailNullRequireXsiNil() throws Exception
{
Document dom = BeanConverter.convertToXml(null, "test");
// System.out.println(OutputUtil.compactString(dom));
@@ -181,7 +181,7 @@
// demonstrates that the list will be read as List<String> even though
// it was written as List<Integer>
- public void testIntegerListDefault() throws Exception
+ public void testListDefault() throws Exception
{
List<Integer> data = Arrays.asList(1, 2, 3);
assert(data.get(0) instanceof Integer);
@@ -195,11 +195,12 @@
}
- // demonstrates that you don't need to require xsi:type to use it
- public void testIntegerListWithXsiType() throws Exception
+ // demonstrates that xsi:type will be used when available, even if
+ // not required -- otherwise we'd translate back as String
+ public void testListWithXsiType() throws Exception
{
List<Integer> data = Arrays.asList(1, 2, 3);
- assert(data.get(0) instanceof Integer);
+ assertTrue(data.get(0) instanceof Integer);
Document dom = BeanConverter.convertToXml(data, "test", Bean2XmlOptions.ADD_XSI_TYPE);
// System.out.println(OutputUtil.compactString(dom));
@@ -209,8 +210,32 @@
}
+ public void testListWithSequenceNumbers() throws Exception
+ {
+ List<String> data = Arrays.asList("foo", "bar", "baz");
+
+ Document dom = BeanConverter.convertToXml(data, "test", Bean2XmlOptions.SEQUENCE_INDEXES);
+// System.out.println(OutputUtil.compactString(dom));
+
+ List<?> result = BeanConverter.convertToJava(dom, List.class);
+ assertEquals(data, result);
+ }
+
+
+ public void testListWithElementsNamedByParent() throws Exception
+ {
+ List<String> data = Arrays.asList("foo", "bar", "baz");
+
+ Document dom = BeanConverter.convertToXml(data, "test", Bean2XmlOptions.SEQUENCE_NAMED_BY_PARENT);
+// System.out.println(OutputUtil.compactString(dom));
+
+ List<?> result = BeanConverter.convertToJava(dom, List.class);
+ assertEquals(data, result);
+ }
+
+
// demonstrates that the caller drives the inbound conversion
- public void testConvertListToSortedSet() throws Exception
+ public void testListToSortedSet() throws Exception
{
List<String> data = Arrays.asList("foo", "bar", "baz", "bar");
@@ -277,7 +302,7 @@
}
- public void testSimpleBeanRequireXsiType() throws Exception
+ public void testFailSimpleBeanRequireXsiType() throws Exception
{
SimpleBean data = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-23 15:20:04
|
Revision: 151
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=151&view=rev
Author: kdgregory
Date: 2009-09-23 15:19:55 +0000 (Wed, 23 Sep 2009)
Log Message:
-----------
AbstractConversionTestCase wasn't marked abstract, was causing test suite to fail
Modified Paths:
--------------
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractConversionTestCase.java
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractConversionTestCase.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractConversionTestCase.java 2009-09-23 15:03:04 UTC (rev 150)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractConversionTestCase.java 2009-09-23 15:19:55 UTC (rev 151)
@@ -26,7 +26,7 @@
/**
* A place to put common code for the conversion tests.
*/
-public class AbstractConversionTestCase
+public abstract class AbstractConversionTestCase
extends AbstractTestCase
{
public AbstractConversionTestCase(String testName)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-23 15:03:12
|
Revision: 150
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=150&view=rev
Author: kdgregory
Date: 2009-09-23 15:03:04 +0000 (Wed, 23 Sep 2009)
Log Message:
-----------
remove println()s from testcases
Modified Paths:
--------------
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonConverter.java
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonConverter.java 2009-09-22 21:13:56 UTC (rev 149)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonConverter.java 2009-09-23 15:03:04 UTC (rev 150)
@@ -20,8 +20,6 @@
import org.w3c.dom.Element;
import net.sf.practicalxml.DomUtil;
-import net.sf.practicalxml.OutputUtil;
-import net.sf.practicalxml.XmlUtil;
import net.sf.practicalxml.converter.AbstractConversionTestCase;
import net.sf.practicalxml.converter.JsonConverter;
@@ -95,7 +93,6 @@
Element dst = JsonConverter.convertToXml(json, "test")
.getDocumentElement();
- System.out.println(json);
assertChildren(src, dst);
}
@@ -139,7 +136,6 @@
Element dst = JsonConverter.convertToXml(json, "test")
.getDocumentElement();
- System.out.println(json);
assertChildren(src, dst);
assertChildren((Element)src.getFirstChild(), (Element)dst.getFirstChild());
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-22 21:14:04
|
Revision: 149
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=149&view=rev
Author: kdgregory
Date: 2009-09-22 21:13:56 +0000 (Tue, 22 Sep 2009)
Log Message:
-----------
add JsonConverter as facade for Xml2JsonConverter / Json2XmlConverter
Added Paths:
-----------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/JsonConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonConverter.java
Added: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/JsonConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/JsonConverter.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/JsonConverter.java 2009-09-22 21:13:56 UTC (rev 149)
@@ -0,0 +1,100 @@
+// 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;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import net.sf.practicalxml.converter.json.Json2XmlConverter;
+import net.sf.practicalxml.converter.json.Json2XmlOptions;
+import net.sf.practicalxml.converter.json.Xml2JsonConverter;
+import net.sf.practicalxml.converter.json.Xml2JsonOptions;
+
+
+/**
+ * Converts between XML DOMs and JSON (Javascript Object Notation) strings.
+ * See the {@link net.sf.practicalxml.converter.json package docs} for
+ * details.
+ * <p>
+ * This class provides static facade methods for
+ * {@link net.sf.practicalxml.converter.json.Json2XmlConverter} and
+ * {@link net.sf.practicalxml.converter.json.Xml2JsonConverter}. If static
+ * methods and throwaway objects offend you then use those classes directly.
+ */
+public class JsonConverter
+{
+ /**
+ * Creates a new DOM document from the passed JSON string, in which all
+ * elements are members of the specified namespace and will inherit the
+ * root's prefix (if any).
+ *
+ * @param json The source object.
+ * @param nsUri The namespace of the root element. This will be
+ * inherited by all child elements.
+ * @param rootName The qualified name given to the root element of the
+ * generated document. If a qualified name, all child
+ * elements will inherit its prefix.
+ * @param options Conversion options.
+ */
+ public static Document convertToXml(
+ String json, String nsUri, String rootName, Json2XmlOptions... options)
+ {
+ return new Json2XmlConverter(json, options).convert().getOwnerDocument();
+ }
+
+
+ /**
+ * Creates a new DOM document from the passed bean, without namespace.
+ *
+ * @param json The source object.
+ * @param rootName The name given to the root element of the produced
+ * document.
+ * @param options Conversion options.
+ */
+ public static Document convertToXml(
+ String json, String rootName, Json2XmlOptions... options)
+ {
+ return new Json2XmlConverter(json, options).convert().getOwnerDocument();
+ }
+
+
+ /**
+ * Creates a new JSON string from the root of the passed <code>Document
+ * </code>.
+ *
+ * @param dom The source document.
+ * @param options Conversion options.
+ */
+ public static String convertToJson(Document dom, Xml2JsonOptions... options)
+ {
+ return convertToJson(dom.getDocumentElement(), options);
+ }
+
+
+ /**
+ * Creates a new JSON string from the the passed <code>Element</code>.
+ * This is useful when a DOM contains a tree of objects and you just
+ * want to convert one of them.
+ *
+ * @param dom The source element -- this may or may not be the
+ * root element of its document.
+ * @param options Conversion options.
+ */
+ public static String convertToJson(Element root, Xml2JsonOptions... options)
+ {
+ return new Xml2JsonConverter().convert(root, new StringBuilder(256))
+ .toString();
+ }
+}
Added: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonConverter.java (rev 0)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonConverter.java 2009-09-22 21:13:56 UTC (rev 149)
@@ -0,0 +1,164 @@
+// 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 java.util.Iterator;
+import java.util.List;
+
+import org.w3c.dom.Element;
+
+import net.sf.practicalxml.DomUtil;
+import net.sf.practicalxml.OutputUtil;
+import net.sf.practicalxml.XmlUtil;
+import net.sf.practicalxml.converter.AbstractConversionTestCase;
+import net.sf.practicalxml.converter.JsonConverter;
+
+import static net.sf.practicalxml.builder.XmlBuilder.*;
+
+
+/**
+ * These testcases all try "out and back" conversions, starting from XML.
+ */
+public class TestJsonConverter
+extends AbstractConversionTestCase
+{
+ public TestJsonConverter(String testName)
+ {
+ super(testName);
+ }
+
+
+//----------------------------------------------------------------------------
+// Support Code
+//----------------------------------------------------------------------------
+
+
+//----------------------------------------------------------------------------
+// Assertions
+//----------------------------------------------------------------------------
+
+ /**
+ * Asserts that the two passed elements have the same number of children,
+ * that those children have the same local name (in document order), and
+ * that they have the same text values.
+ * <p>
+ * This should probably move into <code>DomAsserts</code>
+ */
+ private void assertChildren(Element expected, Element actual)
+ {
+ List<Element> expectedChildren = DomUtil.getChildren(expected);
+ List<Element> actualChildren = DomUtil.getChildren(actual);
+
+ assertEquals("child count", expectedChildren.size(), actualChildren.size());
+
+ int idx = 0;
+ Iterator<Element> expectedItx = expectedChildren.iterator();
+ Iterator<Element> actualItx = actualChildren.iterator();
+ while (expectedItx.hasNext())
+ {
+ Element expectedElement = expectedItx.next();
+ Element actualElement = actualItx.next();
+ assertEquals("element " + idx + " local name",
+ DomUtil.getLocalName(expectedElement),
+ DomUtil.getLocalName(actualElement));
+ assertEquals("element " + idx + " content",
+ DomUtil.getText(expectedElement),
+ DomUtil.getText(actualElement));
+ assertEquals("element " + idx + " child count",
+ DomUtil.getChildren(expectedElement).size(),
+ DomUtil.getChildren(actualElement).size());
+ }
+ }
+
+
+//----------------------------------------------------------------------------
+// Test Cases
+//----------------------------------------------------------------------------
+
+ public void testEmptyDocument() throws Exception
+ {
+ Element src = element("data")
+ .toDOM().getDocumentElement();
+ String json = JsonConverter.convertToJson(src);
+ Element dst = JsonConverter.convertToXml(json, "test")
+ .getDocumentElement();
+
+ System.out.println(json);
+ assertChildren(src, dst);
+ }
+
+
+ public void testTwoChildrenOfRoot() throws Exception
+ {
+ Element src = element("data",
+ element("foo", text("bar")),
+ element("argle", text("bargle")))
+ .toDOM().getDocumentElement();
+ String json = JsonConverter.convertToJson(src);
+ Element dst = JsonConverter.convertToXml(json, "test")
+ .getDocumentElement();
+
+ assertChildren(src, dst);
+ }
+
+
+ public void testRepeatedElements() throws Exception
+ {
+ Element src = element("data",
+ element("foo", text("bar")),
+ element("foo", text("baz")))
+ .toDOM().getDocumentElement();
+ String json = JsonConverter.convertToJson(src);
+ Element dst = JsonConverter.convertToXml(json, "test", Json2XmlOptions.ARRAYS_AS_REPEATED_ELEMENTS)
+ .getDocumentElement();
+
+ assertChildren(src, dst);
+ }
+
+
+ public void testNestedElements() throws Exception
+ {
+ Element src = element("data",
+ element("foo",
+ element("argle", text("bargle"))),
+ element("bar", text("baz")))
+ .toDOM().getDocumentElement();
+ String json = JsonConverter.convertToJson(src);
+ Element dst = JsonConverter.convertToXml(json, "test")
+ .getDocumentElement();
+
+ System.out.println(json);
+ assertChildren(src, dst);
+ assertChildren((Element)src.getFirstChild(), (Element)dst.getFirstChild());
+ }
+
+
+ public void testNamespaces() throws Exception
+ {
+ Element src = element("urn:foo", "argle:bargle",
+ element("urn:bar", "foo",
+ element("argle", text("bargle"))),
+ element("bar", text("baz")))
+ .toDOM().getDocumentElement();
+ String json = JsonConverter.convertToJson(src);
+ Element dst = JsonConverter.convertToXml(json, "test")
+ .getDocumentElement();
+
+ assertNull(dst.getNamespaceURI());
+ assertNull(dst.getPrefix());
+ assertChildren(src, dst);
+ assertChildren((Element)src.getFirstChild(), (Element)dst.getFirstChild());
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-22 21:07:12
|
Revision: 148
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=148&view=rev
Author: kdgregory
Date: 2009-09-22 21:07:06 +0000 (Tue, 22 Sep 2009)
Log Message:
-----------
support namespaces for JSON->XML
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJson2XmlConverter.java
Modified: 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 2009-09-22 20:01:27 UTC (rev 147)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java 2009-09-22 21:07:06 UTC (rev 148)
@@ -61,7 +61,30 @@
*/
public Element convert()
{
- Element root = DomUtil.newDocument("data");
+ return convert("data");
+ }
+
+
+ /**
+ * 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 have the given name, but no namespace.
+ */
+ public Element convert(String localName)
+ {
+ return convert(null, localName);
+ }
+
+
+ /**
+ * 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 have the given name and namespace, and all child elements
+ * will inherit the namespace (and prefix, if it exists).
+ */
+ public Element convert(String nsUri, String qname)
+ {
+ Element root = DomUtil.newDocument(nsUri, qname);
parse(root);
return root;
}
@@ -155,7 +178,7 @@
while (true)
{
- Element child = DomUtil.appendChild(parent, childName);
+ Element child = appendChild(parent, childName);
next = valueDispatch(next, child);
if (atEndOfSequence(next, "]", true))
return;
@@ -284,7 +307,7 @@
throw new ConversionException(commonExceptionText("invalid token"));
try
{
- return DomUtil.appendChild(parent, name);
+ return DomUtil.appendChildInheritNamespace(parent, name);
}
catch (Exception e)
{
Modified: 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 2009-09-22 20:01:27 UTC (rev 147)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJson2XmlConverter.java 2009-09-22 21:07:06 UTC (rev 148)
@@ -502,4 +502,28 @@
}
}
+
+ public void testConvertWithNamespace() throws Exception
+ {
+ String src = "{foo: {bar: 123}}";
+
+ Element root = new Json2XmlConverter(src).convert("urn:argle", "argle:bargle");
+ assertEquals("urn:argle", root.getNamespaceURI());
+ assertEquals("argle", root.getPrefix());
+ assertEquals("bargle", root.getLocalName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("urn:argle", child.getNamespaceURI());
+ assertEquals("argle", child.getPrefix());
+ assertEquals("foo", child.getLocalName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element grandchild = (Element)child.getFirstChild();
+ assertEquals("urn:argle", grandchild.getNamespaceURI());
+ assertEquals("argle", grandchild.getPrefix());
+ assertEquals("bar", grandchild.getLocalName());
+ assertEquals("123", DomUtil.getText(grandchild));
+ assertEquals(0, DomUtil.getChildren(grandchild).size());
+ }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-22 20:01:35
|
Revision: 147
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=147&view=rev
Author: kdgregory
Date: 2009-09-22 20:01:27 +0000 (Tue, 22 Sep 2009)
Log Message:
-----------
remove Xml2JsonOptions.USE_XSI_TYPE
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/package.html
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java 2009-09-22 19:21:25 UTC (rev 146)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java 2009-09-22 20:01:27 UTC (rev 147)
@@ -20,10 +20,5 @@
*/
public enum Xml2JsonOptions
{
- /**
- * Examines the XML element for an <code>xsi:type</code> attribute; if
- * present, will only quote-delimit character data (<code>xsd:string</code>,
- * <code>xsd:char</code>, and the like).
- */
- USE_XSI_TYPE
+ // nothing here right now
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/package.html
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/package.html 2009-09-22 19:21:25 UTC (rev 146)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/package.html 2009-09-22 20:01:27 UTC (rev 147)
@@ -22,8 +22,7 @@
<dd> JSON supports numbers and boolean literals in addition to quote-delimited
strings. The JSON to XML conversion will handle these values transparently.
The default XML to JSON conversion writes all content as quote-delimited
- strings, but there is a conversion option to recognize a limited set of
- non-string elements based on the <code>xsi:type</code> attribute.
+ strings (although this may change).
<dt> Arrays, XML to JSON
<dd> XML does not have a defined array construct, but may repeat elements; JSON
has a defined array construct, and repeated elements will overwrite the
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-22 19:21:38
|
Revision: 146
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=146&view=rev
Author: kdgregory
Date: 2009-09-22 19:21:25 +0000 (Tue, 22 Sep 2009)
Log Message:
-----------
testcase refactoring
Modified Paths:
--------------
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractConversionTestCase.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/AbstractBeanConverterTestCase.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestXml2BeanConverter.java
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractConversionTestCase.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractConversionTestCase.java 2009-09-22 19:06:46 UTC (rev 145)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractConversionTestCase.java 2009-09-22 19:21:25 UTC (rev 146)
@@ -14,6 +14,12 @@
package net.sf.practicalxml.converter;
+import static net.sf.practicalxml.builder.XmlBuilder.attribute;
+
+import javax.xml.XMLConstants;
+
+import org.w3c.dom.Element;
+
import net.sf.practicalxml.AbstractTestCase;
@@ -32,8 +38,45 @@
// Support Code
//----------------------------------------------------------------------------
+ protected static net.sf.practicalxml.builder.Node xsiType(String typeName)
+ {
+ return attribute(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI,
+ "type",
+ typeName);
+ }
+
+ protected static net.sf.practicalxml.builder.Node xsiNil(boolean isNil)
+ {
+ return attribute(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI,
+ "nil",
+ isNil ? "true" : "false");
+ }
+
+
//----------------------------------------------------------------------------
// Assertions
//----------------------------------------------------------------------------
+
+ protected void assertXsiType(String message, Element elem, String expectedType)
+ {
+ String attr = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
+ assertEquals(message, expectedType, attr);
+ }
+
+
+ protected void assertXsiNil(Element elem, boolean expected)
+ {
+ String attr = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil");
+ boolean isNil = attr.equals("true");
+ assertEquals("xsi:nil (\"" + attr + "\")", expected, isNil);
+ }
+
+
+ protected void assertXsiNil(String message, Element elem, boolean expected)
+ {
+ String attr = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil");
+ boolean isNil = attr.equals("true");
+ assertEquals(message, expected, isNil);
+ }
}
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/AbstractBeanConverterTestCase.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/AbstractBeanConverterTestCase.java 2009-09-22 19:06:46 UTC (rev 145)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/AbstractBeanConverterTestCase.java 2009-09-22 19:21:25 UTC (rev 146)
@@ -20,8 +20,6 @@
import java.util.Date;
import java.util.List;
-import javax.xml.XMLConstants;
-
import org.w3c.dom.Element;
import junit.framework.Assert;
@@ -222,27 +220,4 @@
{
assertEquals(message, expectedValue, DomUtil.getText(elem));
}
-
-
- protected void assertXsiType(String message, Element elem, String expectedType)
- {
- String attr = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
- assertEquals(message, expectedType, attr);
- }
-
-
- protected void assertXsiNil(Element elem, boolean expected)
- {
- String attr = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil");
- boolean isNil = attr.equals("true");
- assertEquals("xsi:nil (\"" + attr + "\")", expected, isNil);
- }
-
-
- protected void assertXsiNil(String message, Element elem, boolean expected)
- {
- String attr = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil");
- boolean isNil = attr.equals("true");
- assertEquals(message, expected, isNil);
- }
}
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestXml2BeanConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestXml2BeanConverter.java 2009-09-22 19:06:46 UTC (rev 145)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestXml2BeanConverter.java 2009-09-22 19:21:25 UTC (rev 146)
@@ -24,7 +24,6 @@
import java.util.SortedMap;
import java.util.SortedSet;
-import javax.xml.XMLConstants;
import org.w3c.dom.Element;
import net.sf.practicalxml.converter.ConversionException;
@@ -55,22 +54,6 @@
}
- private static net.sf.practicalxml.builder.Node xsiType(String typeName)
- {
- return attribute(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI,
- "type",
- typeName);
- }
-
-
- private static net.sf.practicalxml.builder.Node xsiNil(boolean isNil)
- {
- return attribute(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI,
- "nil",
- isNil ? "true" : "false");
- }
-
-
private static void assertConversionFailure(
String message, Xml2BeanConverter driver, Element elem, Class<?> klass)
{
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-22 19:07:02
|
Revision: 145
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=145&view=rev
Author: kdgregory
Date: 2009-09-22 19:06:46 +0000 (Tue, 22 Sep 2009)
Log Message:
-----------
implement Json2XmlOptions.ARRAYS_AS_REPEATED_ELEMENTS
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJson2XmlConverter.java
Modified: 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 2009-09-22 17:32:02 UTC (rev 144)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java 2009-09-22 19:06:46 UTC (rev 145)
@@ -17,6 +17,7 @@
import java.util.EnumSet;
import org.w3c.dom.Element;
+import org.w3c.dom.Node;
import net.sf.practicalxml.DomUtil;
import net.sf.practicalxml.converter.ConversionException;
@@ -72,15 +73,22 @@
/**
* Top-level parser entry: expects the string to be a single object
- * definition, without anything before or after the outer brace pair.
+ * or array definition, without anything before or after the outer
+ * brace/bracket pair.
*/
private void parse(Element parent)
{
- expect("{");
- parseObject(parent);
+ String first = nextToken();
+ if (first.equals("{"))
+ parseObject(parent);
+ else if (first.equals("["))
+ parseArray(parent);
+ else
+ throw new ConversionException(commonExceptionText(
+ "unexpected content start of line"));
if (nextToken().length() > 0)
throw new ConversionException(commonExceptionText(
- "unexpected content after closing brace"));
+ "unexpected content at end of line"));
}
@@ -125,13 +133,29 @@
private void parseArray(Element parent)
{
+ String childName = "data";
+ if (_options.contains(Json2XmlOptions.ARRAYS_AS_REPEATED_ELEMENTS))
+ {
+ // we come in here with the assumption that array elements will
+ // be created as children of "parent" ... but now we learn that
+ // they're actually siblings, and the passed parent will disappear
+ // ... so here's an ugly little hack to make that happen
+ Node realParent = parent.getParentNode();
+ if (!(realParent instanceof Element))
+ throw new ConversionException(commonExceptionText(
+ "cannot convert top-level array as repeated elements"));
+ childName = DomUtil.getLocalName(parent);
+ realParent.removeChild(parent);
+ parent = (Element)realParent;
+ }
+
String next = nextToken();
if (atEndOfSequence(next, "]", false))
return;
while (true)
{
- Element child = DomUtil.appendChild(parent, "data");
+ Element child = DomUtil.appendChild(parent, childName);
next = valueDispatch(next, child);
if (atEndOfSequence(next, "]", true))
return;
Modified: 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 2009-09-22 17:32:02 UTC (rev 144)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJson2XmlConverter.java 2009-09-22 19:06:46 UTC (rev 145)
@@ -402,6 +402,58 @@
}
+ public void testConvertTopLevelArray() throws Exception
+ {
+ String src = "[123, 456]";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(2, root.getChildNodes().getLength());
+
+ Element child1 = (Element)root.getFirstChild();
+ assertEquals("data", child1.getNodeName());
+ assertEquals("123", DomUtil.getText(child1));
+ assertEquals(0, DomUtil.getChildren(child1).size());
+
+ Element child2 = (Element)child1.getNextSibling();
+ assertEquals("data", child2.getNodeName());
+ assertEquals("456", DomUtil.getText(child2));
+ assertEquals(0, DomUtil.getChildren(child2).size());
+ }
+
+
+ public void testConvertArrayAsRepeatedElements() throws Exception
+ {
+ // leading and trailing elements to ensure sibling order
+ String src = "{foo: \"abc\", bar: [123, 456], baz: \"def\"}";
+
+ Element root = new Json2XmlConverter(src, Json2XmlOptions.ARRAYS_AS_REPEATED_ELEMENTS)
+ .convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(4, root.getChildNodes().getLength());
+
+ Element child1 = (Element)root.getFirstChild();
+ assertEquals("foo", child1.getNodeName());
+ assertEquals("abc", DomUtil.getText(child1));
+ assertEquals(0, DomUtil.getChildren(child1).size());
+
+ Element child2 = (Element)child1.getNextSibling();
+ assertEquals("bar", child2.getNodeName());
+ assertEquals("123", DomUtil.getText(child2));
+ assertEquals(0, DomUtil.getChildren(child2).size());
+
+ Element child3 = (Element)child2.getNextSibling();
+ assertEquals("bar", child3.getNodeName());
+ assertEquals("456", DomUtil.getText(child3));
+ assertEquals(0, DomUtil.getChildren(child3).size());
+
+ Element child4 = (Element)child3.getNextSibling();
+ assertEquals("baz", child4.getNodeName());
+ assertEquals("def", DomUtil.getText(child4));
+ assertEquals(0, DomUtil.getChildren(child4).size());
+ }
+
+
public void testFailConvertUnterminatedArray() throws Exception
{
String src = "{foo: [123, 456";
@@ -432,4 +484,22 @@
// success
}
}
+
+
+ public void testFailConvertArrayAsRootUsingRepeatedElements() throws Exception
+ {
+ String src = "[123, 456]";
+
+ try
+ {
+ new Json2XmlConverter(src, Json2XmlOptions.ARRAYS_AS_REPEATED_ELEMENTS)
+ .convert();
+ fail("able to create XML with multiple root elements");
+ }
+ catch (ConversionException ee)
+ {
+ // success
+ }
+ }
+
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-22 18:05:30
|
Revision: 144
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=144&view=rev
Author: kdgregory
Date: 2009-09-22 17:32:02 +0000 (Tue, 22 Sep 2009)
Log Message:
-----------
xml->json: support arrays
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/package.html
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java 2009-09-22 15:27:06 UTC (rev 143)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java 2009-09-22 17:32:02 UTC (rev 144)
@@ -14,9 +14,12 @@
package net.sf.practicalxml.converter.json;
+import java.util.ArrayList;
import java.util.EnumSet;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import net.sf.practicalxml.DomUtil;
@@ -43,16 +46,24 @@
//----------------------------------------------------------------------------
/**
- * Appends the contents of the specified element to an existing buffer.
+ * Converts the subtree rooted at <code>elem</code> to a JSON string.
+ */
+ public String convert(Element elem)
+ {
+ return convert(elem, new StringBuilder(256)).toString();
+ }
+
+
+ /**
+ * Converts the subtree rooted at <code>elem</code> to a JSON string,
+ * appending to an existing buffer. This is useful when building a
+ * JSON assignment statment (eg: "var x = OBJECT").
+ * <p>
* Returns the buffer as a convenience.
*/
public StringBuilder convert(Element elem, StringBuilder buf)
{
- String text = DomUtil.getText(elem);
- if (text != null)
- return appendText(text, buf);
- else
- return appendChildren(elem, buf);
+ return append(buf, elem);
}
@@ -60,8 +71,22 @@
// Internals
//----------------------------------------------------------------------------
- private StringBuilder appendText(String text, StringBuilder buf)
+ // yes, this method is just a restatement of convert(Element,StringBuilder)
+ // I want all the internal appenders named "append".
+ private StringBuilder append(StringBuilder buf, Element elem)
{
+ List<Element> children = DomUtil.getChildren(elem);
+ String text = DomUtil.getText(elem);
+
+ if ((children.size() > 0) || (text == null))
+ return appendObject(buf, children);
+ else
+ return appendText(buf, text);
+ }
+
+
+ private StringBuilder appendText(StringBuilder buf, String text)
+ {
buf.append('"')
.append(JsonUtil.escape(text))
.append('"');
@@ -69,20 +94,74 @@
}
- private StringBuilder appendChildren(Element elem, StringBuilder buf)
+ private StringBuilder appendObject(StringBuilder buf, List<Element> children)
{
+ List<String> names = new ArrayList<String>();
+ Map<String,List<Element>> arrays = new HashMap<String,List<Element>>();
+ Map<String,Element> nonArrays = new HashMap<String,Element>();
+ categorizeChildren(children, names, arrays, nonArrays);
+
buf.append("{");
- List<Element> children = DomUtil.getChildren(elem);
- for (Iterator<Element> childItx = children.iterator() ; childItx.hasNext() ; )
+ for (Iterator<String> itx = names.iterator() ; itx.hasNext() ; )
{
- Element child = childItx.next();
- buf.append(DomUtil.getLocalName(child))
- .append(": ");
- convert(child, buf);
- if (childItx.hasNext())
+ String name = itx.next();
+ buf.append(name).append(": ");
+ if (arrays.containsKey(name))
+ appendArray(buf, arrays.get(name));
+ else
+ append(buf, nonArrays.get(name));
+ if (itx.hasNext())
buf.append(", ");
}
buf.append("}");
return buf;
}
+
+
+ private StringBuilder appendArray(StringBuilder buf, List<Element> values)
+ {
+ buf.append("[");
+ for (Iterator<Element> itx = values.iterator() ; itx.hasNext() ; )
+ {
+ Element child = itx.next();
+ append(buf, child);
+ if (itx.hasNext())
+ buf.append(", ");
+ }
+ buf.append("]");
+ return buf;
+ }
+
+
+ /**
+ * Examines the children of the passed element and categorizes them as
+ * "array" or "not array", while tracking the first appearance of the
+ * element name in document order.
+ */
+ private void categorizeChildren(
+ List<Element> children, List<String> names,
+ Map<String,List<Element>> arrays, Map<String,Element> nonArrays)
+ {
+ for (Element child : children)
+ {
+ String name = DomUtil.getLocalName(child);
+ if (arrays.containsKey(name))
+ {
+ arrays.get(name).add(child);
+ }
+ else if (nonArrays.containsKey(name))
+ {
+ Element prev = nonArrays.remove(name);
+ List<Element> list = new ArrayList<Element>(2);
+ list.add(prev);
+ list.add(child);
+ arrays.put(name, list);
+ }
+ else
+ {
+ nonArrays.put(name, child);
+ names.add(name);
+ }
+ }
+ }
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/package.html
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/package.html 2009-09-22 15:27:06 UTC (rev 143)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/package.html 2009-09-22 17:32:02 UTC (rev 144)
@@ -2,36 +2,39 @@
<body>
This package contains classes to convert JSON (JavaScript Object Notation)
-strings (as defined <a href="http://www.json.org/">json.org</a> ) to and
+strings (as defined <a href="http://www.json.org/">json.org</a> ) to and
from an XML DOM. Although both XML and JSON are textual representations of
hierarchical data, there are some peculiarities in the conversion:
<dl>
<dt> Container Element
<dd> Although elements within a JSON object are named, the object itself is
- not. XML requires a named root element, so the JSON->XML conversion
- creates a root element named "data", and the XML->JSON conversion ignores
- the passed root element.
+ not. XML requires a named root element, so the JSON to XML conversion
+ creates a root element named "data", and the XML to JSON conversion
+ ignores the passed root element.
<dt> Document Order
<dd> In XML, document order is important and may be validated; in JSON, the
order of elements within an object is not important. To support arrays
- (qv), the XML->JSON conversion intentionally breaks document order. And
+ the XML to JSON conversion intentionally breaks document order (qv). And
as JSON has no intrinsic order, you'll need to explicitly re-arrange the
- result of a JSON->XML conversion prior to any validation.
+ result of a JSON to XML conversion prior to any validation.
<dt> Non-String Data
<dd> JSON supports numbers and boolean literals in addition to quote-delimited
- strings. The JSON->XML conversion will handle these values transparently.
- The default XML->JSON conversion writes all content as quote-delimited
+ strings. The JSON to XML conversion will handle these values transparently.
+ The default XML to JSON conversion writes all content as quote-delimited
strings, but there is a conversion option to recognize a limited set of
- non-string elements based on the <code>xsi:type</code> attribute.
-<dt> Arrays
+ non-string elements based on the <code>xsi:type</code> attribute.
+<dt> Arrays, XML to JSON
<dd> XML does not have a defined array construct, but may repeat elements; JSON
has a defined array construct, and repeated elements will overwrite the
- former definition. To avoid this problem, the XML->JSON conversion will
- identify all repeated elements and create an array construct. The default
- JSON->XML conversion creates a parent-children construct (which is more
- palatable to subsequent XML->Java conversion), but a conversion option
- allows conversion to a repeated element.
+ former definition. To avoid this problem, the XML to JSON converter will
+ create a JSON array construct from all siblings with the same localname.
+<dt> Arrays, JSON to XML
+<dd> By default, arrays are converted into a single parent element, with one
+ child named "data" for each element of the array; this is similar to the
+ Java to XML conversion. Optionally, you may convert an array into a series
+ of repeated elements (siblings), all with the same name. When using this
+ option, conversion will fail if presented with a top-level JSON array.
</dl>
</body>
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java 2009-09-22 15:27:06 UTC (rev 143)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java 2009-09-22 17:32:02 UTC (rev 144)
@@ -37,9 +37,8 @@
public void convertAndAssert(String expected, ElementNode rootNode)
{
Element root = rootNode.toDOM().getDocumentElement();
- StringBuilder buf = new Xml2JsonConverter()
- .convert(root, new StringBuilder(256));
- assertEquals(expected, buf.toString());
+ String json = new Xml2JsonConverter().convert(root);
+ assertEquals(expected, json);
}
@@ -86,6 +85,53 @@
}
+ public void testArray() throws Exception
+ {
+ // note that "argle" elements are not adjacent, must become adjacent
+ convertAndAssert(
+ "{foo: \"bar\", argle: [\"bargle\", \"wargle\"], baz: \"bar\"}",
+ element("data",
+ element("foo", text("bar")),
+ element("argle", text("bargle")),
+ element("baz", text("bar")),
+ element("argle", text("wargle"))));
+ }
+
+
+ public void testArrayWithNestedObject() throws Exception
+ {
+ convertAndAssert(
+ "{foo: \"bar\", argle: [\"bargle\", {foo: \"bar\", bar: \"baz\"}]}",
+ element("data",
+ element("foo", text("bar")),
+ element("argle", text("bargle")),
+ element("argle",
+ element("foo", text("bar")),
+ element("bar", text("baz")))));
+ }
+
+
+ // this covers documents parsed with "ignorable whitespace"
+ public void testMixedContentWithWhitespace() throws Exception
+ {
+ convertAndAssert(
+ "{foo: \"bar\"}",
+ element("data",
+ text(" "),
+ element("foo", text("bar")),
+ text("\n")));
+ }
+
+
+ public void testWhitespace() throws Exception
+ {
+ convertAndAssert(
+ "{foo: \" \"}",
+ element("data",
+ element("foo", text(" "))));
+ }
+
+
public void testStringEscaping() throws Exception
{
convertAndAssert(
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-22 15:27:17
|
Revision: 143
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=143&view=rev
Author: kdgregory
Date: 2009-09-22 15:27:06 +0000 (Tue, 22 Sep 2009)
Log Message:
-----------
add conversion options to ctors
Modified 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/Xml2JsonConverter.java
Modified: 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 2009-09-22 15:05:25 UTC (rev 142)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java 2009-09-22 15:27:06 UTC (rev 143)
@@ -14,6 +14,8 @@
package net.sf.practicalxml.converter.json;
+import java.util.EnumSet;
+
import org.w3c.dom.Element;
import net.sf.practicalxml.DomUtil;
@@ -33,17 +35,24 @@
*/
public class Json2XmlConverter
{
+ private EnumSet<Json2XmlOptions> _options = EnumSet.noneOf(Json2XmlOptions.class);
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)
+ public Json2XmlConverter(String src, Json2XmlOptions... options)
{
_src = src;
+ for (Json2XmlOptions option : options)
+ _options.add(option);
}
+//----------------------------------------------------------------------------
+// Public Methods
+//----------------------------------------------------------------------------
+
/**
* Creates a new XML <code>Document</code> from the passed JSON string
* (which must contain an object definition and nothing else). The root
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java 2009-09-22 15:05:25 UTC (rev 142)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java 2009-09-22 15:27:06 UTC (rev 143)
@@ -14,6 +14,7 @@
package net.sf.practicalxml.converter.json;
+import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
@@ -27,6 +28,20 @@
*/
public class Xml2JsonConverter
{
+ private EnumSet<Json2XmlOptions> _options = EnumSet.noneOf(Json2XmlOptions.class);
+
+
+ public Xml2JsonConverter(Json2XmlOptions... options)
+ {
+ for (Json2XmlOptions option : options)
+ _options.add(option);
+ }
+
+
+//----------------------------------------------------------------------------
+// Public Methods
+//----------------------------------------------------------------------------
+
/**
* Appends the contents of the specified element to an existing buffer.
* Returns the buffer as a convenience.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-22 15:05:43
|
Revision: 142
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=142&view=rev
Author: kdgregory
Date: 2009-09-22 15:05:25 +0000 (Tue, 22 Sep 2009)
Log Message:
-----------
add conversion options, package docs
Added Paths:
-----------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlOptions.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/package.html
Added: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlOptions.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlOptions.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlOptions.java 2009-09-22 15:05:25 UTC (rev 142)
@@ -0,0 +1,31 @@
+// 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;
+
+
+/**
+ * Options to control conversion from JSON strings to XML documents.
+ */
+public enum Json2XmlOptions
+{
+ /**
+ * Convert JSON arrays to repeated XML elements with the same name.
+ * Default behavior is to create a parent-children construct, in which
+ * the parent has the given element name, while each child is named
+ * "data" (this approach can be subsequently passed to the XML->Java
+ * converter).
+ */
+ ARRAYS_AS_REPEATED_ELEMENTS
+}
Added: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java 2009-09-22 15:05:25 UTC (rev 142)
@@ -0,0 +1,29 @@
+// 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;
+
+
+/**
+ * Options to control conversion from XML documents to JSON strings
+ */
+public enum Xml2JsonOptions
+{
+ /**
+ * Examines the XML element for an <code>xsi:type</code> attribute; if
+ * present, will only quote-delimit character data (<code>xsd:string</code>,
+ * <code>xsd:char</code>, and the like).
+ */
+ USE_XSI_TYPE
+}
Added: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/package.html
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/package.html (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/package.html 2009-09-22 15:05:25 UTC (rev 142)
@@ -0,0 +1,38 @@
+<html>
+<body>
+
+This package contains classes to convert JSON (JavaScript Object Notation)
+strings (as defined <a href="http://www.json.org/">json.org</a> ) to and
+from an XML DOM. Although both XML and JSON are textual representations of
+hierarchical data, there are some peculiarities in the conversion:
+
+<dl>
+<dt> Container Element
+<dd> Although elements within a JSON object are named, the object itself is
+ not. XML requires a named root element, so the JSON->XML conversion
+ creates a root element named "data", and the XML->JSON conversion ignores
+ the passed root element.
+<dt> Document Order
+<dd> In XML, document order is important and may be validated; in JSON, the
+ order of elements within an object is not important. To support arrays
+ (qv), the XML->JSON conversion intentionally breaks document order. And
+ as JSON has no intrinsic order, you'll need to explicitly re-arrange the
+ result of a JSON->XML conversion prior to any validation.
+<dt> Non-String Data
+<dd> JSON supports numbers and boolean literals in addition to quote-delimited
+ strings. The JSON->XML conversion will handle these values transparently.
+ The default XML->JSON conversion writes all content as quote-delimited
+ strings, but there is a conversion option to recognize a limited set of
+ non-string elements based on the <code>xsi:type</code> attribute.
+<dt> Arrays
+<dd> XML does not have a defined array construct, but may repeat elements; JSON
+ has a defined array construct, and repeated elements will overwrite the
+ former definition. To avoid this problem, the XML->JSON conversion will
+ identify all repeated elements and create an array construct. The default
+ JSON->XML conversion creates a parent-children construct (which is more
+ palatable to subsequent XML->Java conversion), but a conversion option
+ allows conversion to a repeated element.
+</dl>
+
+</body>
+</html>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-22 15:04:54
|
Revision: 141
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=141&view=rev
Author: kdgregory
Date: 2009-09-22 15:04:28 +0000 (Tue, 22 Sep 2009)
Log Message:
-----------
replace StringBuffer by StringBuilder
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java 2009-09-18 18:45:53 UTC (rev 140)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java 2009-09-22 15:04:28 UTC (rev 141)
@@ -31,7 +31,7 @@
* Appends the contents of the specified element to an existing buffer.
* Returns the buffer as a convenience.
*/
- public StringBuffer convert(Element elem, StringBuffer buf)
+ public StringBuilder convert(Element elem, StringBuilder buf)
{
String text = DomUtil.getText(elem);
if (text != null)
@@ -45,7 +45,7 @@
// Internals
//----------------------------------------------------------------------------
- private StringBuffer appendText(String text, StringBuffer buf)
+ private StringBuilder appendText(String text, StringBuilder buf)
{
buf.append('"')
.append(JsonUtil.escape(text))
@@ -54,7 +54,7 @@
}
- private StringBuffer appendChildren(Element elem, StringBuffer buf)
+ private StringBuilder appendChildren(Element elem, StringBuilder buf)
{
buf.append("{");
List<Element> children = DomUtil.getChildren(elem);
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java 2009-09-18 18:45:53 UTC (rev 140)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java 2009-09-22 15:04:28 UTC (rev 141)
@@ -37,8 +37,8 @@
public void convertAndAssert(String expected, ElementNode rootNode)
{
Element root = rootNode.toDOM().getDocumentElement();
- StringBuffer buf = new Xml2JsonConverter()
- .convert(root, new StringBuffer());
+ StringBuilder buf = new Xml2JsonConverter()
+ .convert(root, new StringBuilder(256));
assertEquals(expected, buf.toString());
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-18 18:46:45
|
Revision: 140
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=140&view=rev
Author: kdgregory
Date: 2009-09-18 18:45:53 +0000 (Fri, 18 Sep 2009)
Log Message:
-----------
BeanConverter now contains only static methods, is a facade
Renamed Bean2XmlDriver and Xml2BeanDriver to XXXConverter
Moved conversion docs into package
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/BeanConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java
Added Paths:
-----------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/package.html
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestXml2BeanConverter.java
Removed Paths:
-------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlDriver.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanDriver.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlDriver.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestXml2BeanDriver.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/BeanConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/BeanConverter.java 2009-09-18 15:51:32 UTC (rev 139)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/BeanConverter.java 2009-09-18 18:45:53 UTC (rev 140)
@@ -17,175 +17,32 @@
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import net.sf.practicalxml.converter.bean.Bean2XmlDriver;
+import net.sf.practicalxml.converter.bean.Bean2XmlConverter;
import net.sf.practicalxml.converter.bean.Bean2XmlOptions;
-import net.sf.practicalxml.converter.bean.Xml2BeanDriver;
+import net.sf.practicalxml.converter.bean.Xml2BeanConverter;
import net.sf.practicalxml.converter.bean.Xml2BeanOptions;
/**
* Converts Java objects (not just beans) to or from an XML representation.
* Originally developed to support simple web services, without the overhead
- * (schema definitions and/or annotations) required by JAXB.
+ * (schema definitions and/or annotations) required by JAXB. See the {@link
+ * net.sf.practicalxml.converter.bean package docs} for specifics.
* <p>
- * A single instance is intended for conversions in one direction only. This
- * is a consequence of specifying options as varargs, but fits well with
- * "normal" application design, in which input and output are handled by
- * different parts of the code. You won't get an error if you try to convert
- * the "wrong" way, you'll simply get default behavior. Note that, depending
- * on options settings, output generated by one converter may not be valid
- * input for another.
+ * This class provides static facade methods for
+ * {@link net.sf.practicalxml.converter.bean.Bean2XmlConverter} and
+ * {@link net.sf.practicalxml.converter.bean.Xml2BeanConverter}. If static
+ * methods and throwaway objects offend you then use those classes directly.
* <p>
- * The basic structure of XML produced/consumed by this class is that the
- * root element represents the object being converted, and its child nodes
- * represent the elements/properties of the object. Nodes representing complex
- * objects have child elements, those representing simple (primitive) objects
- * have a single text child. Objects are processed recursively, and cycles are
- * <em>not</em> detected (although this may change).
- * <p>
- * A namespace and qualified name may be provided to {@link #convertToXml},
- * and all elements will inherit the namespace and prefix. Namespaces are
- * ignored on input; all property matches uses the element's local name.
- * <p>
- * Each element may have an <code>xsi:type</code> attribute (where <code>xsi
- * </code> references to the XML Schema instance namespace). This attribute
- * is optional for both output and input; if used for output, it is merely
- * informational, but for input will be examined to validate that the XML is
- * appropriate for the desired object type. For primitive types, wrappers,
- * and strings, it takes the form "<code>xsd:TYPE</code>", where <code>TYPE
- * </code> is one of the simple types defined by XML schema. For other Java
- * types, it takes the form "<code>java:TYPE</code>", where <code>TYPE</code>
- * is the fully qualified Java classname.
- * <p>
- * On input, the desired type is specified by the caller or by introspection
- * (except in the case of collection elements; see below). The <code>xsi:type
- * </code> value, if any, is ignored except for validation.
- * <p>
- * Additional conversion rules are as follows:
- *
- * <table border="1">
- * <tr><th>Java Object Type
- * <th>{@link #convertToXml}
- * <th>{@link #convertToJava}
- * <tr><td>Primitives, Wrapper objects, and String
- * <td>
- * <td>
- * <tr><td>Arrays
- * <td>Elements of the array are written in sequence to the DOM, using the
- * element name "<code>data</code>". Elements are given an attribute
- * named "<code>index</code>", which contains the element's position
- * within the array.
- * <td>Elements of the array are processed in sequence, ignoring both
- * element name and "index" attribute.
- * <tr><td>Lists and Sets
- * <td>The collection is iterated, and elements are written in sequence to
- * the DOM, using the element name "<code>data</code>". Elements are
- * given an attribute named "<code>index</code>", which contains the
- * element's position within the iteration (meaningful only for lists).
- * <td>Elements of the are processed in sequence, ignoring both element
- * name and "index" attribute.
- * <p>
- * If an <code>xsi:type</code> attribute is present, it will be used
- * to drive conversion of the element. Otherwise, the element will be
- * converted as a <code>String</code> (which will fail for complex
- * types, because string conversion assumes a single text node).
- * <p>
- * Where the caller specifies an interface as the conversion class, the
- * converter will choose an appropriate implementation class:
- * <ul>
- * <li> <code>ArrayList</code> for <code>List</code> or <code>Collection</code>
- * <li> <code>TreeSet</code> for <code>SortedSet</code>
- * <li> <code>HashSet</code> for <code>Set</code>
- * </ul>
- * <tr><td>Maps
- * <td>The collection is iterated, and elements are written in sequence to
- * the DOM. Depending on the output options, either the entry key will
- * be used as the element name, or the name will be "<code>data</code>"
- * and the key stored in an attribute named "<code>key</code>". The
- * former option is only permitted if all keys in the map are valid
- * XML element names; otherwise the converter will throw.
- * <td>Elements are processed in sequence. The converter first looks for
- * a "<code>key</code>" attribute, and will use it as the entry key
- * if found. Otherwise, it will use the element name. If your maps
- * are being reduced to a single entry, look for a missing attribute.
- * <p>
- * If an <code>xsi:type</code> attribute is present, it will be used
- * to drive conversion of the element. Otherwise, the element will be
- * converted as a <code>String</code> (which will fail for complex
- * types, because string conversion assumes a single text node).
- * <p>
- * Where the caller specifies an interface as the conversion class,
- * the converter will choose an appropriate implementation class:
- * <code>TreeMap</code> for <code>SortedMap</code>, and <code>HashMap
- * </code> for <code>Map</code>.
- * <tr><td>Bean-structured Objects
- * <td>The object is introspected, and properties are written in the order
- * provided by the <code>Introspector</code>.
- * <td>The bean class must provide a no-argument constructor (otherwise it
- * doesn't follow the bean spec, and we can't use it).
- * <p>
- * The converter relies on <code>java.beans.Introspector</code> to find
- * property setter methods for an object. If the object provides
- * multiple methods for the property, the converter will use whichever
- * one the introspector provides.
- * <p>
- * Elements are processed in order, and the element's localname is used
- * to find the associated object property. If the XML does not contain
- * an element corresponding to a bean property, that property is left
- * with its default value (ie, we don't try to find an element based
- * on property name).
- * <p>
- * If the XML contains an element that does not correspond to any bean
- * property, the converter will either throw or ignore the element,
- * depending on options settings.
- * <tr><td>Other Objects
- * <td>not supported
- * <td>not supported
- * </table>
- *
* <strong>Warning</strong>:
- * <code>java.beans.Introspector</code> holds a cache of introspected objects.
- * If you use this converter in an app-server you should call
- * <code>Introspector.flushCaches()</code> during deploy.
+ * Bean-to-XML conversion uses <code>java.beans.Introspector</code>, which
+ * holds a cache of introspected objects. If you use this conversion in an
+ * app-server you should call <code>Introspector.flushCaches()</code> during
+ * deploy.
*/
public class BeanConverter
{
- private Bean2XmlDriver _outputDriver;
- private Xml2BeanDriver _inputDriver;
-
-
/**
- * Creates an instance with all options disabled. This can be used for
- * conversions in either direction, and is meant primarily for testing.
- */
- public BeanConverter()
- {
- _outputDriver = new Bean2XmlDriver();
- _inputDriver = new Xml2BeanDriver();
- }
-
-
- /**
- * Creates an instance to be used for Bean -> XML conversion,
- */
- public BeanConverter(Bean2XmlOptions... options)
- {
- _outputDriver = new Bean2XmlDriver(options);
- _inputDriver = new Xml2BeanDriver();
- }
-
-
- /**
- * Creates an instance to be used for XML -> Bean conversion.
- */
- public BeanConverter(Xml2BeanOptions options)
- {
- _outputDriver = new Bean2XmlDriver();
- _inputDriver = new Xml2BeanDriver(options);
- }
-
-
- /**
* Creates a new DOM document from the passed bean, in which all elements
* are members of the specified namespace and will inherit the root's
* prefix (if any).
@@ -197,10 +54,13 @@
* @param rootName The qualified name given to the root element of the
* generated document. If a qualified name, all child
* elements will inherit its prefix.
+ * @param options Conversion options.
*/
- public Document convertToXml(Object bean, String nsUri, String rootName)
+ public static Document convertToXml(
+ Object bean, String nsUri, String rootName, Bean2XmlOptions... options)
{
- return _outputDriver.convert(bean, nsUri, rootName)
+ return new Bean2XmlConverter(options)
+ .convert(bean, nsUri, rootName)
.getOwnerDocument();
}
@@ -212,10 +72,13 @@
* bean, collection, or simple type.
* @param rootName The name given to the root element of the produced
* document.
+ * @param options Conversion options.
*/
- public Document convertToXml(Object bean, String rootName)
+ public static Document convertToXml(
+ Object bean, String rootName, Bean2XmlOptions... options)
{
- return _outputDriver.convert(bean, rootName)
+ return new Bean2XmlConverter(options)
+ .convert(bean, rootName)
.getOwnerDocument();
}
@@ -227,10 +90,12 @@
* @param dom The source document.
* @param klass The desired class to instantiate and fill from this
* document.
+ * @param options Conversion options.
*/
- public <T> T convertToJava(Document dom, Class<T> klass)
+ public static <T> T convertToJava(
+ Document dom, Class<T> klass, Xml2BeanOptions... options)
{
- return convertToJava(dom.getDocumentElement(), klass);
+ return convertToJava(dom.getDocumentElement(), klass, options);
}
@@ -243,9 +108,11 @@
* root element of its document.
* @param klass The desired class to instantiate and fill from this
* document.
+ * @param options Conversion options.
*/
- public <T> T convertToJava(Element root, Class<T> klass)
+ public static <T> T convertToJava(
+ Element root, Class<T> klass, Xml2BeanOptions... options)
{
- return _inputDriver.convert(root, klass);
+ return new Xml2BeanConverter(options).convert(root, klass);
}
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java 2009-09-18 15:51:32 UTC (rev 139)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java 2009-09-18 18:45:53 UTC (rev 140)
@@ -25,7 +25,7 @@
/**
* Packaging class used for XML output appenders. This class is a temporary
- * hack, as I move intelligence into {@link Bean2XmlDriver}; the contained
+ * hack, as I move intelligence into {@link Bean2XmlConverter}; the contained
* classes will end up in a new package, once I figure out what the package
* structure should be.
*/
Copied: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java (from rev 130, branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlDriver.java)
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-09-18 18:45:53 UTC (rev 140)
@@ -0,0 +1,253 @@
+// 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.bean;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.Map;
+
+import org.w3c.dom.Element;
+
+import net.sf.practicalxml.DomUtil;
+import net.sf.practicalxml.converter.ConversionException;
+import net.sf.practicalxml.converter.bean.Bean2XmlAppenders.*;
+import net.sf.practicalxml.converter.internal.ConversionStrings;
+import net.sf.practicalxml.converter.internal.DomUtilToo;
+import net.sf.practicalxml.converter.internal.PrimitiveConversionHelper;
+
+
+/**
+ * Driver class for converting a Java bean into an XML DOM. Normal usage is
+ * to create a single instance of this class with desired options, then use
+ * it for multiple conversions. This class is thread-safe.
+ */
+public class Bean2XmlConverter
+{
+ private PrimitiveConversionHelper _helper;
+ private EnumSet<Bean2XmlOptions> _options = EnumSet.noneOf(Bean2XmlOptions.class);
+
+ public Bean2XmlConverter(Bean2XmlOptions... options)
+ {
+ for (Bean2XmlOptions option : options)
+ _options.add(option);
+ _helper = new PrimitiveConversionHelper(shouldUseXsdFormatting());
+ }
+
+
+//----------------------------------------------------------------------------
+// Public methods
+//----------------------------------------------------------------------------
+
+ /**
+ * Creates an XML DOM with the specified root element name, and fills it
+ * by introspecting the passed object (see {@link #introspect} for
+ * treatment of simple objects).
+ */
+ public Element convert(Object obj, String rootName)
+ {
+ return convert(obj, null, rootName);
+ }
+
+
+ /**
+ * Creates an XML DOM with the specified root element name and namespace
+ * URI, and fills it by introspecting the passed object (see {@link
+ * #introspect} for treatment of simple objects). The namespace URI (and
+ * prefix, if provided) will be used for all child elements.
+ */
+ public Element convert(Object obj, String nsUri, String rootName)
+ {
+ Element root = DomUtil.newDocument(nsUri, rootName);
+ doXsiNamespaceHack(root);
+ convert(obj, "", new DirectAppender(root, _options));
+ return root;
+ }
+
+
+ /**
+ * Introspects the passed object, and appends its contents to the output.
+ * This method is public to allow non-standard conversions, such as
+ * appending into an existing tree, or (in the future, if we introduce an
+ * appender factory) producing non-XML output.
+ */
+ public void convert(Object obj, String name, Appender appender)
+ {
+ // these methods have side effects!
+ // empty blocks and comments are there to keep Eclipse happy
+ if (tryToConvertAsPrimitiveOrNull(obj, null, name, appender))
+ { /* it was converted */ }
+ else if (tryToConvertAsArray(obj, name, appender))
+ { /* it was converted */ }
+ else if (tryToConvertAsMap(obj, name, appender))
+ { /* it was converted */ }
+ else if (tryToConvertAsCollection(obj, name, appender))
+ { /* it was converted */ }
+ else if (tryToConvertAsBean(obj, name, appender))
+ { /* it was converted */ }
+ else
+ throw new ConversionException("unable to convert: " + obj.getClass().getName());
+ }
+
+
+//----------------------------------------------------------------------------
+// Internals
+//----------------------------------------------------------------------------
+
+ private boolean shouldUseXsdFormatting()
+ {
+ return _options.contains(Bean2XmlOptions.XSD_FORMAT)
+ || _options.contains(Bean2XmlOptions.ADD_XSI_TYPE);
+ }
+
+
+ /**
+ * Introduces the XML Schema Instance namespace into the DOM tree using a
+ * meaningless attribute. The Xerces serializer does not attempt to promote
+ * namespace definitions above the subtree in which they first appear, which
+ * means that the XSI definition could be repeated many times throughout the
+ * serialized tree, adding bulk to the serialized representation.
+ * <p>
+ * By putting "nil=false" at the root element, we will keep the serializer
+ * from inserting all these definitions. This has to happen <em>before</em>
+ * any actual conversion, in case some bozo passes <code>null</code> to
+ * the top-level conversion routine.
+ * <p>
+ * Note that we only do this if <code>xsi:nil</code> is enabled by itself.
+ * If <code>xsi:type</code> is enabled, the converter will attach that
+ * attribute to the root instead, thereby establishing the namespace context.
+ */
+ private void doXsiNamespaceHack(Element root)
+ {
+ if (_options.contains(Bean2XmlOptions.XSI_NIL)
+ && !_options.contains(Bean2XmlOptions.ADD_XSI_TYPE))
+ {
+ DomUtilToo.setXsiNil(root, false);
+ }
+ }
+
+
+ private boolean tryToConvertAsPrimitiveOrNull(
+ Object obj, Class<?> klass, String name, Appender appender)
+ {
+ if (obj != null)
+ klass = obj.getClass();
+
+ String objType = _helper.getXsdType(klass);
+ if ((obj == null) || (objType != null))
+ {
+ appender.appendValue(name, objType, _helper.stringify(obj));
+ return true;
+ }
+
+ return false;
+ }
+
+
+ private boolean tryToConvertAsArray(Object array, String name, Appender appender)
+ {
+ if (!array.getClass().isArray())
+ return false;
+
+ Element parent = appender.appendContainer(name, DomUtilToo.getXsiTypeForJavaObject(array));
+ Appender childAppender = new IndexedAppender(parent, _options);
+ int length = Array.getLength(array);
+ for (int idx = 0 ; idx < length ; idx++)
+ {
+ Object value = Array.get(array, idx);
+ convert(value, ConversionStrings.EL_COLLECTION_ITEM, childAppender);
+ }
+ return true;
+ }
+
+
+ private boolean tryToConvertAsMap(Object obj, String name, Appender appender)
+ {
+ if (!(obj instanceof Map))
+ return false;
+
+ Element parent = appender.appendContainer(name, DomUtilToo.getXsiTypeForJavaObject(obj));
+ Appender childAppender = new MapAppender(parent, _options);
+ for (Map.Entry<?,?> entry : ((Map<?,?>)obj).entrySet())
+ {
+ convert(entry.getValue(), String.valueOf(entry.getKey()), childAppender);
+ }
+ return true;
+ }
+
+
+ private boolean tryToConvertAsCollection(Object obj, String name, Appender appender)
+ {
+ if (!(obj instanceof Collection))
+ return false;
+
+ Element parent = appender.appendContainer(name, DomUtilToo.getXsiTypeForJavaObject(obj));
+ Appender childAppender = new IndexedAppender(parent, _options);
+ for (Object value : (Collection<?>)obj)
+ {
+ convert(value, ConversionStrings.EL_COLLECTION_ITEM, childAppender);
+ }
+ return true;
+ }
+
+
+ private boolean tryToConvertAsBean(Object bean, String name, Appender appender)
+ {
+ Element parent = appender.appendContainer(name, DomUtilToo.getXsiTypeForJavaObject(bean));
+ Appender childAppender = new BasicAppender(parent, _options);
+ try
+ {
+ BeanInfo info = Introspector.getBeanInfo(bean.getClass(), Object.class);
+ PropertyDescriptor[] props = info.getPropertyDescriptors();
+ for (int ii = 0 ; ii < props.length ; ii++)
+ convertBeanProperty(bean, props[ii], childAppender);
+ }
+ catch (IntrospectionException ee)
+ {
+ throw new ConversionException("introspection failure", ee);
+ }
+ return true;
+ }
+
+
+ private void convertBeanProperty(
+ Object bean, PropertyDescriptor propDesc, Appender appender)
+ {
+ String name = propDesc.getName();
+ Class<?> type = propDesc.getPropertyType();
+ Object value;
+ try
+ {
+ Method getter = propDesc.getReadMethod();
+ if (getter == null)
+ return;
+ value = getter.invoke(bean);
+ }
+ catch (Exception ee)
+ {
+ throw new ConversionException("unable to retrieve bean value", ee);
+ }
+
+ if (value == null)
+ tryToConvertAsPrimitiveOrNull(value, type, name, appender);
+ else
+ convert(value, name, appender);
+ }
+}
Deleted: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlDriver.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlDriver.java 2009-09-18 15:51:32 UTC (rev 139)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlDriver.java 2009-09-18 18:45:53 UTC (rev 140)
@@ -1,253 +0,0 @@
-// 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.bean;
-
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.Array;
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.Map;
-
-import org.w3c.dom.Element;
-
-import net.sf.practicalxml.DomUtil;
-import net.sf.practicalxml.converter.ConversionException;
-import net.sf.practicalxml.converter.bean.Bean2XmlAppenders.*;
-import net.sf.practicalxml.converter.internal.ConversionStrings;
-import net.sf.practicalxml.converter.internal.DomUtilToo;
-import net.sf.practicalxml.converter.internal.PrimitiveConversionHelper;
-
-
-/**
- * Driver class for converting a Java bean into an XML DOM. Normal usage is
- * to create a single instance of this class with desired options, then use
- * it for multiple conversions. This class is thread-safe.
- */
-public class Bean2XmlDriver
-{
- private PrimitiveConversionHelper _helper;
- private EnumSet<Bean2XmlOptions> _options = EnumSet.noneOf(Bean2XmlOptions.class);
-
- public Bean2XmlDriver(Bean2XmlOptions... options)
- {
- for (Bean2XmlOptions option : options)
- _options.add(option);
- _helper = new PrimitiveConversionHelper(shouldUseXsdFormatting());
- }
-
-
-//----------------------------------------------------------------------------
-// Public methods
-//----------------------------------------------------------------------------
-
- /**
- * Creates an XML DOM with the specified root element name, and fills it
- * by introspecting the passed object (see {@link #introspect} for
- * treatment of simple objects).
- */
- public Element convert(Object obj, String rootName)
- {
- return convert(obj, null, rootName);
- }
-
-
- /**
- * Creates an XML DOM with the specified root element name and namespace
- * URI, and fills it by introspecting the passed object (see {@link
- * #introspect} for treatment of simple objects). The namespace URI (and
- * prefix, if provided) will be used for all child elements.
- */
- public Element convert(Object obj, String nsUri, String rootName)
- {
- Element root = DomUtil.newDocument(nsUri, rootName);
- doXsiNamespaceHack(root);
- convert(obj, "", new DirectAppender(root, _options));
- return root;
- }
-
-
- /**
- * Introspects the passed object, and appends its contents to the output.
- * This method is public to allow non-standard conversions, such as
- * appending into an existing tree, or (in the future, if we introduce an
- * appender factory) producing non-XML output.
- */
- public void convert(Object obj, String name, Appender appender)
- {
- // these methods have side effects!
- // empty blocks and comments are there to keep Eclipse happy
- if (tryToConvertAsPrimitiveOrNull(obj, null, name, appender))
- { /* it was converted */ }
- else if (tryToConvertAsArray(obj, name, appender))
- { /* it was converted */ }
- else if (tryToConvertAsMap(obj, name, appender))
- { /* it was converted */ }
- else if (tryToConvertAsCollection(obj, name, appender))
- { /* it was converted */ }
- else if (tryToConvertAsBean(obj, name, appender))
- { /* it was converted */ }
- else
- throw new ConversionException("unable to convert: " + obj.getClass().getName());
- }
-
-
-//----------------------------------------------------------------------------
-// Internals
-//----------------------------------------------------------------------------
-
- private boolean shouldUseXsdFormatting()
- {
- return _options.contains(Bean2XmlOptions.XSD_FORMAT)
- || _options.contains(Bean2XmlOptions.ADD_XSI_TYPE);
- }
-
-
- /**
- * Introduces the XML Schema Instance namespace into the DOM tree using a
- * meaningless attribute. The Xerces serializer does not attempt to promote
- * namespace definitions above the subtree in which they first appear, which
- * means that the XSI definition could be repeated many times throughout the
- * serialized tree, adding bulk to the serialized representation.
- * <p>
- * By putting "nil=false" at the root element, we will keep the serializer
- * from inserting all these definitions. This has to happen <em>before</em>
- * any actual conversion, in case some bozo passes <code>null</code> to
- * the top-level conversion routine.
- * <p>
- * Note that we only do this if <code>xsi:nil</code> is enabled by itself.
- * If <code>xsi:type</code> is enabled, the converter will attach that
- * attribute to the root instead, thereby establishing the namespace context.
- */
- private void doXsiNamespaceHack(Element root)
- {
- if (_options.contains(Bean2XmlOptions.XSI_NIL)
- && !_options.contains(Bean2XmlOptions.ADD_XSI_TYPE))
- {
- DomUtilToo.setXsiNil(root, false);
- }
- }
-
-
- private boolean tryToConvertAsPrimitiveOrNull(
- Object obj, Class<?> klass, String name, Appender appender)
- {
- if (obj != null)
- klass = obj.getClass();
-
- String objType = _helper.getXsdType(klass);
- if ((obj == null) || (objType != null))
- {
- appender.appendValue(name, objType, _helper.stringify(obj));
- return true;
- }
-
- return false;
- }
-
-
- private boolean tryToConvertAsArray(Object array, String name, Appender appender)
- {
- if (!array.getClass().isArray())
- return false;
-
- Element parent = appender.appendContainer(name, DomUtilToo.getXsiTypeForJavaObject(array));
- Appender childAppender = new IndexedAppender(parent, _options);
- int length = Array.getLength(array);
- for (int idx = 0 ; idx < length ; idx++)
- {
- Object value = Array.get(array, idx);
- convert(value, ConversionStrings.EL_COLLECTION_ITEM, childAppender);
- }
- return true;
- }
-
-
- private boolean tryToConvertAsMap(Object obj, String name, Appender appender)
- {
- if (!(obj instanceof Map))
- return false;
-
- Element parent = appender.appendContainer(name, DomUtilToo.getXsiTypeForJavaObject(obj));
- Appender childAppender = new MapAppender(parent, _options);
- for (Map.Entry<?,?> entry : ((Map<?,?>)obj).entrySet())
- {
- convert(entry.getValue(), String.valueOf(entry.getKey()), childAppender);
- }
- return true;
- }
-
-
- private boolean tryToConvertAsCollection(Object obj, String name, Appender appender)
- {
- if (!(obj instanceof Collection))
- return false;
-
- Element parent = appender.appendContainer(name, DomUtilToo.getXsiTypeForJavaObject(obj));
- Appender childAppender = new IndexedAppender(parent, _options);
- for (Object value : (Collection<?>)obj)
- {
- convert(value, ConversionStrings.EL_COLLECTION_ITEM, childAppender);
- }
- return true;
- }
-
-
- private boolean tryToConvertAsBean(Object bean, String name, Appender appender)
- {
- Element parent = appender.appendContainer(name, DomUtilToo.getXsiTypeForJavaObject(bean));
- Appender childAppender = new BasicAppender(parent, _options);
- try
- {
- BeanInfo info = Introspector.getBeanInfo(bean.getClass(), Object.class);
- PropertyDescriptor[] props = info.getPropertyDescriptors();
- for (int ii = 0 ; ii < props.length ; ii++)
- convertBeanProperty(bean, props[ii], childAppender);
- }
- catch (IntrospectionException ee)
- {
- throw new ConversionException("introspection failure", ee);
- }
- return true;
- }
-
-
- private void convertBeanProperty(
- Object bean, PropertyDescriptor propDesc, Appender appender)
- {
- String name = propDesc.getName();
- Class<?> type = propDesc.getPropertyType();
- Object value;
- try
- {
- Method getter = propDesc.getReadMethod();
- if (getter == null)
- return;
- value = getter.invoke(bean);
- }
- catch (Exception ee)
- {
- throw new ConversionException("unable to retrieve bean value", ee);
- }
-
- if (value == null)
- tryToConvertAsPrimitiveOrNull(value, type, name, appender);
- else
- convert(value, name, appender);
- }
-}
Copied: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java (from rev 130, branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanDriver.java)
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java 2009-09-18 18:45:53 UTC (rev 140)
@@ -0,0 +1,396 @@
+// 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.bean;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import net.sf.practicalxml.DomUtil;
+import net.sf.practicalxml.converter.ConversionException;
+import net.sf.practicalxml.converter.internal.ConversionStrings;
+import net.sf.practicalxml.converter.internal.DomUtilToo;
+import net.sf.practicalxml.converter.internal.PrimitiveConversionHelper;
+import net.sf.practicalxml.internal.StringUtils;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+/**
+ * Driver class for converting an XML DOM into a Java bean. Normal usage is
+ * to create a single instance of this class with desired options, then use
+ * it for multiple conversions. This class is thread-safe.
+ */
+public class Xml2BeanConverter
+{
+ private EnumSet<Xml2BeanOptions> _options;
+ private PrimitiveConversionHelper _helper;
+ private Map<Class<?>,Map<String,Method>> _introspectedClasses;
+
+
+ public Xml2BeanConverter(Xml2BeanOptions... options)
+ {
+ _options = EnumSet.noneOf(Xml2BeanOptions.class);
+ for (Xml2BeanOptions option : options)
+ _options.add(option);
+
+ _helper = new PrimitiveConversionHelper(_options.contains(Xml2BeanOptions.EXPECT_XSD_FORMAT));
+ _introspectedClasses = new HashMap<Class<?>,Map<String,Method>>();
+ }
+
+
+//----------------------------------------------------------------------------
+// Public Methods
+//----------------------------------------------------------------------------
+
+ /**
+ * Attempts to convert the passed DOM subtree into an object of the
+ * specified class.
+ */
+ public <T> T convert(Element elem, Class<T> klass)
+ {
+ return klass.cast(convertWithoutCast(elem, klass));
+ }
+
+
+//----------------------------------------------------------------------------
+// Internal Conversion Methods
+//----------------------------------------------------------------------------
+
+ /**
+ * Attempts to convert the passed DOM subtree into an object of the
+ * specified class. Note that this version does not use generics,
+ * and does not try to cast the result, whereas the public version
+ * does. Internally, we want to treat <code>Integer.TYPE</code> the
+ * same as <code>Integer.class</code>, and the cast prevents that.
+ */
+ public Object convertWithoutCast(Element elem, Class<?> klass)
+ {
+ validateXsiType(elem, klass);
+ if (isAllowableNull(elem))
+ return null;
+
+ Object obj = tryConvertAsPrimitive(elem, klass);
+ if (obj == null)
+ obj = tryConvertAsArray(elem, klass);
+ if (obj == null)
+ obj = tryConvertAsSimpleCollection(elem, klass);
+ if (obj == null)
+ obj = tryConvertAsMap(elem, klass);
+ if (obj == null)
+ obj = tryConvertAsBean(elem, klass);
+ return obj;
+ }
+
+
+ private boolean isAllowableNull(Element elem)
+ {
+ String text = getText(elem);
+ if ((text != null) || hasElementChildren(elem))
+ return false;
+
+ if (_options.contains(Xml2BeanOptions.REQUIRE_XSI_NIL))
+ {
+ if (!DomUtilToo.getXsiNil(elem))
+ throw new ConversionException("missing/false xsi:nil", elem);
+ }
+
+ return true;
+ }
+
+
+ private Object tryConvertAsPrimitive(Element elem, Class<?> klass)
+ {
+ if (_helper.getXsdType(klass) == null)
+ return null;
+
+ if (hasElementChildren(elem))
+ throw new ConversionException("expecting primitive; has children", elem);
+
+ return _helper.parse(getText(elem), klass);
+ }
+
+
+ private Object tryConvertAsArray(Element elem, Class<?> klass)
+ {
+ Class<?> childKlass = klass.getComponentType();
+ if (childKlass == null)
+ return null;
+
+ List<Element> children = DomUtil.getChildren(elem);
+ Object result = Array.newInstance(childKlass, children.size());
+ int idx = 0;
+ for (Element child : children)
+ {
+ Array.set(result, idx++, convertWithoutCast(child, childKlass));
+ }
+ return result;
+ }
+
+
+ private Object tryConvertAsSimpleCollection(Element elem, Class<?> klass)
+ {
+ Collection<Object> result = instantiateCollection(klass);
+ if (result == null)
+ return null;
+
+ List<Element> children = DomUtil.getChildren(elem);
+ for (Element child : children)
+ {
+ Class<?> childClass = getClassFromXsiType(child);
+ if (childClass == null)
+ childClass = String.class;
+ result.add(convertWithoutCast(child, childClass));
+ }
+ return result;
+ }
+
+
+ private Object tryConvertAsMap(Element elem, Class<?> klass)
+ {
+ Map<Object,Object> result = instantiateMap(klass);
+ if (result == null)
+ return null;
+
+ List<Element> children = DomUtil.getChildren(elem);
+ for (Element child : children)
+ {
+ String key = child.getAttribute(ConversionStrings.AT_MAP_KEY);
+ if (StringUtils.isEmpty(key))
+ key = DomUtil.getLocalName(child);
+ Class<?> childClass = getClassFromXsiType(child);
+ if (childClass == null)
+ childClass = String.class;
+ result.put(key, convertWithoutCast(child, childClass));
+ }
+ return result;
+ }
+
+
+ private Object tryConvertAsBean(Element elem, Class<?> klass)
+ {
+ Object bean = instantiateBean(elem, klass);
+
+ List<Element> children = DomUtil.getChildren(elem);
+ for (Element child : children)
+ {
+ Method setter = getSetterMethod(klass, child);
+ if (setter == null)
+ continue;
+
+ Class<?> childClass = setter.getParameterTypes()[0];
+ Object childValue = convertWithoutCast(child, childClass);
+ invokeSetter(elem, bean, setter, childValue);
+ }
+ return bean;
+ }
+
+
+//----------------------------------------------------------------------------
+// Other Internals
+//----------------------------------------------------------------------------
+
+ /**
+ * Returns the text content of an element, applying appropriate options.
+ */
+ private String getText(Element elem)
+ {
+ String text = DomUtil.getText(elem);
+ if (StringUtils.isBlank(text)
+ && _options.contains(Xml2BeanOptions.CONVERT_BLANK_AS_NULL))
+ text = null;
+ return text;
+ }
+
+
+ /**
+ * Examines an element's <code>xsi:type</code> attribute, if any, and
+ * returns the Java class corresponding to it. Used when converting
+ * collection types, which don't have type information that can be
+ * introspected, and also to validate non-XSD types.
+ */
+ private Class<?> getClassFromXsiType(Element elem)
+ {
+ String xsiType = DomUtilToo.getXsiType(elem);
+ if (xsiType == null)
+ return null;
+
+ String javaType = DomUtilToo.getJavaClassFromXsiType(xsiType);
+ if (javaType != null)
+ {
+ try
+ {
+ return Class.forName(javaType);
+ }
+ catch (ClassNotFoundException ee)
+ {
+ throw new ConversionException(
+ "invalid Java type specification: " + javaType, elem, ee);
+ }
+ }
+
+ return _helper.getJavaType(xsiType);
+ }
+
+
+ private void validateXsiType(Element elem, Class<?> klass)
+ {
+ if (!_options.contains(Xml2BeanOptions.REQUIRE_XSI_TYPE))
+ return;
+
+ String xsiType = DomUtilToo.getXsiType(elem);
+ if (xsiType == null)
+ throw new ConversionException("missing xsi:type", elem);
+
+ if (xsiType.equals(_helper.getXsdType(klass)))
+ return;
+
+ Class<?> xsiKlass = getClassFromXsiType(elem);
+ if (klass.isAssignableFrom(xsiKlass))
+ return;
+
+ throw new ConversionException(
+ "invalid xsi:type: \"" + xsiType + "\" for " + klass.getName(),
+ elem);
+ }
+
+
+ private boolean hasElementChildren(Element elem)
+ {
+ Node child = elem.getFirstChild();
+ while (child != null)
+ {
+ if (child instanceof Element)
+ return true;
+ child = child.getNextSibling();
+ }
+ return false;
+ }
+
+
+ private Method getSetterMethod(Class<?> beanKlass, Element child)
+ {
+ Map<String,Method> methodMap = _introspectedClasses.get(beanKlass);
+ if (methodMap == null)
+ methodMap = introspect(beanKlass);
+
+ Method setter = methodMap.get(DomUtil.getLocalName(child));
+ if ((setter == null) && !_options.contains(Xml2BeanOptions.IGNORE_MISSING_PROPERTIES))
+ {
+ throw new ConversionException("can't find property setter", child);
+ }
+
+ return setter;
+ }
+
+
+ private Map<String,Method> introspect(Class<?> klass)
+ {
+ Map<String,Method> methodMap = new HashMap<String,Method>();
+ try
+ {
+ BeanInfo info = Introspector.getBeanInfo(klass, Object.class);
+ for (PropertyDescriptor propDesc : info.getPropertyDescriptors())
+ {
+ Method setter = propDesc.getWriteMethod();
+ if (setter != null)
+ methodMap.put(propDesc.getName(), setter);
+ }
+ }
+ catch (IntrospectionException ee)
+ {
+ throw new ConversionException("unable to introspect", ee);
+ }
+
+ _introspectedClasses.put(klass, methodMap);
+ return methodMap;
+ }
+
+
+ /**
+ * Attempts to create a <code>Collection</code> instance appropriate for
+ * the passed class, returns <code>null</code> if unable.
+ */
+ private Collection<Object> instantiateCollection(Class<?> klass)
+ {
+ if (SortedSet.class.isAssignableFrom(klass))
+ return new TreeSet<Object>();
+ else if (Set.class.isAssignableFrom(klass))
+ return new HashSet<Object>();
+ else if (List.class.isAssignableFrom(klass))
+ return new ArrayList<Object>();
+ else if (Collection.class.isAssignableFrom(klass))
+ return new ArrayList<Object>();
+ else
+ return null;
+ }
+
+
+ /**
+ * Attempts to create a <code>Map</code> instance appropriate for the
+ * passed class, returns <code>null</code> if unable.
+ */
+ private Map<Object,Object> instantiateMap(Class<?> klass)
+ {
+ if (SortedMap.class.isAssignableFrom(klass))
+ return new TreeMap<Object,Object>();
+ else if (Map.class.isAssignableFrom(klass))
+ return new HashMap<Object,Object>();
+ else
+ return null;
+ }
+
+
+ private Object instantiateBean(Element elem, Class<?> klass)
+ {
+ try
+ {
+ return klass.newInstance();
+ }
+ catch (Exception ee)
+ {
+ throw new ConversionException("unable to instantiate bean", elem, ee);
+ }
+ }
+
+
+ private void invokeSetter(Element elem, Object bean, Method setter, Object value)
+ {
+ try
+ {
+ setter.invoke(bean, value);
+ }
+ catch (Exception ee)
+ {
+ throw new ConversionException("unable to set property", elem, ee);
+ }
+ }
+}
Deleted: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanDriver.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanDriver.java 2009-09-18 15:51:32 UTC (rev 139)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanDriver.java 2009-09-18 18:45:53 UTC (rev 140)
@@ -1,396 +0,0 @@
-// 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.bean;
-
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.Array;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-import net.sf.practicalxml.DomUtil;
-import net.sf.practicalxml.converter.ConversionException;
-import net.sf.practicalxml.converter.internal.ConversionStrings;
-import net.sf.practicalxml.converter.internal.DomUtilToo;
-import net.sf.practicalxml.converter.internal.PrimitiveConversionHelper;
-import net.sf.practicalxml.internal.StringUtils;
-
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-
-/**
- * Driver class for converting an XML DOM into a Java bean. Normal usage is
- * to create a single instance of this class with desired options, then use
- * it for multiple conversions. This class is thread-safe.
- */
-public class Xml2BeanDriver
-{
- private EnumSet<Xml2BeanOptions> _options;
- private PrimitiveConversionHelper _helper;
- private Map<Class<?>,Map<String,Method>> _introspectedClasses;
-
-
- public Xml2BeanDriver(Xml2BeanOptions... options)
- {
- _options = EnumSet.noneOf(Xml2BeanOptions.class);
- for (Xml2BeanOptions option : options)
- _options.add(option);
-
- _helper = new PrimitiveConversionHelper(_options.contains(Xml2BeanOptions.EXPECT_XSD_FORMAT));
- _introspectedClasses = new HashMap<Class<?>,Map<String,Method>>();
- }
-
-
-//----------------------------------------------------------------------------
-// Public Methods
-//----------------------------------------------------------------------------
-
- /**
- * Attempts to convert the passed DOM subtree into an object of the
- * specified class.
- */
- public <T> T convert(Element elem, Class<T> klass)
- {
- return klass.cast(convertWithoutCast(elem, klass));
- }
-
-
-//----------------------------------------------------------------------------
-// Internal Conversion Methods
-//----------------------------------------------------------------------------
-
- /**
- * Attempts to convert the passed DOM subtree into an object of the
- * specified class. Note that this version does not use generics,
- * and does not try to cast the result, whereas the public version
- * does. Internally, we want to treat <code>Integer.TYPE</code> the
- * same as <code>Integer.class</code>, and the cast prevents that.
- */
- public Object convertWithoutCast(Element elem, Class<?> klass)
- {
- validateXsiType(elem, klass);
- if (isAllowableNull(elem))
- return null;
-
- Object obj = tryConvertAsPrimitive(elem, klass);
- if (obj == null)
- obj = tryConvertAsArray(elem, klass);
- if (obj == null)
- obj = tryConvertAsSimpleCollection(elem, klass);
- if (obj == null)
- obj = tryConvertAsMap(elem, klass);
- if (obj == null)
- obj = tryConvertAsBean(elem, klass);
- return obj;
- }
-
-
- private boolean isAllowableNull(Element elem)
- {
- String text = getText(elem);
- if ((text != null) || hasElementChildren(elem))
- return false;
-
- if (_options.contains(Xml2BeanOptions.REQUIRE_XSI_NIL))
- {
- if (!DomUtilToo.getXsiNil(elem))
- throw new ConversionException("missing/false xsi:nil", elem);
- }
-
- return true;
- }
-
-
- private Object tryConvertAsPrimitive(Element elem, Class<?> klass)
- {
- if (_helper.getXsdType(klass) == null)
- return null;
-
- if (hasElementChildren(elem))
- throw new ConversionException("expecting primitive; has children", elem);
-
- return _helper.parse(getText(elem), klass);
- }
-
-
- private Object tryConvertAsArray(Element elem, Class<?> klass)
- {
- Class<?> childKlass = klass.getComponentType();
- if (childKlass == null)
- return null;
-
- List<Element> children = DomUtil.getChildren(elem);
- Object result = Array.newInstance(childKlass, children.size());
- int idx = 0;
- for (Element child : children)
- {
- Array.set(result, idx++, convertWithoutCast(child, childKlass));
- }
- return result;
- }
-
-
- private Object tryConvertAsSimpleCollection(Element elem, Class<?> klass)
- {
- Collection<Object> result = instantiateCollection(klass);
- if (result == null)
- return null;
-
- List<Element> children = DomUtil.getChildren(elem);
- for (Element child : children)
- {
- Class<?> childClass = getClassFromXsiType(child);
- if (childClass == null)
- childClass = String.class;
- result.add(convertWithoutCast(child, childClass));
- }
- return result;
- }
-
-
- private Object tryConvertAsMap(Element elem, Class<?> klass)
- {
- Map<Object,Object> result = instantiateMap(klass);
- if (result == null)
- return null;
-
- List<Element> children = DomUtil.getChildren(elem);
- for (Element child : children)
- {
- String key = child.getAttribute(ConversionStrings.AT_MAP_KEY);
- if (StringUtils.isEmpty(key))
- key = DomUtil.getLocalName(child);
- Class<?> childClass = getClassFromXsiType(child);
- if (childClass == null)
- childClass = String.class;
- result.put(key, convertWithoutCast(child, childClass));
- }
- return result;
- }
-
-
- private Object tryConvertAsBean(Element elem, Class<?> klass)
- {
- Object bean = instantiateBean(elem, klass);
-
- List<Element> children = DomUtil.getChildren(elem);
- for (Element child : children)
- {
- Method setter = getSetterMethod(klass, child);
- if (setter == null)
- continue;
-
- Class<?> childClass = setter.getParameterTypes()[0];
- Object childValue = convertWithoutCast(child, childClass);
- invokeSetter(elem, bean, setter, childValue);
- }
- return bean;
- }
-
-
-//----------------------------------------------------------------------------
-// Other Internals
-//----------------------------------------------------------------------------
-
- /**
- * Returns the text content of an element, applying appropriate options.
- */
- private String getText(Element elem)
- {
- String text = DomUtil.getText(elem);
- if (StringUtils.isBlank(text)
- && _options.contains(Xml2BeanOptions.CONVERT_BLANK_AS_NULL))
- text = null;
- return text;
- }
-
-
- /**
- * Examines an element's <code>xsi:type</code> attribute, if any, and
- * returns the Java class corresponding to it. Used when converting
- * collection types, which don't have type information that can be
- * introspected, and also to validate non-XSD types.
- */
- private Class<?> getClassFromXsiType(Element elem)
- {
- String xsiType = DomUtilToo.getXsiType(elem);
- if (xsiType == null)
- return null;
-
- String javaType = DomUtilToo.getJavaClassFromXsiType(xsiType);
- if (javaType != null)
- {
- try
- {
- return Class.forName(javaType);
- }
- catch (ClassNotFoundException ee)
- {
- throw new ConversionException(
- "invalid Java type specification: " + javaType, elem, ee);
- }
- }
-
- return _helper.getJavaType(xsiType);
- }
-
-
- private void validateXsiType(Element elem, Class<?> klass)
- {
- if (!_options.contains(Xml2BeanOptions.REQUIRE_XSI_TYPE))
- return;
-
- String xsiType = DomUtilToo.getXsiType(elem);
- if (xsiType == null)
- throw new ConversionException("missing xsi:type", elem);
-
- if (xsiType.equals(_helper.getXsdType(klass)))
- return;
-
- Class<?> xsiKlass = getClassFromXsiType(elem);
- if (klass.isAssignableFrom(xsiKlass))
- return;
-
- throw new ConversionException(
- "invalid xsi:type: \"" + xsiType + "\" for " + klass.getName(),
- elem);
- }
-
-
- private boolean hasElementChildren(Element elem)
- {
- Node child = elem.getFirstChild();
- while (child != null)
- {
- if (child instanceof Element)
- return true;
- child = child.getNextSibling();
- }
- return false;
- }
-
-
- private Method getSetterMethod(Class<?> beanKlass, Element child)
- {
- Map<String,Method> methodMap = _introspectedClasses.get(beanKlass);
- if (methodMap == null)
- methodMap = introspect(beanKlass);
-
- Method setter = methodMap.get(DomUtil.getLocalName(child));
- if ((setter == null) && !_options.contains(Xml2BeanOptions.IGNORE_MISSING_PROPERTIES))
- {
- throw new ConversionException("can't find property setter", child);
- }
-
- return setter;
- }
-
-
- private Map<String,Method> introspect(Class<?> klass)
- {
- Map<String,Method> methodMap = new HashMap<String,Method>();
- try
- {
- BeanInfo info = Introspector.getBeanInfo(klass, Object.class);
- for (PropertyDescriptor propDesc : info.getPropertyDescriptors())
- {
- Method setter = propDesc.getWriteMethod();
- if (setter != null)
- methodMap.put(propDesc.getName(), setter);
- }
- }
- catch (IntrospectionException ee)
- {
- throw new ConversionException("unable to introspect", ee);
- }
-
- _introspectedClasses.put(klass, methodMap);
- return methodMap;
- }
-
-
- /**
- * Attempts to create a <code>Collection</code> instance appropriate for
- * the passed class, returns <code>null</code> if unable.
- */
- private Collection<Object> instantiateCollection(Class<?> klass)
- {
- if (SortedSet.class.isAssignableFrom(klass))
- return new TreeSet<Object>();
- else if (Set.class.isAssignableFrom(klass))
- return new HashSet<Object>();
- else if (List.class.isAssignableFrom(klass))
- return new ArrayList<Object>();
- else if (Collection.class.isAssignableFrom(klass))
- return new ArrayList<Object>();
- else
- return null;
- }
-
-
- /**
- * Attempts to create a <code>Map</code> instance appropriate for the
- * passed class, returns <code>null</code> if unable.
- */
- private Map<Object,Object> instantiateMap(Class<?> klass)
- {
- if (SortedMap.class.isAssignableFrom(klass))
- return new TreeMap<Object,Object>();
- else if (Map.class.isAssignableFrom(klass))
- return new HashMap<Object,Object>();
- else
- return null;
- }
-
-
- private Object instantiateBean(Element elem, Class<?> klass)
- {
- try
- {
- return klass.newInstance();
- }
- ...
[truncated message content] |
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-18 15:51:42
|
Revision: 139
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=139&view=rev
Author: kdgregory
Date: 2009-09-18 15:51:32 +0000 (Fri, 18 Sep 2009)
Log Message:
-----------
OutputUtil: add compact() and indented(), allowing arbitrary source and target objects
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/OutputUtil.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/OutputUtil.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/OutputUtil.java 2009-09-17 12:49:44 UTC (rev 138)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/OutputUtil.java 2009-09-18 15:51:32 UTC (rev 139)
@@ -64,6 +64,29 @@
/**
+ * Serializes to a compact format, without prologue or whitespace between
+ * elements, using UTF-8 encoding.
+ */
+ public static void compact(Source src, Result target)
+ {
+ new TransformHelper().transform(src, target);
+ }
+
+
+ /**
+ * Serializes to a human-readable format, with each element starting on a
+ * new line, and child elements indented a specified amount from their
+ * parent.
+ */
+ public static void indented(Source src, Result target, int indent)
+ {
+ new TransformHelper()
+ .setIndent(indent)
+ .transform(src, target);
+ }
+
+
+ /**
* Writes a DOM document to a simple string format, without a prologue or
* whitespace between elements.
* <p>
@@ -75,8 +98,7 @@
public static String compactString(Document dom)
{
StringWriter out = new StringWriter();
- new TransformHelper()
- .transform(new DOMSource(dom), new StreamResult(out));
+ compact(new DOMSource(dom), new StreamResult(out));
return out.toString();
}
@@ -102,8 +124,7 @@
public static String compactString(XMLReader reader)
{
StringWriter out = new StringWriter();
- new TransformHelper()
- .transform(new SAXSource(reader, null), new StreamResult(out));
+ compact(new SAXSource(reader, null), new StreamResult(out));
return out.toString();
}
@@ -115,22 +136,20 @@
* Do not simply write this string to a file unless you use UTF-8 encoding
* or attach a prologue that specifies the encoding.
*
- * @param dom The DOM tree to be output.
- * @param indentSize The number of spaces to indent each level of the
- * tree. Indentation is <em>best effort</em>: the
- * <code>javax.transform</code> API does not provide
- * any way to set indent level, so we use JDK-specific
- * features to achieve this, <em>where available</em>.
- * Note also that indenting will cause problems with
- * elements that contain mixed content, particularly
- * if the text elements cannot be trimmed.
+ * @param dom The DOM tree to be output.
+ * @param indent The number of spaces to indent each level of the
+ * tree. Indentation is <em>best effort</em>: the
+ * <code>javax.transform</code> API does not provide
+ * any way to set indent level, so we use JDK-specific
+ * features to achieve this, <em>where available</em>.
+ * Note also that indenting will cause problems with
+ * elements that contain mixed content, particularly
+ * if the text elements cannot be trimmed.
*/
- public static String indentedString(Document dom, int indentSize)
+ public static String indentedString(Document dom, int indent)
{
StringWriter out = new StringWriter();
- new TransformHelper()
- .setIndent(indentSize)
- .transform(new DOMSource(dom), new StreamResult(out));
+ indented(new DOMSource(dom), new StreamResult(out), indent);
return out.toString();
}
@@ -151,29 +170,27 @@
* Do not simply write this string to a file unless you use UTF-8 encoding
* or attach a prologue that specifies the encoding.
*
- * @param reader Provides a source of SAX events for the transformer.
- * @param indentSize The number of spaces to indent each level of the
- * tree. Indentation is <em>best effort</em>: the
- * <code>javax.transform</code> API does not provide
- * any way to set indent level, so we use JDK-specific
- * features to achieve this, <em>where available</em>.
- * Note also that indenting will cause problems with
- * elements that contain mixed content, particularly
- * if the text elements cannot be trimmed.
+ * @param reader Provides a source of SAX events for the transformer.
+ * @param indent The number of spaces to indent each level of the
+ * tree. Indentation is <em>best effort</em>: the
+ * <code>javax.transform</code> API does not provide
+ * any way to set indent level, so we use JDK-specific
+ * features to achieve this, <em>where available</em>.
+ * Note also that indenting will cause problems with
+ * elements that contain mixed content, particularly
+ * if the text elements cannot be trimmed.
*/
- public static String indentedString(XMLReader reader, int indentSize)
+ public static String indentedString(XMLReader reader, int indent)
{
StringWriter out = new StringWriter();
- new TransformHelper()
- .setIndent(indentSize)
- .transform(new SAXSource(reader, null), new StreamResult(out));
+ indented(new SAXSource(reader, null), new StreamResult(out), indent);
return out.toString();
}
/**
- * Writes a DOM document to a stream using UTF-8 encoding, without a prologue
- * or whitespace between elements.
+ * Writes a DOM document to a stream using UTF-8 encoding, in a compact
+ * format without a prologue or whitespace between elements.
*
* @param dom The DOM tree to be output.
* @param stream The output stream. This stream will be flushed by
@@ -181,16 +198,15 @@
*/
public static void compactStream(Document dom, OutputStream stream)
{
- new TransformHelper()
- .transform(new DOMSource(dom), new StreamResult(stream));
+ compact(new DOMSource(dom), new StreamResult(stream));
flushStream(stream);
}
/**
- * Writes XML to a stream using UTF-8 encoding, without prologue or
- * whitespace between elements, using the passed <code>XMLReader</code>
- * to generate a stream of SAX events.
+ * Writes XML to a stream using UTF-8 encoding, in a compact format
+ * without prologue or whitespace between elements, using the passed
+ * <code>XMLReader</code> to generate a stream of SAX events.
* <p>
* The transformer will call the reader's <code>setContentHandler()</code>
* method, followed by <code>parse()</code>. In the latter method, the
@@ -206,8 +222,7 @@
*/
public static void compactStream(XMLReader reader, OutputStream stream)
{
- new TransformHelper()
- .transform(new SAXSource(reader, null), new StreamResult(stream));
+ compact(new SAXSource(reader, null), new StreamResult(stream));
flushStream(stream);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-17 12:49:51
|
Revision: 138
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=138&view=rev
Author: kdgregory
Date: 2009-09-17 12:49:44 +0000 (Thu, 17 Sep 2009)
Log Message:
-----------
add more explanation about release numbering
Modified Paths:
--------------
trunk/README.txt
Modified: trunk/README.txt
===================================================================
--- trunk/README.txt 2009-09-16 22:10:04 UTC (rev 137)
+++ trunk/README.txt 2009-09-17 12:49:44 UTC (rev 138)
@@ -31,18 +31,37 @@
repository. Minor releases preserve backwards compatibility:
code written for one minor release will work when linked
with another minor release.
- PATCH releases won't actually get released: the PATCH revision
- number should be incremented with each checkin, in preference
- to using a "-SNAPSHOT" of the next minor release. This will
- lock users into keeping their build scripts and local repository
- up-to-date, which is a Good Thing.
+ PATCH releases happen whenever a method or class gets added or
+ changed in a minor way. They will not be released to any
+ central repository, and will probably not be tagged either.
Major and minor releases will be tagged in the Subversion repository,
using the form "rel-X.Y", where X and Y are the major and minor release
numbers. Patch releases may be tagged using the form "rel-X.Y.Z", if the
maintainer decides that it's important to rebuild that particular release
- (although making it a minor release might be a better idea).
+ (eg, as a dependency for another application).
Major and minor releases will be available for download from Sourceforge
( http://sourceforge.net/project/showfiles.php?group_id=234884 ), and also
from the Central Maven Repository.
+
+ The whole "patch release" idea has caused some controversy. My thought with
+ these releases is that they're a step above "nightly development build,"
+ and represent stable functionality. By giving fixed release numbers, your
+ build tool should call out any possible incompatibilities, such as "your
+ main project relies on 1.0.15, but your repository contains 1.0.17, why?"
+ I believe that long-lived "snapshot" builds on the trunk are a bad idea
+ (that said, if you're making a number of changes and want to check-in
+ increments, feel free to put "SNAPSHOT" on the revision number; but try
+ to finish within a day).
+
+ As far as tagging goes, I don't think that it's necessary unless you rely
+ on a particular patch revision. Then go for it. Since Subversion revision
+ numbers apply to the entire repository, you can always create an tag for
+ some past point in time. Easiest way to do this is browse the history of
+ pom.xml.
+
+ To clear up one last bit of confusion: the patch number should only be
+ incremented when the external API has changed. If you add comments, or
+ tests, or even completely rewrite the internals, the patch number stays
+ the same.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-16 22:10:10
|
Revision: 137
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=137&view=rev
Author: kdgregory
Date: 2009-09-16 22:10:04 +0000 (Wed, 16 Sep 2009)
Log Message:
-----------
update release number
Modified Paths:
--------------
trunk/pom.xml
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2009-09-16 22:05:24 UTC (rev 136)
+++ trunk/pom.xml 2009-09-16 22:10:04 UTC (rev 137)
@@ -5,7 +5,7 @@
<groupId>net.sf.practicalxml</groupId>
<artifactId>practicalxml</artifactId>
<packaging>jar</packaging>
- <version>1.0.5-SNAPSHOT</version>
+ <version>1.0.5</version>
<name>practicalxml</name>
<url>http://sourceforge.net/projects/practicalxml/</url>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-16 22:05:36
|
Revision: 136
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=136&view=rev
Author: kdgregory
Date: 2009-09-16 22:05:24 +0000 (Wed, 16 Sep 2009)
Log Message:
-----------
fix JavaDoc complaints
Modified Paths:
--------------
trunk/src/main/java/net/sf/practicalxml/SchemaUtil.java
trunk/src/main/java/net/sf/practicalxml/XmlUtil.java
trunk/src/main/java/net/sf/practicalxml/xpath/AbstractFunction.java
Modified: trunk/src/main/java/net/sf/practicalxml/SchemaUtil.java
===================================================================
--- trunk/src/main/java/net/sf/practicalxml/SchemaUtil.java 2009-09-16 21:31:05 UTC (rev 135)
+++ trunk/src/main/java/net/sf/practicalxml/SchemaUtil.java 2009-09-16 22:05:24 UTC (rev 136)
@@ -68,7 +68,7 @@
* <p>
* The caller is responsible for ordering the sources so that imported
* schemas appear first. This method is unable to combine sources from
- * the same target namespace; see {@link #combineSchema combineSchema()}
+ * the same target namespace; see {@link #combineSchemas combineSchemas()}
* for explanation.
*
* @param sources The source schema documents. Note that these are
@@ -93,7 +93,7 @@
* <p>
* The caller is responsible for ordering the sources so that imported
* schemas appear first. This method is unable to combine sources from
- * the same target namespace; see {@link #combineSchema combineSchema()}
+ * the same target namespace; see {@link #combineSchemas combineSchemas()}
* for explanation.
*
* @param factory Used to create the schema object.
@@ -119,7 +119,7 @@
* <p>
* The caller is responsible for ordering the documents so that imported
* schemas appear first. This method is unable to combine sources from
- * the same target namespace; see {@link #combineSchema combineSchema()}
+ * the same target namespace; see {@link #combineSchemas combineSchemas()}
* for explanation.
*
* @param factory Used to create the schema object.
Modified: trunk/src/main/java/net/sf/practicalxml/XmlUtil.java
===================================================================
--- trunk/src/main/java/net/sf/practicalxml/XmlUtil.java 2009-09-16 21:31:05 UTC (rev 135)
+++ trunk/src/main/java/net/sf/practicalxml/XmlUtil.java 2009-09-16 22:05:24 UTC (rev 136)
@@ -91,7 +91,7 @@
* XML Schema for <code>dateTime</code> elements. Output is UTC time, and
* omits timezone specifier.
*
- * @see http://www.w3.org/TR/xmlschema-2/#dateTime
+ * @see <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">XML Schema</a>
*/
public static String formatXsdDatetime(Date date)
{
Modified: trunk/src/main/java/net/sf/practicalxml/xpath/AbstractFunction.java
===================================================================
--- trunk/src/main/java/net/sf/practicalxml/xpath/AbstractFunction.java 2009-09-16 21:31:05 UTC (rev 135)
+++ trunk/src/main/java/net/sf/practicalxml/xpath/AbstractFunction.java 2009-09-16 22:05:24 UTC (rev 136)
@@ -444,22 +444,6 @@
* Processes a <code>null</code> argument — it's unclear whether
* this can ever happen. The default implementation throws <code>
* IllegalArgumentException</code>.
-
-
- @Override
- public boolean equals(Object obj)
- {
- // FIXME - implement
- return super.equals(obj);
- }
-
-
- @Override
- public int hashCode()
- {
- // FIXME - implement
- return super.hashCode();
- }
*
* @param index Index of the argument, numbered from 0.
* @param helper Helper object to preserve intermediate results.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|