practicalxml-commits Mailing List for Practical XML (Page 8)
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-16 21:31:11
|
Revision: 135
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=135&view=rev
Author: kdgregory
Date: 2009-09-16 21:31:05 +0000 (Wed, 16 Sep 2009)
Log Message:
-----------
fix invalid @returns JavaDoc directive
Modified Paths:
--------------
trunk/src/main/java/net/sf/practicalxml/XmlUtil.java
Modified: trunk/src/main/java/net/sf/practicalxml/XmlUtil.java
===================================================================
--- trunk/src/main/java/net/sf/practicalxml/XmlUtil.java 2009-09-16 21:29:12 UTC (rev 134)
+++ trunk/src/main/java/net/sf/practicalxml/XmlUtil.java 2009-09-16 21:31:05 UTC (rev 135)
@@ -47,8 +47,8 @@
* the BMP, you probably don't have ASCII control characters in your
* text, and don't need this method at all.
*
- * @returns true if this string does <em>not</em> contain any illegal
- * characters.
+ * @return true if this string does <em>not</em> contain any illegal
+ * characters.
*/
public static boolean isLegal(String s)
{
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 21:29:23
|
Revision: 134
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=134&view=rev
Author: kdgregory
Date: 2009-09-16 21:29:12 +0000 (Wed, 16 Sep 2009)
Log Message:
-----------
DomUtil: getChildren(), getChild(), trimTextRecursive(), and removeEmptyTextRecursive() now take any Node (so you can pass Document as well as Element)
Modified Paths:
--------------
trunk/src/main/java/net/sf/practicalxml/DomUtil.java
trunk/src/site/changes.xml
trunk/src/test/java/net/sf/practicalxml/TestDomUtil.java
Modified: trunk/src/main/java/net/sf/practicalxml/DomUtil.java
===================================================================
--- trunk/src/main/java/net/sf/practicalxml/DomUtil.java 2009-09-16 20:46:30 UTC (rev 133)
+++ trunk/src/main/java/net/sf/practicalxml/DomUtil.java 2009-09-16 21:29:12 UTC (rev 134)
@@ -29,6 +29,7 @@
import org.w3c.dom.Text;
import net.sf.practicalxml.internal.StringUtils;
+import net.sf.practicalxml.util.NodeListIterator;
import net.sf.practicalxml.xpath.NamespaceResolver;
@@ -193,10 +194,11 @@
/**
- * Returns all <code>Element</code> children of the passed element, in
- * document order.
+ * Returns all <code>Element</code> children of the passed node, in
+ * document order. Will accept any node type, although only <code>Document
+ * </code> and <code>Element</code> make sense.
*/
- public static List<Element> getChildren(Element parent)
+ public static List<Element> getChildren(Node parent)
{
return filter(parent.getChildNodes(), Element.class);
}
@@ -209,7 +211,7 @@
* Returns the children in document order. Returns an empty list if
* there are no children matching the specified namespace/name.
*/
- public static List<Element> getChildren(Element parent, String lclName)
+ public static List<Element> getChildren(Node parent, String lclName)
{
List<Element> ret = getChildren(parent);
Iterator<Element> itx = ret.iterator();
@@ -231,7 +233,7 @@
* Returns the children in document order. Returns an empty list if
* there are no children matching the specified namespace/name.
*/
- public static List<Element> getChildren(Element parent, String nsUri, String lclName)
+ public static List<Element> getChildren(Node parent, String nsUri, String lclName)
{
List<Element> ret = getChildren(parent);
Iterator<Element> itx = ret.iterator();
@@ -249,7 +251,7 @@
* Returns the first child element with the given <em>localname</em>,
* null if there are no such nodes.
*/
- public static Element getChild(Element parent, String lclName)
+ public static Element getChild(Node parent, String lclName)
{
List<Element> children = getChildren(parent, lclName);
return (children.size() > 0) ? children.get(0) : null;
@@ -260,7 +262,7 @@
* Returns the first child element with the given namespace and
* local name, null if there are no such elements.
*/
- public static Element getChild(Element parent, String nsUri, String lclName)
+ public static Element getChild(Node parent, String nsUri, String lclName)
{
List<Element> children = getChildren(parent, nsUri, lclName);
return (children.size() > 0) ? children.get(0) : null;
@@ -346,12 +348,12 @@
* Removes leading and trailing whitespace from all descendent text
* nodes. Will remove text nodes that trim to an empty string.
*/
- public static void trimTextRecursive(Element elem)
+ public static void trimTextRecursive(Node node)
{
- NodeList children = elem.getChildNodes();
- for (int ii = children.getLength() - 1 ; ii >= 0 ; ii--)
+ Iterator<Node> itx = new NodeListIterator(node.getChildNodes());
+ while (itx.hasNext())
{
- Node child = children.item(ii);
+ Node child = itx.next();
switch (child.getNodeType())
{
case Node.ELEMENT_NODE :
@@ -361,7 +363,7 @@
case Node.TEXT_NODE :
String value = StringUtils.trimToEmpty(((Text)child).getData());
if (StringUtils.isEmpty(value))
- elem.removeChild(child);
+ itx.remove();
else
((Text)child).setData(value);
break;
@@ -378,12 +380,12 @@
* could be removed by by the parser if you had a DTD that specified
* element-only content.
*/
- public static void removeEmptyTextRecursive(Element elem)
+ public static void removeEmptyTextRecursive(Node node)
{
- NodeList children = elem.getChildNodes();
- for (int ii = children.getLength() - 1 ; ii >= 0 ; ii--)
+ Iterator<Node> itx = new NodeListIterator(node.getChildNodes());
+ while (itx.hasNext())
{
- Node child = children.item(ii);
+ Node child = itx.next();
switch (child.getNodeType())
{
case Node.ELEMENT_NODE :
@@ -392,7 +394,7 @@
case Node.CDATA_SECTION_NODE :
case Node.TEXT_NODE :
if (StringUtils.isBlank(child.getNodeValue()))
- elem.removeChild(child);
+ itx.remove();
break;
default :
// do nothing
Modified: trunk/src/site/changes.xml
===================================================================
--- trunk/src/site/changes.xml 2009-09-16 20:46:30 UTC (rev 133)
+++ trunk/src/site/changes.xml 2009-09-16 21:29:12 UTC (rev 134)
@@ -11,11 +11,16 @@
initial context
</action>
<action dev='kdgregory' type='add'>
- DomUtil: Add filter(NodeList)
+ DomUtil: Add filter()
</action>
<action dev='kdgregory' type='update'>
DomUtil: appendText() now returns the created node
</action>
+ <action dev='kdgregory' type='update'>
+ DomUtil: getChildren(), getChild(), trimTextRecursive(),
+ and removeEmptyTextRecursive() now take any Node (so you
+ can pass Document as well as Element)
+ </action>
</release>
<release version="1.0.4" date="2009-09-10"
Modified: trunk/src/test/java/net/sf/practicalxml/TestDomUtil.java
===================================================================
--- trunk/src/test/java/net/sf/practicalxml/TestDomUtil.java 2009-09-16 20:46:30 UTC (rev 133)
+++ trunk/src/test/java/net/sf/practicalxml/TestDomUtil.java 2009-09-16 21:29:12 UTC (rev 134)
@@ -162,7 +162,7 @@
}
- public void testGetChildren() throws Exception
+ public void testGetChildrenOfElement() throws Exception
{
Element root = DomUtil.newDocument("foo");
DomUtil.appendText(root, "bar");
@@ -197,6 +197,62 @@
}
+
+ public void testGetChildrenOfDocument() throws Exception
+ {
+ Element root1 = DomUtil.newDocument("foo");
+ Document dom1 = root1.getOwnerDocument();
+
+ assertSame(root1, DomUtil.getChild(dom1, "foo"));
+ assertNull(DomUtil.getChild(dom1, "bar"));
+
+ List<Element> rslt1a = DomUtil.getChildren(dom1);
+ assertEquals(1, rslt1a.size());
+ assertSame(root1, rslt1a.get(0));
+
+ List<Element> rslt1b = DomUtil.getChildren(dom1, "foo");
+ assertEquals(1, rslt1b.size());
+ assertSame(root1, rslt1b.get(0));
+
+ List<Element> rslt1c = DomUtil.getChildren(dom1, "bar");
+ assertEquals(0, rslt1c.size());
+
+ // and now with namespaces
+
+ Element root2 = DomUtil.newDocument("urn:bar", "foo");
+ Document dom2 = root2.getOwnerDocument();
+
+ assertSame(root2, DomUtil.getChild(dom2, "urn:bar", "foo"));
+ assertNull(DomUtil.getChild(dom2, "urn:bar", "bar"));
+
+ List<Element> rslt2a = DomUtil.getChildren(dom2);
+ assertEquals(1, rslt2a.size());
+ assertSame(root2, rslt2a.get(0));
+
+ List<Element> rslt2b = DomUtil.getChildren(dom2, "urn:bar", "foo");
+ assertEquals(1, rslt2b.size());
+ assertSame(root2, rslt2b.get(0));
+
+ List<Element> rslt2c = DomUtil.getChildren(dom2, "urn:bar", "bar");
+ assertEquals(0, rslt2c.size());
+
+ List<Element> rslt2d = DomUtil.getChildren(dom2, "bar");
+ assertEquals(0, rslt2d.size());
+ }
+
+
+ // ensure that we don't throw if we pass something dumb
+ public void testGetChildrenOfComment() throws Exception
+ {
+ Element root = DomUtil.newDocument("foo");
+ Comment comment = root.getOwnerDocument().createComment("blah blah blah");
+ root.appendChild(comment);
+
+ List<Element> result = DomUtil.getChildren(comment);
+ assertEquals(0, result.size());
+ }
+
+
public void testAppendText() throws Exception
{
Element root = DomUtil.newDocument("root");
@@ -284,7 +340,7 @@
assertEquals(TEXT1, child1.getTextContent());
assertEquals(TEXT2_WS, child2.getTextContent());
- DomUtil.trimTextRecursive(root);
+ DomUtil.trimTextRecursive(root.getOwnerDocument());
assertEquals(TEXT1, child1.getTextContent());
assertEquals("", child2.getTextContent());
assertEquals(0, child2.getChildNodes().getLength());
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 20:46:44
|
Revision: 133
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=133&view=rev
Author: kdgregory
Date: 2009-09-16 20:46:30 +0000 (Wed, 16 Sep 2009)
Log Message:
-----------
DomUtil:
- added filter(), use it internally
- appendText() now returns the created node
Modified Paths:
--------------
trunk/src/main/java/net/sf/practicalxml/DomUtil.java
trunk/src/site/changes.xml
trunk/src/test/java/net/sf/practicalxml/TestDomUtil.java
Modified: trunk/src/main/java/net/sf/practicalxml/DomUtil.java
===================================================================
--- trunk/src/main/java/net/sf/practicalxml/DomUtil.java 2009-09-15 18:37:09 UTC (rev 132)
+++ trunk/src/main/java/net/sf/practicalxml/DomUtil.java 2009-09-16 20:46:30 UTC (rev 133)
@@ -15,6 +15,7 @@
package net.sf.practicalxml;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
@@ -197,17 +198,7 @@
*/
public static List<Element> getChildren(Element parent)
{
- List<Element> ret = new ArrayList<Element>();
- NodeList children = parent.getChildNodes();
- for (int ii = 0 ; ii < children.getLength() ; ii++)
- {
- Node child = children.item(ii);
- if (child instanceof Element)
- {
- ret.add((Element)child);
- }
- }
- return ret;
+ return filter(parent.getChildNodes(), Element.class);
}
@@ -216,45 +207,39 @@
* <em>localname</em>, ignoring namespace.
* <p>
* Returns the children in document order. Returns an empty list if
- * there are no children matching the specified name.
+ * there are no children matching the specified namespace/name.
*/
public static List<Element> getChildren(Element parent, String lclName)
{
- List<Element> ret = new ArrayList<Element>();
- NodeList children = parent.getChildNodes();
- for (int ii = 0 ; ii < children.getLength() ; ii++)
+ List<Element> ret = getChildren(parent);
+ Iterator<Element> itx = ret.iterator();
+ while (itx.hasNext())
{
- Node child = children.item(ii);
- if ((child instanceof Element)
- && (lclName.equals(getLocalName((Element)child))))
- {
- ret.add((Element)child);
- }
+ Element child = itx.next();
+ if (!lclName.equals(getLocalName((Element)child)))
+ itx.remove();
}
return ret;
}
/**
- * Returns the children of the passed element that have the given
- * namespace and <em>localname</em> (ignoring prefix). Namespace may
- * be <code>null</code>, in which case the child element must not
- * have a namespace.
+ * Returns the children of the passed element that have the given namespace
+ * and localname (ignoring prefix). Namespace may be <code>null</code>, in
+ * which case the child element must not have a namespace.
* <p>
* Returns the children in document order. Returns an empty list if
* there are no children matching the specified namespace/name.
*/
public static List<Element> getChildren(Element parent, String nsUri, String lclName)
{
- List<Element> ret = new ArrayList<Element>();
- NodeList children = parent.getChildNodes();
- for (int ii = 0 ; ii < children.getLength() ; ii++)
+ List<Element> ret = getChildren(parent);
+ Iterator<Element> itx = ret.iterator();
+ while (itx.hasNext())
{
- Node child = children.item(ii);
- if ((child instanceof Element) && isNamed((Element)child, nsUri, lclName))
- {
- ret.add((Element)child);
- }
+ Element child = itx.next();
+ if (!isNamed(child, nsUri, lclName))
+ itx.remove();
}
return ret;
}
@@ -283,13 +268,13 @@
/**
- * Returns text that is an immediate child of this node. This is
- * unlike <code>Node.getTextContent()</code>, which returns all
- * descendent text for the element.
+ * Returns the concatenation of all text and CDATA nodes that are immediate
+ * children of the passed node. If there are no text/CDATA nodes, returns
+ * <code>null</code>.
* <p>
- * Concatenates all text and CDATA nodes, does not trim whitespace.
- * If there are no text nodes, returns <code>null</code>; if all
- * text nodes contain empty strings, returns an empty string.
+ * This method differs from <code>Node.getTextContent()</code> in two ways:
+ * the latter concatenates all descendent text nodes, and will return an
+ * empty string (rather than <code>null</code>) if there are none.
*/
public static String getText(Element elem)
{
@@ -309,7 +294,6 @@
break;
default :
// do nothing
-
}
}
@@ -321,10 +305,11 @@
* Appends the specified text as a new text node on the specified
* element.
*/
- public static void appendText(Element elem, String text)
+ public static Text appendText(Element elem, String text)
{
Text child = elem.getOwnerDocument().createTextNode(text);
elem.appendChild(child);
+ return child;
}
@@ -453,7 +438,7 @@
/**
- * Creates a paramaterized list from a <code>NodeList</code>, making it
+ * Creates a parameterized list from a <code>NodeList</code>, making it
* usable within the Java coding idiom.
*
* @param nodelist The list of nodes to convert.
@@ -475,6 +460,26 @@
/**
+ * Extracts all nodes of a given type from the passed NodeList, creating
+ * a Java list of the nodes in document order.
+ *
+ * @param list The source list, which may contain any node type.
+ * @param klass The desired node type to extract from this list.
+ */
+ public static <T> List<T> filter(NodeList list, Class<T> klass)
+ {
+ ArrayList<T> result = new ArrayList<T>();
+ for (int ii = 0 ; ii < list.getLength() ; ii++)
+ {
+ Node node = list.item(ii);
+ if (klass.isInstance(node))
+ result.add(klass.cast(node));
+ }
+ return result;
+ }
+
+
+ /**
* Returns the path from the root of the document to the specified
* element, consisting of each node's qualified name, separated by
* slashes. Accepts an arbitrary number of attribute names, and
Modified: trunk/src/site/changes.xml
===================================================================
--- trunk/src/site/changes.xml 2009-09-15 18:37:09 UTC (rev 132)
+++ trunk/src/site/changes.xml 2009-09-16 20:46:30 UTC (rev 133)
@@ -5,11 +5,17 @@
<body>
<release version="1.0.5" date="2009-09-15"
- description="DomAsserts">
+ description="DomAsserts, DomUtil">
<action dev='kdgregory' type='update'>
DomAsserts: XPath assertions now take any node as
initial context
</action>
+ <action dev='kdgregory' type='add'>
+ DomUtil: Add filter(NodeList)
+ </action>
+ <action dev='kdgregory' type='update'>
+ DomUtil: appendText() now returns the created node
+ </action>
</release>
<release version="1.0.4" date="2009-09-10"
Modified: trunk/src/test/java/net/sf/practicalxml/TestDomUtil.java
===================================================================
--- trunk/src/test/java/net/sf/practicalxml/TestDomUtil.java 2009-09-15 18:37:09 UTC (rev 132)
+++ trunk/src/test/java/net/sf/practicalxml/TestDomUtil.java 2009-09-16 20:46:30 UTC (rev 133)
@@ -16,8 +16,11 @@
import java.util.List;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
@@ -107,33 +110,6 @@
}
- public void testGetSetAppendText() throws Exception
- {
- String t1 = "argle";
- String t2 = "bargle";
- String t3 = "wargle";
-
- Element root = DomUtil.newDocument("foo");
- assertNull(DomUtil.getText(root));
-
- DomUtil.setText(root, t1);
- assertEquals(t1, DomUtil.getText(root));
-
- DomUtil.appendText(root, t2);
- assertEquals(t1 + t2, DomUtil.getText(root));
-
- DomUtil.setText(root, t3);
- assertEquals(t3, DomUtil.getText(root));
-
- Element child = DomUtil.appendChildInheritNamespace(root, "bar");
- assertNull(DomUtil.getText(child));
-
- DomUtil.appendText(child, t1);
- assertEquals(t1, DomUtil.getText(child));
- assertEquals(t3, DomUtil.getText(root));
- }
-
-
public void testGetLocalName() throws Exception
{
Element root = DomUtil.newDocument("foo");
@@ -221,39 +197,70 @@
}
+ public void testAppendText() throws Exception
+ {
+ Element root = DomUtil.newDocument("root");
+ Text text = DomUtil.appendText(root, "blah blah");
+ assertSame(text, root.getChildNodes().item(0));
+ }
+
+
public void testGetText() throws Exception
{
+ String t1 = "argle";
+ String t2 = "bargle";
+ String t3 = "wargle";
+
Element root = DomUtil.newDocument("foo");
- Text rootText1 = root.getOwnerDocument().createTextNode("argle");
- root.appendChild(rootText1);
- Element child = root.getOwnerDocument().createElement("bargle");
- root.appendChild(child);
- Text rootText2 = root.getOwnerDocument().createTextNode("wargle");
- root.appendChild(rootText2);
- Text childText = root.getOwnerDocument().createTextNode("zippy");
- child.appendChild(childText);
+ assertNull(DomUtil.getText(root));
- assertEquals("arglewargle", DomUtil.getText(root));
+ DomUtil.appendText(root, t1);
+ DomUtil.appendText(root, t2);
+ assertEquals(t1 + t2, DomUtil.getText(root));
+
+ Element child = DomUtil.appendChild(root, "bar");
+ DomUtil.appendText(child, t3);
+ assertEquals(t1 + t2 + t3, root.getTextContent());
+ assertEquals(t1 + t2, DomUtil.getText(root));
+ assertEquals(t3, DomUtil.getText(child));
}
+ // this test is just here for coverage
+ public void testGetSetTextWithCData() throws Exception
+ {
+ String t1 = "argle";
+ String t2 = "bargle";
+
+ Element root = DomUtil.newDocument("root");
+ Document dom = root.getOwnerDocument();
+ CDATASection cdata = dom.createCDATASection(t1);
+ root.appendChild(cdata);
+
+ assertEquals(t1, DomUtil.getText(root));
+ assertEquals(t1, root.getTextContent());
+
+ DomUtil.setText(root, t2);
+ assertEquals(t2, DomUtil.getText(root));
+ assertEquals(t2, root.getTextContent());
+ }
+
+
public void testSetText() throws Exception
{
+ String t1 = "argle";
+ String t2 = "bargle";
+ String t3 = "wargle";
+
Element root = DomUtil.newDocument("foo");
- Text rootText1 = root.getOwnerDocument().createTextNode("argle");
- root.appendChild(rootText1);
- Element child = root.getOwnerDocument().createElement("bargle");
- root.appendChild(child);
- Text rootText2 = root.getOwnerDocument().createTextNode("wargle");
- root.appendChild(rootText2);
- Text childText = root.getOwnerDocument().createTextNode("zippy");
- child.appendChild(childText);
+ Element child = DomUtil.appendChild(root, "bar");
+ DomUtil.appendText(root, t1);
+ DomUtil.appendText(child, t2);
- DomUtil.setText(root, "bar");
- assertEquals(2, root.getChildNodes().getLength());
- assertSame(child, root.getChildNodes().item(0));
- assertEquals("bar", root.getChildNodes().item(1).getTextContent());
- assertEquals("zippy", child.getTextContent());
+ DomUtil.setText(root, t3);
+ assertEquals(t3, DomUtil.getText(root));
+ assertEquals(t2, DomUtil.getText(child));
+ assertEquals(t2 + t3, root.getTextContent());
}
@@ -337,4 +344,40 @@
assertSame(child1, result.get(0));
assertSame(child2, result.get(1));
}
+
+
+ public void testFilterNodeList() throws Exception
+ {
+ Element root = DomUtil.newDocument("foo");
+ Document dom = root.getOwnerDocument();
+ Text child1 = dom.createTextNode("argle");
+ root.appendChild(child1);
+ Element child2 = dom.createElement("bar");
+ root.appendChild(child2);
+ Comment child3 = dom.createComment("blah blah blah");
+ root.appendChild(child3);
+ Text child4 = dom.createTextNode("wargle");
+ root.appendChild(child4);
+ Element child5 = dom.createElement("baz");
+ root.appendChild(child5);
+ NodeList list = root.getChildNodes();
+
+ List<Element> elems = DomUtil.filter(list, Element.class);
+ assertEquals(2, elems.size());
+ assertSame(child2, elems.get(0));
+ assertSame(child5, elems.get(1));
+
+ List<Text> texts = DomUtil.filter(list, Text.class);
+ assertEquals(2, texts.size());
+ assertSame(child1, texts.get(0));
+ assertSame(child4, texts.get(1));
+
+ List<Comment> comments = DomUtil.filter(list, Comment.class);
+ assertEquals(1, comments.size());
+ assertSame(child3, comments.get(0));
+
+ List<Document> docs = DomUtil.filter(list, Document.class);
+ assertEquals(0, docs.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-15 18:37:16
|
Revision: 132
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=132&view=rev
Author: kdgregory
Date: 2009-09-15 18:37:09 +0000 (Tue, 15 Sep 2009)
Log Message:
-----------
add changelog report
Modified Paths:
--------------
trunk/pom.xml
Added Paths:
-----------
trunk/src/site/changes.xml
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2009-09-15 00:56:23 UTC (rev 131)
+++ trunk/pom.xml 2009-09-15 18:37:09 UTC (rev 132)
@@ -82,11 +82,13 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
- <bottom>
- <a href="http://sourceforge.net/projects/practicalxml/">
- <img src="http://sflogo.sourceforge.net/sflogo.php?group_id=234884&type=3">
+ <bottom>
+ <a
+ href="http://sourceforge.net/projects/practicalxml/">
+ <img
+ src="http://sflogo.sourceforge.net/sflogo.php?group_id=234884&type=3">
</a>
- </bottom>
+ </bottom>
</configuration>
</plugin>
<plugin>
@@ -117,6 +119,20 @@
</executions>
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-changes-plugin</artifactId>
+ <configuration>
+ <xmlPath>${basedir}/src/site/changes.xml</xmlPath>
+ </configuration>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>changes-report</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
</plugins>
</reporting>
Added: trunk/src/site/changes.xml
===================================================================
--- trunk/src/site/changes.xml (rev 0)
+++ trunk/src/site/changes.xml 2009-09-15 18:37:09 UTC (rev 132)
@@ -0,0 +1,49 @@
+<document xmlns="http://maven.apache.org/changes/1.0.0">
+ <properties>
+ <title>PracticalXML Change Log</title>
+ </properties>
+
+ <body>
+ <release version="1.0.5" date="2009-09-15"
+ description="DomAsserts">
+ <action dev='kdgregory' type='update'>
+ DomAsserts: XPath assertions now take any node as
+ initial context
+ </action>
+ </release>
+
+ <release version="1.0.4" date="2009-09-10"
+ description="NodeListIterator">
+ <action dev='kdgregory' type='add'>
+ NodeListIterator: wrapper for a NodeList that provides
+ full iterator functionality
+ </action>
+ </release>
+
+ <release version="1.0.3" date="2009-07-14" description="XmlUtil">
+ <action dev='kdgregory' type='add'>
+ XmlUtil: add formatXsdDecimal()
+ </action>
+ </release>
+
+ <release version="1.0.2" date="2009-04-27" description="OutputUtil, XmlBuilder">
+ <action dev='kdgregory' type='add'>
+ OutputUtil: added support for XMLReader as input source
+ </action>
+ <action dev='kdgregory' type='update'>
+ XmlBuilder: use SAX for text output; support PI nodes
+ </action>
+ </release>
+
+ <release version="1.0.1" date="2009-04-25" description="XmlUtil">
+ <action dev='kdgregory' type='add'>
+ XmlUtil: add .scape(), unescape()
+ </action>
+ <action />
+ </release>
+
+ <release version="1.0.0" date="2009-01-14" description="First production release"/>
+ </body>
+</document>
+
+
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-15 00:56:30
|
Revision: 131
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=131&view=rev
Author: kdgregory
Date: 2009-09-15 00:56:23 +0000 (Tue, 15 Sep 2009)
Log Message:
-----------
historical tag
Added Paths:
-----------
tags/rel-1.0.4/
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-14 23:52:28
|
Revision: 130
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=130&view=rev
Author: kdgregory
Date: 2009-09-14 23:52:20 +0000 (Mon, 14 Sep 2009)
Log Message:
-----------
BeanConverter: convert to Document, not Element
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/BeanConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java
Property Changed:
----------------
branches/dev-1.1/
Property changes on: branches/dev-1.1
___________________________________________________________________
Added: svn:mergeinfo
+ /trunk:128
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-14 23:38:49 UTC (rev 129)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/BeanConverter.java 2009-09-14 23:52:20 UTC (rev 130)
@@ -174,6 +174,7 @@
_inputDriver = new Xml2BeanDriver();
}
+
/**
* Creates an instance to be used for XML -> Bean conversion.
*/
@@ -197,9 +198,10 @@
* generated document. If a qualified name, all child
* elements will inherit its prefix.
*/
- public Element convertToXml(Object bean, String nsUri, String rootName)
+ public Document convertToXml(Object bean, String nsUri, String rootName)
{
- return _outputDriver.convert(bean, nsUri, rootName);
+ return _outputDriver.convert(bean, nsUri, rootName)
+ .getOwnerDocument();
}
@@ -211,9 +213,10 @@
* @param rootName The name given to the root element of the produced
* document.
*/
- public Element convertToXml(Object bean, String rootName)
+ public Document convertToXml(Object bean, String rootName)
{
- return _outputDriver.convert(bean, rootName);
+ return _outputDriver.convert(bean, rootName)
+ .getOwnerDocument();
}
@@ -232,7 +235,9 @@
/**
- * Creates a new Java object from the the passed DOM <code>Element</code>.
+ * Creates a new Java object 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.
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-14 23:38:49 UTC (rev 129)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java 2009-09-14 23:52:20 UTC (rev 130)
@@ -60,11 +60,12 @@
//----------------------------------------------------------------------------
private static void assertConversionFailure(
- String message, BeanConverter converter, Element elem, Class<?> klass)
+ String message, BeanConverter converter,
+ Document dom, Class<?> klass)
{
try
{
- converter.convertToJava(elem, klass);
+ converter.convertToJava(dom, klass);
fail(message);
}
catch (ConversionException ee)
@@ -84,11 +85,12 @@
BeanConverter inConverter = new BeanConverter();
String obj = "this is a test";
- Element root = outConverter.convertToXml(obj, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ Document dom = outConverter.convertToXml(obj, "test");
+// System.out.println(OutputUtil.compactString(dom));
+ Element root = dom.getDocumentElement();
assertEquals("test", DomUtil.getLocalName(root));
- Object result = inConverter.convertToJava(root, String.class);
+ Object result = inConverter.convertToJava(dom, String.class);
assertEquals(obj, result);
}
@@ -101,10 +103,10 @@
for (PrimitiveValue value : PRIMITIVE_VALUES)
{
Object obj = value.getValue();
- Element root = outConverter.convertToXml(obj, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ Document dom = outConverter.convertToXml(obj, "test");
+// System.out.println(OutputUtil.compactString(dom));
- Object result = inConverter.convertToJava(root, value.getKlass());
+ Object result = inConverter.convertToJava(dom, value.getKlass());
assertEquals(obj, result);
}
}
@@ -118,10 +120,10 @@
for (PrimitiveValue value : PRIMITIVE_VALUES)
{
Object obj = value.getValue();
- Element root = outConverter.convertToXml(obj, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ Document dom = outConverter.convertToXml(obj, "test");
+// System.out.println(OutputUtil.compactString(dom));
- Object result = inConverter.convertToJava(root, value.getKlass());
+ Object result = inConverter.convertToJava(dom, value.getKlass());
assertEquals(obj, result);
}
}
@@ -132,10 +134,10 @@
BeanConverter outConverter = new BeanConverter();
BeanConverter inConverter = new BeanConverter();
- Element root = outConverter.convertToXml(null, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ Document dom = outConverter.convertToXml(null, "test");
+// System.out.println(OutputUtil.compactString(dom));
- Object result = inConverter.convertToJava(root, String.class);
+ Object result = inConverter.convertToJava(dom, String.class);
assertNull(result);
}
@@ -145,10 +147,10 @@
BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.XSI_NIL);
BeanConverter inConverter = new BeanConverter(Xml2BeanOptions.REQUIRE_XSI_NIL);
- Element root = outConverter.convertToXml(null, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ Document dom = outConverter.convertToXml(null, "test");
+// System.out.println(OutputUtil.compactString(dom));
- Object result = inConverter.convertToJava(root, String.class);
+ Object result = inConverter.convertToJava(dom, String.class);
assertNull(result);
}
@@ -158,11 +160,12 @@
BeanConverter outConverter = new BeanConverter();
BeanConverter inConverter = new BeanConverter(Xml2BeanOptions.REQUIRE_XSI_NIL);
- Element root = outConverter.convertToXml(null, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ Document dom = outConverter.convertToXml(null, "test");
+// System.out.println(OutputUtil.compactString(dom));
- assertConversionFailure("accepted DOM with null entry but no xsi:nil",
- inConverter, root, String.class);
+ assertConversionFailure(
+ "accepted DOM with null entry but no xsi:nil",
+ inConverter, dom, String.class);
}
@@ -173,10 +176,10 @@
BeanConverter outConverter = new BeanConverter();
BeanConverter inConverter = new BeanConverter();
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ Document dom = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(dom));
- int[] result = inConverter.convertToJava(root, int[].class);
+ int[] result = inConverter.convertToJava(dom, int[].class);
assertTrue(Arrays.equals(data, result));
}
@@ -188,10 +191,10 @@
BeanConverter outConverter = new BeanConverter();
BeanConverter inConverter = new BeanConverter();
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ Document dom = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(dom));
- List<String> result = inConverter.convertToJava(root, List.class);
+ List<String> result = inConverter.convertToJava(dom, List.class);
assertEquals(data, result);
}
@@ -206,10 +209,10 @@
BeanConverter outConverter = new BeanConverter();
BeanConverter inConverter = new BeanConverter();
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ Document dom = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(dom));
- List<?> result = inConverter.convertToJava(root, List.class);
+ List<?> result = inConverter.convertToJava(dom, List.class);
assertTrue(result instanceof List);
assertTrue(result.get(0) instanceof String);
}
@@ -224,10 +227,10 @@
BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.ADD_XSI_TYPE);
BeanConverter inConverter = new BeanConverter();
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ Document dom = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(dom));
- List<?> result = inConverter.convertToJava(root, List.class);
+ List<?> result = inConverter.convertToJava(dom, List.class);
assertEquals(data, result);
}
@@ -240,10 +243,10 @@
BeanConverter outConverter = new BeanConverter();
BeanConverter inConverter = new BeanConverter();
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ Document dom = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(dom));
- Set<?> result = inConverter.convertToJava(root, SortedSet.class);
+ Set<?> result = inConverter.convertToJava(dom, SortedSet.class);
Iterator<?> itx = result.iterator();
assertEquals("bar", itx.next());
assertEquals("baz", itx.next());
@@ -262,14 +265,14 @@
BeanConverter outConverter = new BeanConverter();
BeanConverter inConverter = new BeanConverter();
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ Document dom = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(dom));
- DomAsserts.assertCount(3, root, "/test/data");
- DomAsserts.assertCount(1, root, "/test/data[@key='foo']");
- DomAsserts.assertEquals("argle", root, "/test/data[@key='foo']");
+ DomAsserts.assertCount(3, dom, "/test/data");
+ DomAsserts.assertCount(1, dom, "/test/data[@key='foo']");
+ DomAsserts.assertEquals("argle", dom, "/test/data[@key='foo']");
- Map<?,?> result = inConverter.convertToJava(root, Map.class);
+ Map<?,?> result = inConverter.convertToJava(dom, Map.class);
assertEquals(data, result);
}
@@ -285,14 +288,14 @@
BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.INTROSPECT_MAPS);
BeanConverter inConverter = new BeanConverter();
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ Document dom = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(dom));
- DomAsserts.assertCount(0, root, "/test/data");
- DomAsserts.assertCount(1, root, "/test/foo");
- DomAsserts.assertEquals("argle", root, "/test/foo");
+ DomAsserts.assertCount(0, dom, "/test/data");
+ DomAsserts.assertCount(1, dom, "/test/foo");
+ DomAsserts.assertEquals("argle", dom, "/test/foo");
- Map<?,?> result = inConverter.convertToJava(root, Map.class);
+ Map<?,?> result = inConverter.convertToJava(dom, Map.class);
assertEquals(data, result);
}
@@ -304,10 +307,10 @@
BeanConverter outConverter = new BeanConverter();
BeanConverter inConverter = new BeanConverter();
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ Document dom = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(dom));
- SimpleBean result = inConverter.convertToJava(root, SimpleBean.class);
+ SimpleBean result = inConverter.convertToJava(dom, SimpleBean.class);
data.assertEquals(result);
}
@@ -320,17 +323,18 @@
BeanConverter outconverter2 = new BeanConverter();
BeanConverter inConverter = new BeanConverter(Xml2BeanOptions.REQUIRE_XSI_TYPE);
- Element valid = outconverter1.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(valid.getOwnerDocument()));
+ Document valid = outconverter1.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(valid));
SimpleBean result = inConverter.convertToJava(valid, SimpleBean.class);
data.assertEquals(result);
- Element invalid = outconverter2.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(invalid.getOwnerDocument()));
+ Document invalid = outconverter2.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(invalid));
- assertConversionFailure("converter requiring xsi:type accepted XML without",
- inConverter, invalid, SimpleBean.class);
+ assertConversionFailure(
+ "converter requiring xsi:type accepted XML without",
+ inConverter, invalid, SimpleBean.class);
}
@@ -343,10 +347,10 @@
BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.ADD_XSI_TYPE);
BeanConverter inConverter = new BeanConverter();
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ Document dom = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(dom));
- List<SimpleBean> result = inConverter.convertToJava(root, List.class);
+ List<SimpleBean> result = inConverter.convertToJava(dom, List.class);
assertEquals(2, result.size());
bean1.assertEquals(result.get(0));
bean2.assertEquals(result.get(1));
@@ -364,10 +368,10 @@
BeanConverter outConverter = new BeanConverter();
BeanConverter inConverter = new BeanConverter();
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ Document dom = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(dom));
- SimpleBean[] result = inConverter.convertToJava(root, SimpleBean[].class);
+ SimpleBean[] result = inConverter.convertToJava(dom, SimpleBean[].class);
assertEquals(2, result.length);
bean1.assertEquals(result[0]);
bean2.assertEquals(result[1]);
@@ -384,10 +388,10 @@
BeanConverter outConverter = new BeanConverter();
BeanConverter inConverter = new BeanConverter();
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ Document dom = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(dom));
- CompoundBean result = inConverter.convertToJava(root, CompoundBean.class);
+ CompoundBean result = inConverter.convertToJava(dom, CompoundBean.class);
data.assertEquals(result);
}
@@ -399,29 +403,14 @@
BeanConverter outConverter = new BeanConverter();
BeanConverter inConverter = new BeanConverter();
- Element root = outConverter.convertToXml(data, "urn:foo", "bar:test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ Document dom = outConverter.convertToXml(data, "urn:foo", "bar:test");
+// System.out.println(OutputUtil.compactString(dom));
+ Element root = dom.getDocumentElement();
Element child = DomUtil.getChild(root, "sval");
assertEquals("urn:foo", child.getNamespaceURI());
assertEquals("bar", child.getPrefix());
- SimpleBean result = inConverter.convertToJava(root, SimpleBean.class);
- data.assertEquals(result);
- }
-
-
- // this one is here just for coverage
- public void testSimpleBeanFromDocument() throws Exception
- {
- SimpleBean data = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
-
- BeanConverter outConverter = new BeanConverter();
- BeanConverter inConverter = new BeanConverter();
-
- Document dom = outConverter.convertToXml(data, "test").getOwnerDocument();
-// System.out.println(OutputUtil.compactString(dom));
-
SimpleBean result = inConverter.convertToJava(dom, SimpleBean.class);
data.assertEquals(result);
}
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-14 23:39:11
|
Revision: 129
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=129&view=rev
Author: kdgregory
Date: 2009-09-14 23:38:49 +0000 (Mon, 14 Sep 2009)
Log Message:
-----------
merge DomAsserts from trunk
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/junit/DomAsserts.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/junit/DomAsserts.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/junit/DomAsserts.java 2009-09-14 23:30:45 UTC (rev 128)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/junit/DomAsserts.java 2009-09-14 23:38:49 UTC (rev 129)
@@ -38,10 +38,10 @@
public class DomAsserts
{
/**
- * Asserts that an element has the given name, ignoring namespace.
+ * Asserts that an element has the given localname.
*
- * @param expected The expected name.
- * @param elem The element to assert.
+ * @param expected The expected name, sans prefix.
+ * @param elem The element on which to assert this name.
*/
public static void assertName(String expected, Element elem)
{
@@ -49,11 +49,11 @@
}
/**
- * Asserts that an element has the given name, ignoring namespace.
+ * Asserts that an element has the given localname.
*
* @param message Message to display if assertion fails.
- * @param expected The expected name.
- * @param elem The element to assert.
+ * @param expected The expected name, sans prefix.
+ * @param elem The element on which to assert this name.
*/
public static void assertName(String message, String expected, Element elem)
{
@@ -71,7 +71,7 @@
* </code> to assert that the element does not
* have a namespace.
* @param expectedName The expected name.
- * @param elem The element to assert.
+ * @param elem The element on which to assert this name.
*/
public static void assertNamespaceAndName(
String expectedNSUri, String expectedName, Element elem)
@@ -89,7 +89,7 @@
* </code> to assert that the element does not
* have a namespace.
* @param expectedName The expected name.
- * @param elem The element to assert.
+ * @param elem The element on which to assert this name.
*/
public static void assertNamespaceAndName(
String message, String expectedNSUri, String expectedName, Element elem)
@@ -100,189 +100,184 @@
/**
- * Asserts that the specified XPath selects at least one node.
- * <p>
- * Will display the XPath if assertion fails.
+ * Asserts that the specified XPath selects at least one node. Uses the
+ * path as a failed-assertion message.
*
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
- public static void assertExists(Element elem, String xpath)
+ public static void assertExists(Node node, String xpath)
{
- assertExists(xpath, elem, xpath);
+ assertExists(xpath, node, xpath);
}
/**
- * Asserts that the specified XPath selects at least one node.
+ * Asserts that the specified XPath selects at least one node, using
+ * the specified message if the assertion fails.
*
- * @param message Message to display if assertion fails.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param message Message to display if assertion fails.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
- public static void assertExists(String message, Element elem, String xpath)
+ public static void assertExists(String message, Node node, String xpath)
{
- assertExists(message, elem, new XPathWrapper(xpath));
+ assertExists(message, node, new XPathWrapper(xpath));
}
/**
- * Asserts that the specified XPath selects at least one node. Uses the
- * <code>XPathWrapper</code> class to allow more complex paths, including
- * namespace bindings.
- * <p>
- * Will display the XPath if assertion fails.
+ * Asserts that the specified XPath selects at least one node. Uses
+ * {@link net.sf.practicalxml.xpath.XPathWrapper} to allow complex
+ * paths, including namespace bindings. Uses the path as a failed-
+ * assertion message.
*
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
- public static void assertExists(Element elem, XPathWrapper xpath)
+ public static void assertExists(Node node, XPathWrapper xpath)
{
- assertExists(xpath.toString(), elem, xpath);
+ assertExists(xpath.toString(), node, xpath);
}
/**
- * Asserts that the specified XPath selects at least one node. Uses the
- * <code>XPathWrapper</code> class to allow more complex paths, including
- * namespace bindings.
+ * Asserts that the specified XPath selects at least one node. Uses
+ * {@link net.sf.practicalxml.xpath.XPathWrapper} to allow complex
+ * paths, including namespace bindings.
*
- * @param message Message to display if assertion fails.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param message Message to display if assertion fails.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
- public static void assertExists(String message, Element elem, XPathWrapper xpath)
+ public static void assertExists(String message, Node node, XPathWrapper xpath)
{
- List<Node> result = xpath.evaluate(elem);
+ List<Node> result = xpath.evaluate(node);
assertTrue(message, result.size() > 0);
}
/**
* Asserts that the specified XPath selects a specified number of nodes.
- * <p>
- * Will display the XPath if assertion fails.
+ * Uses the path as a failed-assertion message.
*
- * @param expected The expected number of nodes selected.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param expected The expected number of nodes selected.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
- public static void assertCount(int expected, Element elem, String xpath)
+ public static void assertCount(int expected, Node node, String xpath)
{
- assertCount(xpath, expected, elem, xpath);
+ assertCount(xpath, expected, node, xpath);
}
/**
* Asserts that the specified XPath selects a specified number of nodes.
*
- * @param message Message to display if assertion fails.
- * @param expected The expected number of nodes selected.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param message Message to display if assertion fails.
+ * @param expected The expected number of nodes selected.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
public static void assertCount(
- String message, int expected, Element elem, String xpath)
+ String message, int expected, Node node, String xpath)
{
- assertCount(message, expected, elem, new XPathWrapper(xpath));
+ assertCount(message, expected, node, new XPathWrapper(xpath));
}
/**
* Asserts that the specified XPath selects a specified number of nodes.
- * Uses the <code>XPathWrapper</code> class to allow more complex paths,
- * including namespace bindings.
- * <p>
- * Will display the XPath if assertion fails.
+ * Uses {@link net.sf.practicalxml.xpath.XPathWrapper} to allow complex
+ * paths, including namespace bindings. Uses the path as a failed-assertion
+ * message.
*
- * @param expected The expected number of nodes selected.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param expected The expected number of nodes selected.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
- public static void assertCount(int expected, Element elem, XPathWrapper xpath)
+ public static void assertCount(int expected, Node node, XPathWrapper xpath)
{
- assertCount(xpath.toString(), expected, elem, xpath);
+ assertCount(xpath.toString(), expected, node, xpath);
}
/**
* Asserts that the specified XPath selects a specified number of nodes.
- * Uses the <code>XPathWrapper</code> class to allow more complex paths,
- * including namespace bindings.
+ * Uses {@link net.sf.practicalxml.xpath.XPathWrapper} to allow complex
+ * paths, including namespace bindings.
*
- * @param message Message to display if assertion fails.
- * @param expected The expected number of nodes selected.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param message Message to display if assertion fails.
+ * @param expected The expected number of nodes selected.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
public static void assertCount(
- String message, int expected, Element elem, XPathWrapper xpath)
+ String message, int expected, Node node, XPathWrapper xpath)
{
- List<Node> result = xpath.evaluate(elem);
+ List<Node> result = xpath.evaluate(node);
Assert.assertEquals(message, expected, result.size());
}
/**
* Asserts that the specified XPath selects a particular String value.
- * <p>
- * Will display the XPath if assertion fails.
+ * Uses the path as a failed-assertion message.
*
- * @param expected The expected value.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param expected The expected value.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
- public static void assertEquals(String expected, Element elem, String xpath)
+ public static void assertEquals(String expected, Node node, String xpath)
{
- assertEquals(xpath, expected, elem, new XPathWrapper(xpath));
+ assertEquals(xpath, expected, node, new XPathWrapper(xpath));
}
/**
* Asserts that the specified XPath selects a particular String value.
*
- * @param message Message to display if assertion fails.
- * @param expected The expected value.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param message Message to display if assertion fails.
+ * @param expected The expected value.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
public static void assertEquals(
- String message, String expected, Element elem, String xpath)
+ String message, String expected, Node node, String xpath)
{
- assertEquals(message, expected, elem, new XPathWrapper(xpath));
+ assertEquals(message, expected, node, new XPathWrapper(xpath));
}
/**
* Asserts that the specified XPath selects a particular String value.
- * This variant uses the <code>XPathWrapper</code> class to allow
- * more complex paths, including namespace bindings.
- * <p>
- * Will display the XPath if assertion fails.
+ * This variant uses {@link net.sf.practicalxml.xpath.XPathWrapper} to
+ * allow complex paths, including namespace bindings. Uses the path as
+ * a failed-assertion message.
*
- * @param expected The expected value.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param expected The expected value.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
- public static void assertEquals(String expected, Element elem, XPathWrapper xpath)
+ public static void assertEquals(String expected, Node node, XPathWrapper xpath)
{
- assertEquals(xpath.toString(), expected, elem, xpath);
+ assertEquals(xpath.toString(), expected, node, xpath);
}
/**
* Asserts that the specified XPath selects a particular String value.
- * This variant uses the <code>XPathWrapper</code> class to allow
- * more complex paths, including namespace bindings.
+ * This variant uses {@link net.sf.practicalxml.xpath.XPathWrapper} to
+ * allow complex paths, including namespace bindings.
*
- * @param message Message to display if assertion fails.
- * @param expected The expected value.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param message Message to display if assertion fails.
+ * @param expected The expected value.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
public static void assertEquals(
- String message, String expected, Element elem, XPathWrapper xpath)
+ String message, String expected, Node node, XPathWrapper xpath)
{
- Assert.assertEquals(message, expected, xpath.evaluateAsString(elem));
+ Assert.assertEquals(message, expected, xpath.evaluateAsString(node));
}
-}
+}
\ No newline at end of file
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-14 23:30:53
|
Revision: 128
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=128&view=rev
Author: kdgregory
Date: 2009-09-14 23:30:45 +0000 (Mon, 14 Sep 2009)
Log Message:
-----------
DomAsserts: XPath assertions now take any node as initial context
Modified Paths:
--------------
trunk/pom.xml
trunk/src/main/java/net/sf/practicalxml/junit/DomAsserts.java
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2009-09-11 18:30:39 UTC (rev 127)
+++ trunk/pom.xml 2009-09-14 23:30:45 UTC (rev 128)
@@ -5,7 +5,7 @@
<groupId>net.sf.practicalxml</groupId>
<artifactId>practicalxml</artifactId>
<packaging>jar</packaging>
- <version>1.0.4</version>
+ <version>1.0.5-SNAPSHOT</version>
<name>practicalxml</name>
<url>http://sourceforge.net/projects/practicalxml/</url>
Modified: trunk/src/main/java/net/sf/practicalxml/junit/DomAsserts.java
===================================================================
--- trunk/src/main/java/net/sf/practicalxml/junit/DomAsserts.java 2009-09-11 18:30:39 UTC (rev 127)
+++ trunk/src/main/java/net/sf/practicalxml/junit/DomAsserts.java 2009-09-14 23:30:45 UTC (rev 128)
@@ -38,10 +38,10 @@
public class DomAsserts
{
/**
- * Asserts that an element has the given name, ignoring namespace.
+ * Asserts that an element has the given localname.
*
- * @param expected The expected name.
- * @param elem The element to assert.
+ * @param expected The expected name, sans prefix.
+ * @param elem The element on which to assert this name.
*/
public static void assertName(String expected, Element elem)
{
@@ -49,11 +49,11 @@
}
/**
- * Asserts that an element has the given name, ignoring namespace.
+ * Asserts that an element has the given localname.
*
* @param message Message to display if assertion fails.
- * @param expected The expected name.
- * @param elem The element to assert.
+ * @param expected The expected name, sans prefix.
+ * @param elem The element on which to assert this name.
*/
public static void assertName(String message, String expected, Element elem)
{
@@ -71,7 +71,7 @@
* </code> to assert that the element does not
* have a namespace.
* @param localName The expected name, sans prefix
- * @param elem The element to assert.
+ * @param elem The element on which to assert this name.
*/
public static void assertNamespaceAndName(
String expectedNSUri, String localName, Element elem)
@@ -89,7 +89,7 @@
* </code> to assert that the element does not
* have a namespace.
* @param localName The expected name, sans prefix
- * @param elem The element to assert.
+ * @param elem The element on which to assert this name.
*/
public static void assertNamespaceAndName(
String message, String expectedNSUri, String localName, Element elem)
@@ -100,189 +100,184 @@
/**
- * Asserts that the specified XPath selects at least one node.
- * <p>
- * Will display the XPath if assertion fails.
+ * Asserts that the specified XPath selects at least one node. Uses the
+ * path as a failed-assertion message.
*
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
- public static void assertExists(Element elem, String xpath)
+ public static void assertExists(Node node, String xpath)
{
- assertExists(xpath, elem, xpath);
+ assertExists(xpath, node, xpath);
}
/**
- * Asserts that the specified XPath selects at least one node.
+ * Asserts that the specified XPath selects at least one node, using
+ * the specified message if the assertion fails.
*
- * @param message Message to display if assertion fails.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param message Message to display if assertion fails.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
- public static void assertExists(String message, Element elem, String xpath)
+ public static void assertExists(String message, Node node, String xpath)
{
- assertExists(message, elem, new XPathWrapper(xpath));
+ assertExists(message, node, new XPathWrapper(xpath));
}
/**
- * Asserts that the specified XPath selects at least one node. Uses the
- * <code>XPathWrapper</code> class to allow more complex paths, including
- * namespace bindings.
- * <p>
- * Will display the XPath if assertion fails.
+ * Asserts that the specified XPath selects at least one node. Uses
+ * {@link net.sf.practicalxml.xpath.XPathWrapper} to allow complex
+ * paths, including namespace bindings. Uses the path as a failed-
+ * assertion message.
*
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
- public static void assertExists(Element elem, XPathWrapper xpath)
+ public static void assertExists(Node node, XPathWrapper xpath)
{
- assertExists(xpath.toString(), elem, xpath);
+ assertExists(xpath.toString(), node, xpath);
}
/**
- * Asserts that the specified XPath selects at least one node. Uses the
- * <code>XPathWrapper</code> class to allow more complex paths, including
- * namespace bindings.
+ * Asserts that the specified XPath selects at least one node. Uses
+ * {@link net.sf.practicalxml.xpath.XPathWrapper} to allow complex
+ * paths, including namespace bindings.
*
- * @param message Message to display if assertion fails.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param message Message to display if assertion fails.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
- public static void assertExists(String message, Element elem, XPathWrapper xpath)
+ public static void assertExists(String message, Node node, XPathWrapper xpath)
{
- List<Node> result = xpath.evaluate(elem);
+ List<Node> result = xpath.evaluate(node);
assertTrue(message, result.size() > 0);
}
/**
* Asserts that the specified XPath selects a specified number of nodes.
- * <p>
- * Will display the XPath if assertion fails.
+ * Uses the path as a failed-assertion message.
*
- * @param expected The expected number of nodes selected.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param expected The expected number of nodes selected.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
- public static void assertCount(int expected, Element elem, String xpath)
+ public static void assertCount(int expected, Node node, String xpath)
{
- assertCount(xpath, expected, elem, xpath);
+ assertCount(xpath, expected, node, xpath);
}
/**
* Asserts that the specified XPath selects a specified number of nodes.
*
- * @param message Message to display if assertion fails.
- * @param expected The expected number of nodes selected.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param message Message to display if assertion fails.
+ * @param expected The expected number of nodes selected.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
public static void assertCount(
- String message, int expected, Element elem, String xpath)
+ String message, int expected, Node node, String xpath)
{
- assertCount(message, expected, elem, new XPathWrapper(xpath));
+ assertCount(message, expected, node, new XPathWrapper(xpath));
}
/**
* Asserts that the specified XPath selects a specified number of nodes.
- * Uses the <code>XPathWrapper</code> class to allow more complex paths,
- * including namespace bindings.
- * <p>
- * Will display the XPath if assertion fails.
+ * Uses {@link net.sf.practicalxml.xpath.XPathWrapper} to allow complex
+ * paths, including namespace bindings. Uses the path as a failed-assertion
+ * message.
*
- * @param expected The expected number of nodes selected.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param expected The expected number of nodes selected.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
- public static void assertCount(int expected, Element elem, XPathWrapper xpath)
+ public static void assertCount(int expected, Node node, XPathWrapper xpath)
{
- assertCount(xpath.toString(), expected, elem, xpath);
+ assertCount(xpath.toString(), expected, node, xpath);
}
/**
* Asserts that the specified XPath selects a specified number of nodes.
- * Uses the <code>XPathWrapper</code> class to allow more complex paths,
- * including namespace bindings.
+ * Uses {@link net.sf.practicalxml.xpath.XPathWrapper} to allow complex
+ * paths, including namespace bindings.
*
- * @param message Message to display if assertion fails.
- * @param expected The expected number of nodes selected.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param message Message to display if assertion fails.
+ * @param expected The expected number of nodes selected.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
public static void assertCount(
- String message, int expected, Element elem, XPathWrapper xpath)
+ String message, int expected, Node node, XPathWrapper xpath)
{
- List<Node> result = xpath.evaluate(elem);
+ List<Node> result = xpath.evaluate(node);
Assert.assertEquals(message, expected, result.size());
}
/**
* Asserts that the specified XPath selects a particular String value.
- * <p>
- * Will display the XPath if assertion fails.
+ * Uses the path as a failed-assertion message.
*
- * @param expected The expected value.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param expected The expected value.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
- public static void assertEquals(String expected, Element elem, String xpath)
+ public static void assertEquals(String expected, Node node, String xpath)
{
- assertEquals(xpath, expected, elem, new XPathWrapper(xpath));
+ assertEquals(xpath, expected, node, new XPathWrapper(xpath));
}
/**
* Asserts that the specified XPath selects a particular String value.
*
- * @param message Message to display if assertion fails.
- * @param expected The expected value.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param message Message to display if assertion fails.
+ * @param expected The expected value.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
public static void assertEquals(
- String message, String expected, Element elem, String xpath)
+ String message, String expected, Node node, String xpath)
{
- assertEquals(message, expected, elem, new XPathWrapper(xpath));
+ assertEquals(message, expected, node, new XPathWrapper(xpath));
}
/**
* Asserts that the specified XPath selects a particular String value.
- * This variant uses the <code>XPathWrapper</code> class to allow
- * more complex paths, including namespace bindings.
- * <p>
- * Will display the XPath if assertion fails.
+ * This variant uses {@link net.sf.practicalxml.xpath.XPathWrapper} to
+ * allow complex paths, including namespace bindings. Uses the path as
+ * a failed-assertion message.
*
- * @param expected The expected value.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param expected The expected value.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
- public static void assertEquals(String expected, Element elem, XPathWrapper xpath)
+ public static void assertEquals(String expected, Node node, XPathWrapper xpath)
{
- assertEquals(xpath.toString(), expected, elem, xpath);
+ assertEquals(xpath.toString(), expected, node, xpath);
}
/**
* Asserts that the specified XPath selects a particular String value.
- * This variant uses the <code>XPathWrapper</code> class to allow
- * more complex paths, including namespace bindings.
+ * This variant uses {@link net.sf.practicalxml.xpath.XPathWrapper} to
+ * allow complex paths, including namespace bindings.
*
- * @param message Message to display if assertion fails.
- * @param expected The expected value.
- * @param elem The element to serve as initial context.
- * @param xpath The path expression.
+ * @param message Message to display if assertion fails.
+ * @param expected The expected value.
+ * @param node Initial context for expression evaluation.
+ * @param xpath Path expression to assert.
*/
public static void assertEquals(
- String message, String expected, Element elem, XPathWrapper xpath)
+ String message, String expected, Node node, XPathWrapper xpath)
{
- Assert.assertEquals(message, expected, xpath.evaluateAsString(elem));
+ Assert.assertEquals(message, expected, xpath.evaluateAsString(node));
}
-}
+}
\ No newline at end of file
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-11 18:30:46
|
Revision: 127
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=127&view=rev
Author: kdgregory
Date: 2009-09-11 18:30:39 +0000 (Fri, 11 Sep 2009)
Log Message:
-----------
Xml2JsonConverter now escapes strings
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/JsonUtil.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonUtil.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/JsonUtil.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/JsonUtil.java 2009-09-11 17:43:24 UTC (rev 126)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/JsonUtil.java 2009-09-11 18:30:39 UTC (rev 127)
@@ -24,6 +24,53 @@
public class JsonUtil
{
/**
+ * Escapes a string, replacing quotes, backslashes, non-printable and
+ * non-ASCII characters by a defined set of single-character or 4-digit
+ * unicode escapes.
+ */
+ public static String escape(String src)
+ {
+ if (src == null)
+ return "";
+
+ StringBuffer buf = new StringBuffer(src.length() + 20);
+ for (int ii = 0 ; ii < src.length() ; ii++)
+ {
+ char c = src.charAt(ii);
+ switch (c)
+ {
+ case '"' :
+ case '\\' :
+ case '/' :
+ buf.append('\\').append(c);
+ break;
+ case '\b' :
+ buf.append("\\b");
+ break;
+ case '\f' :
+ buf.append("\\f");
+ break;
+ case '\n' :
+ buf.append("\\n");
+ break;
+ case '\r' :
+ buf.append("\\r");
+ break;
+ case '\t' :
+ buf.append("\\t");
+ break;
+ default :
+ if ((c >= 32) && (c <= 127))
+ buf.append(c);
+ else
+ buf.append(escapeUnicode(c));
+ }
+ }
+ return buf.toString();
+ }
+
+
+ /**
* Unescapes a string, replacing "slash-sequences" by actual characters.
* Null is converted to empty string.
*
@@ -100,4 +147,18 @@
}
return (char)value;
}
+
+
+ private static String escapeUnicode(char c)
+ {
+ char[] buf = new char[] { '\\', 'u', '0', '0', '0', '0' };
+ int value = c & 0xFFFF;
+ for (int ii = 5 ; ii > 1 ; ii--)
+ {
+ int digit = value % 16;
+ value /= 16;
+ buf[ii] = Character.forDigit(digit, 16);
+ }
+ return new String(buf);
+ }
}
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-11 17:43:24 UTC (rev 126)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java 2009-09-11 18:30:39 UTC (rev 127)
@@ -48,7 +48,7 @@
private StringBuffer appendText(String text, StringBuffer buf)
{
buf.append('"')
- .append(text)
+ .append(JsonUtil.escape(text))
.append('"');
return buf;
}
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonUtil.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonUtil.java 2009-09-11 17:43:24 UTC (rev 126)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonUtil.java 2009-09-11 18:30:39 UTC (rev 127)
@@ -18,6 +18,45 @@
public class TestJsonUtil extends TestCase
{
+ public void testEscapeNullAndEmpty() throws Exception
+ {
+ assertEquals("", JsonUtil.escape(null));
+ assertEquals("", JsonUtil.escape(""));
+ }
+
+
+ public void testEscapeNormalString() throws Exception
+ {
+ assertEquals("f", JsonUtil.unescape("f"));
+ assertEquals("fo", JsonUtil.unescape("fo"));
+ assertEquals("foo", JsonUtil.unescape("foo"));
+ }
+
+
+ public void testEescapeSingleChar() throws Exception
+ {
+ assertEquals("\\\"", JsonUtil.escape("\""));
+ assertEquals("\\\\", JsonUtil.escape("\\"));
+ assertEquals("\\/", JsonUtil.escape("/"));
+ assertEquals("\\b", JsonUtil.escape("\b"));
+ assertEquals("\\f", JsonUtil.escape("\f"));
+ assertEquals("\\n", JsonUtil.escape("\n"));
+ assertEquals("\\r", JsonUtil.escape("\r"));
+ assertEquals("\\t", JsonUtil.escape("\t"));
+
+ // and a couple of tests to ensure that we don't overstep
+ assertEquals("ba\\rbaz", JsonUtil.escape("ba\rbaz"));
+ assertEquals("\\r\\n", JsonUtil.escape("\r\n"));
+ }
+
+
+ public void testEscapeUnicode() throws Exception
+ {
+ assertEquals("\\u0019", JsonUtil.escape("\u0019"));
+ assertEquals("\\u1bcd", JsonUtil.escape("\u1bcd"));
+ }
+
+
public void testUnescapeNullAndEmpty() throws Exception
{
assertEquals("", JsonUtil.unescape(null));
@@ -33,7 +72,7 @@
}
- public void testUnescapeSingleCharSlashes() throws Exception
+ public void testUnescapeSingleChar() throws Exception
{
assertEquals("\"", JsonUtil.unescape("\\\""));
assertEquals("\\", JsonUtil.unescape("\\\\"));
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-11 17:43:24 UTC (rev 126)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java 2009-09-11 18:30:39 UTC (rev 127)
@@ -84,4 +84,19 @@
element("biz", text("baz")),
element("fizz", text("buzz")))));
}
+
+
+ public void testStringEscaping() throws Exception
+ {
+ convertAndAssert(
+ "{backslash: \"\\\\\", "
+ + "quote: \"\\\"\", "
+ + "nonprint: \"\\b\\f\\n\\r\\t\", "
+ + "unicode: \"b\\u00e4r\"}",
+ element("data",
+ element("backslash", text("\\")),
+ element("quote", text("\"")),
+ element("nonprint", text("\b\f\n\r\t")),
+ element("unicode", text("b\u00e4r"))));
+ }
}
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-11 17:43:40
|
Revision: 126
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=126&view=rev
Author: kdgregory
Date: 2009-09-11 17:43:24 +0000 (Fri, 11 Sep 2009)
Log Message:
-----------
implement JSON -> XML conversion
Added Paths:
-----------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/JsonUtil.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJson2XmlConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonUtil.java
Added: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java 2009-09-11 17:43:24 UTC (rev 126)
@@ -0,0 +1,262 @@
+// Copyright 2008-2009 severally by the contributors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package net.sf.practicalxml.converter.json;
+
+import org.w3c.dom.Element;
+
+import net.sf.practicalxml.DomUtil;
+import net.sf.practicalxml.converter.ConversionException;
+
+
+/**
+ * This class contains a hand-written recursive-descent parser for JSON
+ * strings. Instances are constructed around a source string, and used
+ * only once (thus thread-safety is not an issue).
+ * <p>
+ * See <a href="http://www.json.org/">json.org</a> for the JSON grammar.
+ * <p>
+ * The current implementation creates a child element for each element
+ * of an array, producing output similar to that from the Bean->XML
+ * conversion.
+ */
+public class Json2XmlConverter
+{
+ private String _src; // we pull substrings from the base string
+ private int _curPos; // position of current token (start of substring)
+ private int _nextPos; // position of next token (end of substring)
+
+
+ public Json2XmlConverter(String src)
+ {
+ _src = src;
+ }
+
+
+ /**
+ * Creates a new XML <code>Document</code> from the passed JSON string
+ * (which must contain an object definition and nothing else). The root
+ * element will be named "data".
+ */
+ public Element convert()
+ {
+ Element root = DomUtil.newDocument("data");
+ parse(root);
+ return root;
+ }
+
+
+//----------------------------------------------------------------------------
+// Internals
+//----------------------------------------------------------------------------
+
+ /**
+ * Top-level parser entry: expects the string to be a single object
+ * definition, without anything before or after the outer brace pair.
+ */
+ private void parse(Element parent)
+ {
+ expect("{");
+ parseObject(parent);
+ if (nextToken().length() > 0)
+ throw new ConversionException(commonExceptionText(
+ "unexpected content after closing brace"));
+ }
+
+
+ /**
+ * Called when the next token is expected to represent a value (of
+ * any type), to dispatch and append that value to the parent element.
+ * Returns the subsequent token.
+ */
+ private String valueDispatch(String next, Element parent)
+ {
+ if (next.equals("{"))
+ parseObject(parent);
+ else if (next.equals("["))
+ parseArray(parent);
+ else if (next.equals("\""))
+ DomUtil.setText(parent, parseString());
+ else
+ DomUtil.setText(parent, next);
+
+ return nextToken();
+ }
+
+
+ private void parseObject(Element parent)
+ {
+ String next = nextToken();
+ if (atEndOfSequence(next, "}", false))
+ return;
+
+ while (true)
+ {
+ Element child = appendChild(parent, next);
+ expect(":");
+
+ next = valueDispatch(nextToken(), child);
+ if (atEndOfSequence(next, "}", true))
+ return;
+ next = nextToken();
+ }
+ }
+
+
+ private void parseArray(Element parent)
+ {
+ String next = nextToken();
+ if (atEndOfSequence(next, "]", false))
+ return;
+
+ while (true)
+ {
+ Element child = DomUtil.appendChild(parent, "data");
+ next = valueDispatch(next, child);
+ if (atEndOfSequence(next, "]", true))
+ return;
+ next = nextToken();
+ }
+ }
+
+
+ private String parseString()
+ {
+ try
+ {
+ for (_curPos = _nextPos ; _nextPos < _src.length() ; _nextPos++)
+ {
+ char c = _src.charAt(_nextPos);
+ if (c == '"')
+ return JsonUtil.unescape(_src.substring(_curPos, _nextPos++));
+ if (c == '\\')
+ _nextPos++;
+ }
+ throw new ConversionException(commonExceptionText("unterminated string"));
+ }
+ catch (IllegalArgumentException ee)
+ {
+ throw new ConversionException(commonExceptionText("invalid string"), ee);
+ }
+ }
+
+
+ /**
+ * Reads the next token and verifies that it contains the expected value.
+ */
+ private String expect(String expected)
+ {
+ String next = nextToken();
+ if (next.equals(expected))
+ return next;
+
+ throw new ConversionException(commonExceptionText("unexpected token"));
+ }
+
+
+ /**
+ * Checks the next token (passed) to see if it represents the end of a
+ * sequence, a contination (","), or something unexpected.
+ */
+ private boolean atEndOfSequence(String next, String expectedEnd, boolean throwIfSomethingElse)
+ {
+ if (next.equals(expectedEnd))
+ return true;
+ else if (next.equals(","))
+ return false;
+ else if (next.equals(""))
+ throw new ConversionException(commonExceptionText("unexpected end of input"));
+ else if (throwIfSomethingElse)
+ throw new ConversionException(commonExceptionText("unexpected token"));
+ return false;
+ }
+
+
+ /**
+ * Extracts the next token from the string, skipping any initial whitespace.
+ * Tokens consist of a set of specific single-character strings, or any other
+ * sequence of non-whitespace characters.
+ */
+ private String nextToken()
+ {
+ final int len = _src.length();
+
+ _curPos = _nextPos;
+ while ((_curPos < len) && Character.isWhitespace(_src.charAt(_curPos)))
+ _curPos++;
+
+ if (_curPos == len)
+ return "";
+
+ _nextPos = _curPos + 1;
+ if (!isDelimiter(_src.charAt(_curPos)))
+ {
+ while ((_nextPos < len)
+ && !Character.isWhitespace(_src.charAt(_nextPos))
+ && !isDelimiter(_src.charAt(_nextPos)))
+ _nextPos++;
+ }
+
+ return _src.substring(_curPos, _nextPos);
+ }
+
+
+ private boolean isDelimiter(char c)
+ {
+ switch (c)
+ {
+ case '{' :
+ case '}' :
+ case '[' :
+ case ']' :
+ case ':' :
+ case ',' :
+ case '"' :
+ return true;
+ default :
+ return false;
+ }
+ }
+
+
+ private String commonExceptionText(String preamble)
+ {
+ String excerpt = (_curPos + 20) > _src.length()
+ ? _src.substring(_curPos)
+ : _src.substring(_curPos, _curPos + 20) + "[...]";
+ return preamble + " at position " + _curPos + ": \"" + excerpt + "\"";
+ }
+
+
+ /**
+ * A wrapper around DomUtil.appendChild() that applies some validation
+ * on the name, and replaces the DOM exception with ConversionException.
+ */
+ private Element appendChild(Element parent, String name)
+ {
+ if (name.equals(""))
+ throw new ConversionException(commonExceptionText("unexpected end of input"));
+ if (isDelimiter(name.charAt(0)))
+ throw new ConversionException(commonExceptionText("invalid token"));
+ try
+ {
+ return DomUtil.appendChild(parent, name);
+ }
+ catch (Exception e)
+ {
+ throw new ConversionException(commonExceptionText("invalid element name"), e);
+ }
+ }
+
+}
Property changes on: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java
___________________________________________________________________
Added: svn:executable
+ *
Added: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/JsonUtil.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/JsonUtil.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/JsonUtil.java 2009-09-11 17:43:24 UTC (rev 126)
@@ -0,0 +1,103 @@
+// Copyright 2008-2009 severally by the contributors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package net.sf.practicalxml.converter.json;
+
+import net.sf.practicalxml.internal.StringUtils;
+
+
+/**
+ * Static utility methods for working with JSON content. Mostly duplicates
+ * methods from Jakarta Commons.
+ */
+public class JsonUtil
+{
+ /**
+ * Unescapes a string, replacing "slash-sequences" by actual characters.
+ * Null is converted to empty string.
+ *
+ * @throws IllegalArgumentException on any failure
+ */
+ public static String unescape(String src)
+ {
+ if (src == null)
+ return "";
+
+ StringBuffer buf = new StringBuffer(src.length());
+ for (int ii = 0 ; ii < src.length() ; )
+ {
+ char c = src.charAt(ii++);
+ if (c == '\\')
+ {
+ if (ii == src.length())
+ throw new IllegalArgumentException("escape extends past end of string");
+ c = src.charAt(ii++);
+ switch (c)
+ {
+ case '"' :
+ case '\\' :
+ case '/' :
+ // do nothing, simple escape
+ break;
+ case 'b' :
+ c = '\b';
+ break;
+ case 'f' :
+ c = '\f';
+ break;
+ case 'n' :
+ c = '\n';
+ break;
+ case 'r' :
+ c = '\r';
+ break;
+ case 't' :
+ c = '\t';
+ break;
+ case 'U' :
+ case 'u' :
+ c = unescapeUnicode(src, ii);
+ ii += 4;
+ break;
+ default :
+ throw new IllegalArgumentException("invalid escape character: " + c);
+ }
+ }
+ buf.append(c);
+ }
+ return buf.toString();
+ }
+
+
+//----------------------------------------------------------------------------
+// Internals
+//----------------------------------------------------------------------------
+
+ private static char unescapeUnicode(String src, int idx)
+ {
+ if (idx + 4 > src.length())
+ throw new IllegalArgumentException("unicode escape extends past end of string");
+
+ int value = 0;
+ for (int ii = 0 ; ii < 4 ; ii++)
+ {
+ int digit = StringUtils.parseDigit(src.charAt(idx + ii), 16);
+ if (digit < 0)
+ throw new IllegalArgumentException(
+ "invalid unicode escape: " + src.substring(idx, idx + 4));
+ value = value * 16 + digit;
+ }
+ return (char)value;
+ }
+}
Added: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJson2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJson2XmlConverter.java (rev 0)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJson2XmlConverter.java 2009-09-11 17:43:24 UTC (rev 126)
@@ -0,0 +1,435 @@
+// Copyright 2008-2009 severally by the contributors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package net.sf.practicalxml.converter.json;
+
+import org.w3c.dom.Element;
+
+import net.sf.practicalxml.DomUtil;
+import net.sf.practicalxml.converter.AbstractConversionTestCase;
+import net.sf.practicalxml.converter.ConversionException;
+
+
+public class TestJson2XmlConverter
+extends AbstractConversionTestCase
+{
+ public TestJson2XmlConverter(String testName)
+ {
+ super(testName);
+ }
+
+
+//----------------------------------------------------------------------------
+// Test Cases
+// ----
+// Note that in some place we call Node.getChildNodes(), in others we call
+// DomUtil.getChildren. This is intentional: in the former case we want to
+// ensure that the converter isn't inserting extraneous text, in the latter
+// we want to ensure it isn't inserting extraneous elements (but we don't
+// care how many nodes it uses to build the text content).
+//----------------------------------------------------------------------------
+
+ public void testConvertEmpty() throws Exception
+ {
+ String src = "{}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(0, root.getChildNodes().getLength());
+ }
+
+
+ public void testConvertEmptyWithWhitespace() throws Exception
+ {
+ String src = " {\t}\n";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(0, root.getChildNodes().getLength());
+ }
+
+
+ public void testFailContentBeforeInitialBrace() throws Exception
+ {
+ String src = "test = {}";
+
+ try
+ {
+ new Json2XmlConverter(src).convert();
+ fail();
+ }
+ catch (ConversionException ee)
+ {
+ // success
+ }
+ }
+
+
+ public void testFailContentAfterTerminalBrace() throws Exception
+ {
+ String src = "{};";
+
+ try
+ {
+ new Json2XmlConverter(src).convert();
+ fail();
+ }
+ catch (ConversionException ee)
+ {
+ // success
+ }
+ }
+
+
+ public void testFailMissingTerminalBrace() throws Exception
+ {
+ String src = " { ";
+
+ try
+ {
+ new Json2XmlConverter(src).convert();
+ fail();
+ }
+ catch (ConversionException ee)
+ {
+ // success
+ }
+ }
+
+
+ public void testConvertSingleElementNumeric() throws Exception
+ {
+ String src = "{foo: 123}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertEquals("123", DomUtil.getText(child));
+ assertEquals(0, DomUtil.getChildren(child).size());
+ }
+
+
+ public void testConvertSingleElementString() throws Exception
+ {
+ String src = "{foo: \"bar\"}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertEquals("bar", DomUtil.getText(child));
+ assertEquals(0, DomUtil.getChildren(child).size());
+ }
+
+
+ public void testConvertEmptyString() throws Exception
+ {
+ String src = "{foo: \"\"}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertEquals("", DomUtil.getText(child));
+ assertEquals(0, DomUtil.getChildren(child).size());
+ }
+
+
+ public void testConvertStringWithEmbeddedEscape() throws Exception
+ {
+ String src = "{foo: \"b\\\"\\u0061r\"}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertEquals("b\"ar", DomUtil.getText(child));
+ assertEquals(0, DomUtil.getChildren(child).size());
+ }
+
+
+ public void testFailUnterminatedString() throws Exception
+ {
+ String src = "{foo: \"bar}";
+
+ try
+ {
+ new Json2XmlConverter(src).convert();
+ fail();
+ }
+ catch (ConversionException ee)
+ {
+ // success
+ }
+ }
+
+
+ public void testFailInvalidEscapeAtEndOfString() throws Exception
+ {
+ String src = "{foo: \"bar\\u123\"}";
+
+ try
+ {
+ new Json2XmlConverter(src).convert();
+ fail();
+ }
+ catch (ConversionException ee)
+ {
+ // success
+ }
+ }
+
+
+ public void testConvertTwoElementNumeric() throws Exception
+ {
+ String src = "{foo: 123, bar: 456}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(2, root.getChildNodes().getLength());
+
+ Element child1 = (Element)root.getFirstChild();
+ assertEquals("foo", child1.getNodeName());
+ assertEquals("123", DomUtil.getText(child1));
+ assertEquals(0, DomUtil.getChildren(child1).size());
+
+ Element child2 = (Element)child1.getNextSibling();
+ assertEquals("bar", child2.getNodeName());
+ assertEquals("456", DomUtil.getText(child2));
+ assertEquals(0, DomUtil.getChildren(child2).size());
+ }
+
+
+ public void testConvertTwoElementStringWithWhitespace() throws Exception
+ {
+ String src = "{foo : \"123\" , bar\t: \"456\" }";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(2, root.getChildNodes().getLength());
+
+ Element child1 = (Element)root.getFirstChild();
+ assertEquals("foo", child1.getNodeName());
+ assertEquals("123", DomUtil.getText(child1));
+ assertEquals(0, DomUtil.getChildren(child1).size());
+
+ Element child2 = (Element)child1.getNextSibling();
+ assertEquals("bar", child2.getNodeName());
+ assertEquals("456", DomUtil.getText(child2));
+ assertEquals(0, DomUtil.getChildren(child2).size());
+ }
+
+
+ public void testFailObjectMissingCommaBetweenTerms() throws Exception
+ {
+ String src = "{foo: 123 bar: 456}";
+
+ try
+ {
+ new Json2XmlConverter(src).convert();
+ fail();
+ }
+ catch (ConversionException e)
+ {
+ // success
+ }
+ }
+
+
+ public void testFailObjectMissingElement() throws Exception
+ {
+ String src = "{foo: 123, , bar: 456}";
+
+ try
+ {
+ new Json2XmlConverter(src).convert();
+ fail();
+ }
+ catch (ConversionException ee)
+ {
+ // success
+ }
+ }
+
+
+ public void testConvertNested() throws Exception
+ {
+ String src = "{foo: {bar: 123, baz:456}}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertNull(DomUtil.getText(child));
+ assertEquals(2, child.getChildNodes().getLength());
+
+ Element grandchild1 = (Element)child.getFirstChild();
+ assertEquals("bar", grandchild1.getNodeName());
+ assertEquals("123", DomUtil.getText(grandchild1));
+ assertEquals(0, DomUtil.getChildren(grandchild1).size());
+
+ Element grandchild2 = (Element)grandchild1.getNextSibling();
+ assertEquals("baz", grandchild2.getNodeName());
+ assertEquals("456", DomUtil.getText(grandchild2));
+ assertEquals(0, DomUtil.getChildren(grandchild2).size());
+ }
+
+
+ public void testConvertNestedEmpty() throws Exception
+ {
+ String src = "{foo: {}}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertNull(DomUtil.getText(child));
+ assertEquals(0, child.getChildNodes().getLength());
+ }
+
+
+ public void testConvertEmptyArray() throws Exception
+ {
+ String src = "{foo: []}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertNull(DomUtil.getText(child));
+ assertEquals(0, child.getChildNodes().getLength());
+ }
+
+
+ public void testConvertSingleElementNumericArray() throws Exception
+ {
+ String src = "{foo: [123]}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertNull(DomUtil.getText(child));
+ assertEquals(1, child.getChildNodes().getLength());
+
+ Element grandchild = (Element)child.getFirstChild();
+ assertEquals("data", grandchild.getNodeName());
+ assertEquals("123", DomUtil.getText(grandchild));
+ assertEquals(0, DomUtil.getChildren(grandchild).size());
+ }
+
+
+ public void testConvertMultiElementNumericArray() throws Exception
+ {
+ String src = "{foo: [123, 456]}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertNull(DomUtil.getText(child));
+ assertEquals(2, child.getChildNodes().getLength());
+
+ Element grandchild1 = (Element)child.getFirstChild();
+ assertEquals("data", grandchild1.getNodeName());
+ assertEquals("123", DomUtil.getText(grandchild1));
+ assertEquals(0, DomUtil.getChildren(grandchild1).size());
+
+ Element grandchild2 = (Element)grandchild1.getNextSibling();
+ assertEquals("data", grandchild2.getNodeName());
+ assertEquals("456", DomUtil.getText(grandchild2));
+ assertEquals(0, DomUtil.getChildren(grandchild2).size());
+ }
+
+
+ public void testConvertMultiElementMixedArray() throws Exception
+ {
+ String src = "{foo: [123, \"bar\", 456]}";
+
+ Element root = new Json2XmlConverter(src).convert();
+ assertEquals("data", root.getNodeName());
+ assertEquals(1, root.getChildNodes().getLength());
+
+ Element child = (Element)root.getFirstChild();
+ assertEquals("foo", child.getNodeName());
+ assertNull(DomUtil.getText(child));
+ assertEquals(3, child.getChildNodes().getLength());
+
+ Element grandchild1 = (Element)child.getFirstChild();
+ assertEquals("data", grandchild1.getNodeName());
+ assertEquals("123", DomUtil.getText(grandchild1));
+ assertEquals(0, DomUtil.getChildren(grandchild1).size());
+
+ Element grandchild2 = (Element)grandchild1.getNextSibling();
+ assertEquals("data", grandchild2.getNodeName());
+ assertEquals("bar", DomUtil.getText(grandchild2));
+ assertEquals(0, DomUtil.getChildren(grandchild2).size());
+
+ Element grandchild3 = (Element)grandchild2.getNextSibling();
+ assertEquals("data", grandchild3.getNodeName());
+ assertEquals("456", DomUtil.getText(grandchild3));
+ assertEquals(0, DomUtil.getChildren(grandchild3).size());
+ }
+
+
+ public void testFailConvertUnterminatedArray() throws Exception
+ {
+ String src = "{foo: [123, 456";
+
+ try
+ {
+ new Json2XmlConverter(src).convert();
+ fail();
+ }
+ catch (ConversionException ee)
+ {
+ // success
+ }
+ }
+
+
+ public void testFailConvertArrayMissingElement() throws Exception
+ {
+ String src = "{foo: [123 , , 456]}";
+
+ try
+ {
+ new Json2XmlConverter(src).convert();
+ fail();
+ }
+ catch (ConversionException ee)
+ {
+ // success
+ }
+ }
+}
Property changes on: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJson2XmlConverter.java
___________________________________________________________________
Added: svn:executable
+ *
Added: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonUtil.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonUtil.java (rev 0)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestJsonUtil.java 2009-09-11 17:43:24 UTC (rev 126)
@@ -0,0 +1,118 @@
+// Copyright 2008-2009 severally by the contributors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package net.sf.practicalxml.converter.json;
+
+import junit.framework.TestCase;
+
+public class TestJsonUtil extends TestCase
+{
+ public void testUnescapeNullAndEmpty() throws Exception
+ {
+ assertEquals("", JsonUtil.unescape(null));
+ assertEquals("", JsonUtil.unescape(""));
+ }
+
+
+ public void testUnescapeNormalString() throws Exception
+ {
+ assertEquals("f", JsonUtil.unescape("f"));
+ assertEquals("fo", JsonUtil.unescape("fo"));
+ assertEquals("foo", JsonUtil.unescape("foo"));
+ }
+
+
+ public void testUnescapeSingleCharSlashes() throws Exception
+ {
+ assertEquals("\"", JsonUtil.unescape("\\\""));
+ assertEquals("\\", JsonUtil.unescape("\\\\"));
+ assertEquals("/", JsonUtil.unescape("\\/"));
+ assertEquals("\b", JsonUtil.unescape("\\b"));
+ assertEquals("\f", JsonUtil.unescape("\\f"));
+ assertEquals("\n", JsonUtil.unescape("\\n"));
+ assertEquals("\r", JsonUtil.unescape("\\r"));
+ assertEquals("\t", JsonUtil.unescape("\\t"));
+
+ // and a couple of tests to ensure that we don't overstep
+ assertEquals("ba\rbaz", JsonUtil.unescape("ba\\rbaz"));
+ assertEquals("\r\n", JsonUtil.unescape("\\r\\n"));
+ }
+
+
+ public void testUnescapeUnicode() throws Exception
+ {
+ assertEquals("A", JsonUtil.unescape("\\u0041"));
+ assertEquals("A", JsonUtil.unescape("\\U0041"));
+
+ // verify that we correctly index subsequent chars
+ assertEquals("BAR", JsonUtil.unescape("B\\U0041R"));
+ }
+
+
+ public void testUnescapeFailEndOfString() throws Exception
+ {
+ try
+ {
+ JsonUtil.unescape("foo\\");
+ fail("completed for escape at end of string");
+ }
+ catch (IllegalArgumentException e)
+ {
+ // success
+ }
+ }
+
+
+ public void testUnescapeFailInvalidChar() throws Exception
+ {
+ try
+ {
+ JsonUtil.unescape("foo\\q");
+ fail("completed for invalid escape sequence");
+ }
+ catch (IllegalArgumentException e)
+ {
+ // success
+ }
+ }
+
+
+ public void testUnescapeFailIncompleteUnicodeEscape() throws Exception
+ {
+ try
+ {
+ JsonUtil.unescape("foo\\u12");
+ fail("completed for invalid escape sequence");
+ }
+ catch (IllegalArgumentException e)
+ {
+ // success
+ }
+ }
+
+
+ public void testUnescapeFailInvalidUnicodeEscape() throws Exception
+ {
+ try
+ {
+ JsonUtil.unescape("\\u0foo");
+ fail("completed for invalid escape sequence");
+ }
+ catch (IllegalArgumentException e)
+ {
+ // success
+ }
+ }
+
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-09-10 13:39:29
|
Revision: 125
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=125&view=rev
Author: kdgregory
Date: 2009-09-10 13:39:16 +0000 (Thu, 10 Sep 2009)
Log Message:
-----------
add NodeListIterator
Modified Paths:
--------------
trunk/pom.xml
trunk/src/main/java/net/sf/practicalxml/util/NodeListIterable.java
Added Paths:
-----------
trunk/src/main/java/net/sf/practicalxml/util/NodeListIterator.java
trunk/src/test/java/net/sf/practicalxml/util/TestNodeListIterator.java
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2009-09-08 16:06:13 UTC (rev 124)
+++ trunk/pom.xml 2009-09-10 13:39:16 UTC (rev 125)
@@ -5,7 +5,7 @@
<groupId>net.sf.practicalxml</groupId>
<artifactId>practicalxml</artifactId>
<packaging>jar</packaging>
- <version>1.0.3</version>
+ <version>1.0.4</version>
<name>practicalxml</name>
<url>http://sourceforge.net/projects/practicalxml/</url>
Modified: trunk/src/main/java/net/sf/practicalxml/util/NodeListIterable.java
===================================================================
--- trunk/src/main/java/net/sf/practicalxml/util/NodeListIterable.java 2009-09-08 16:06:13 UTC (rev 124)
+++ trunk/src/main/java/net/sf/practicalxml/util/NodeListIterable.java 2009-09-10 13:39:16 UTC (rev 125)
@@ -15,15 +15,15 @@
package net.sf.practicalxml.util;
import java.util.Iterator;
-import java.util.NoSuchElementException;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
- * A wrapper for a DOM <code>NodeList</code> that allows it to be used in
- * a JDK 1.5 for-each loop.
+ * A wrapper for a DOM <code>NodeList</code> that allows it to be used in a
+ * JDK 1.5 for-each loop. See {@link net.sf.practicalxml.util.NodeListIterator}
+ * if you want full iterator operation.
*/
public class NodeListIterable
implements Iterable<Node>
@@ -37,30 +37,6 @@
public Iterator<Node> iterator()
{
- return new MyIterator();
+ return new NodeListIterator(_list);
}
-
-
- private class MyIterator
- implements Iterator<Node>
- {
- int _position = 0;
-
- public boolean hasNext()
- {
- return _position < _list.getLength();
- }
-
- public Node next()
- {
- if (!hasNext())
- throw new NoSuchElementException();
- return _list.item(_position++);
- }
-
- public void remove()
- {
- throw new UnsupportedOperationException("unable to remove from NodeList");
- }
- }
}
Added: trunk/src/main/java/net/sf/practicalxml/util/NodeListIterator.java
===================================================================
--- trunk/src/main/java/net/sf/practicalxml/util/NodeListIterator.java (rev 0)
+++ trunk/src/main/java/net/sf/practicalxml/util/NodeListIterator.java 2009-09-10 13:39:16 UTC (rev 125)
@@ -0,0 +1,79 @@
+// 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.util;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+
+/**
+ * A wrapper for {@link org.w3c.dom.NodeList} that provides full iterator
+ * behavior. See {@link net.sf.practicalxml.util.NodeListIterable} if all
+ * you want to do is use the NodeList in a JDK 1.5 <code>for</code> loop.
+ * <p>
+ * Because a <code>NodeList</code> is a view on a DOM tree, this iterator has
+ * slightly different semantics than a typical <code>java.util</code> iterator.
+ * First, it is not "fail fast": the DOM consists of independent nodes, and we
+ * have no way to track when changes to the DOM may have made the nodelist
+ * invalid.
+ * <p>
+ * Second, and more important, removal via the iterator changes the DOM, not
+ * just the underlying list.
+ */
+public class NodeListIterator
+implements Iterator<Node>
+{
+ private NodeList _list;
+ private int _pos;
+ private Node _current;
+
+
+ public NodeListIterator(NodeList nodelist)
+ {
+ _list = nodelist;
+ }
+
+
+ public boolean hasNext()
+ {
+ return _pos < _list.getLength();
+ }
+
+
+ public Node next()
+ {
+ if (hasNext())
+ {
+ _current = _list.item(_pos++);
+ return _current;
+ }
+ throw new NoSuchElementException("invalid index: " + _pos);
+ }
+
+
+ public void remove()
+ {
+ if (_current == null)
+ throw new IllegalStateException("no current node");
+
+ Node _parent = _current.getParentNode();
+ _parent.removeChild(_current);
+ _pos--;
+ _current = null;
+ }
+}
Added: trunk/src/test/java/net/sf/practicalxml/util/TestNodeListIterator.java
===================================================================
--- trunk/src/test/java/net/sf/practicalxml/util/TestNodeListIterator.java (rev 0)
+++ trunk/src/test/java/net/sf/practicalxml/util/TestNodeListIterator.java 2009-09-10 13:39:16 UTC (rev 125)
@@ -0,0 +1,179 @@
+// 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.util;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+import junit.framework.TestCase;
+
+import static net.sf.practicalxml.builder.XmlBuilder.*;
+
+
+public class TestNodeListIterator
+extends TestCase
+{
+ public final static String EL_CHILD1 = "child1";
+ public final static String EL_CHILD2 = "child2";
+ public final static String TXT1 = "some text";
+
+ private Element _testData
+ = element("root",
+ element(EL_CHILD1),
+ text(TXT1),
+ element(EL_CHILD2))
+ .toDOM().getDocumentElement();
+
+//----------------------------------------------------------------------------
+// Test Cases
+//----------------------------------------------------------------------------
+
+ public void testBasicIteration() throws Exception
+ {
+ Iterator<Node> itx = new NodeListIterator(_testData.getChildNodes());
+
+ assertTrue(itx.hasNext());
+ Node node1 = itx.next();
+ assertTrue(node1 instanceof Element);
+ assertEquals(EL_CHILD1, node1.getNodeName());
+
+ assertTrue(itx.hasNext());
+ Node node2 = itx.next();
+ assertTrue(node2 instanceof Text);
+ assertEquals(TXT1, node2.getNodeValue());
+
+ assertTrue(itx.hasNext());
+ Node node3 = itx.next();
+ assertTrue(node3 instanceof Element);
+ assertEquals(EL_CHILD2, node3.getNodeName());
+
+ assertFalse(itx.hasNext());
+ }
+
+
+ public void testIterationOffTheEnd() throws Exception
+ {
+ Iterator<Node> itx = new NodeListIterator(_testData.getChildNodes());
+ while (itx.hasNext())
+ itx.next();
+
+ try
+ {
+ itx.next();
+ fail("able to iterate off end of list");
+ }
+ catch (NoSuchElementException ee)
+ {
+ // success
+ }
+ }
+
+
+ public void testRemove() throws Exception
+ {
+ Iterator<Node> itx = new NodeListIterator(_testData.getChildNodes());
+
+ itx.next();
+ itx.next();
+ itx.remove();
+
+ assertTrue(itx.hasNext());
+ Node node = itx.next();
+ assertTrue(node instanceof Element);
+ assertEquals(EL_CHILD2, node.getNodeName());
+
+ assertFalse(itx.hasNext());
+
+ // verify that DOM was changed
+
+ NodeList list = _testData.getChildNodes();
+ assertEquals(2, list.getLength());
+
+ Node node1 = list.item(0);
+ assertTrue(node1 instanceof Element);
+ assertEquals(EL_CHILD1, node1.getNodeName());
+
+ Node node2 = list.item(1);
+ assertTrue(node2 instanceof Element);
+ assertEquals(EL_CHILD2, node2.getNodeName());
+ }
+
+
+ public void testRemoveAtEndOfIteration() throws Exception
+ {
+ Iterator<Node> itx = new NodeListIterator(_testData.getChildNodes());
+
+ itx.next();
+ itx.next();
+ itx.next();
+ assertFalse(itx.hasNext());
+
+ itx.remove();
+
+ // verify that DOM was changed
+
+ NodeList list = _testData.getChildNodes();
+ assertEquals(2, list.getLength());
+
+ Node node1 = list.item(0);
+ assertTrue(node1 instanceof Element);
+ assertEquals(EL_CHILD1, node1.getNodeName());
+
+ Node node2 = list.item(1);
+ assertTrue(node2 instanceof Text);
+ assertEquals(TXT1, node2.getNodeValue());
+ }
+
+
+ public void testRemoveFailsIfNextNotCalled() throws Exception
+ {
+ Iterator<Node> itx = new NodeListIterator(_testData.getChildNodes());
+
+ try
+ {
+ itx.remove();
+ fail("remove() succeeded without initial next()");
+ }
+ catch (IllegalStateException ee)
+ {
+ // success
+ }
+ }
+
+
+ public void testRemoveFailsIfCalledTwice() throws Exception
+ {
+ Iterator<Node> itx = new NodeListIterator(_testData.getChildNodes());
+
+ itx.next();
+ itx.next();
+ itx.remove();
+
+ try
+ {
+ itx.remove();
+ fail("remove() succeeded without intervening next()");
+ }
+ catch (IllegalStateException ee)
+ {
+ // success
+ }
+ }
+}
\ No newline at end of file
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-08 16:06:23
|
Revision: 124
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=124&view=rev
Author: kdgregory
Date: 2009-09-08 16:06:13 +0000 (Tue, 08 Sep 2009)
Log Message:
-----------
implement Xml2Json conversion
Added Paths:
-----------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/
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/
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java
Added: 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 (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java 2009-09-08 16:06:13 UTC (rev 124)
@@ -0,0 +1,73 @@
+// 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 net.sf.practicalxml.DomUtil;
+
+import org.w3c.dom.Element;
+
+
+/**
+ * Handles the actual work of converting XML to JSON.
+ */
+public class Xml2JsonConverter
+{
+ /**
+ * Appends the contents of the specified element to an existing buffer.
+ * Returns the buffer as a convenience.
+ */
+ public StringBuffer convert(Element elem, StringBuffer buf)
+ {
+ String text = DomUtil.getText(elem);
+ if (text != null)
+ return appendText(text, buf);
+ else
+ return appendChildren(elem, buf);
+ }
+
+
+//----------------------------------------------------------------------------
+// Internals
+//----------------------------------------------------------------------------
+
+ private StringBuffer appendText(String text, StringBuffer buf)
+ {
+ buf.append('"')
+ .append(text)
+ .append('"');
+ return buf;
+ }
+
+
+ private StringBuffer appendChildren(Element elem, StringBuffer buf)
+ {
+ buf.append("{");
+ List<Element> children = DomUtil.getChildren(elem);
+ for (Iterator<Element> childItx = children.iterator() ; childItx.hasNext() ; )
+ {
+ Element child = childItx.next();
+ buf.append(DomUtil.getLocalName(child))
+ .append(": ");
+ convert(child, buf);
+ if (childItx.hasNext())
+ buf.append(", ");
+ }
+ buf.append("}");
+ return buf;
+ }
+}
Property changes on: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java
___________________________________________________________________
Added: svn:executable
+ *
Added: 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 (rev 0)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java 2009-09-08 16:06:13 UTC (rev 124)
@@ -0,0 +1,87 @@
+// Copyright 2008-2009 severally by the contributors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package net.sf.practicalxml.converter.json;
+
+import org.w3c.dom.Element;
+
+import net.sf.practicalxml.builder.ElementNode;
+import net.sf.practicalxml.converter.AbstractConversionTestCase;
+
+import static net.sf.practicalxml.builder.XmlBuilder.*;
+
+
+public class TestXml2JsonConverter
+extends AbstractConversionTestCase
+{
+ public TestXml2JsonConverter(String testName)
+ {
+ super(testName);
+ }
+
+
+//----------------------------------------------------------------------------
+// Support Code
+//----------------------------------------------------------------------------
+
+ public void convertAndAssert(String expected, ElementNode rootNode)
+ {
+ Element root = rootNode.toDOM().getDocumentElement();
+ StringBuffer buf = new Xml2JsonConverter()
+ .convert(root, new StringBuffer());
+ assertEquals(expected, buf.toString());
+ }
+
+
+//----------------------------------------------------------------------------
+// Test Cases
+//----------------------------------------------------------------------------
+
+ public void testEmptyConversion() throws Exception
+ {
+ convertAndAssert(
+ "{}",
+ element("data"));
+ }
+
+
+ public void testSingleChild() throws Exception
+ {
+ convertAndAssert(
+ "{foo: \"bar\"}",
+ element("data",
+ element("foo", text("bar"))));
+ }
+
+
+ public void testTwoChildren() throws Exception
+ {
+ convertAndAssert(
+ "{foo: \"bar\", argle: \"bargle\"}",
+ element("data",
+ element("foo", text("bar")),
+ element("argle", text("bargle"))));
+ }
+
+
+ public void testChildAndGrandchildren() throws Exception
+ {
+ convertAndAssert(
+ "{foo: \"bar\", argle: {biz: \"baz\", fizz: \"buzz\"}}",
+ element("data",
+ element("foo", text("bar")),
+ element("argle",
+ element("biz", text("baz")),
+ element("fizz", text("buzz")))));
+ }
+}
Property changes on: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java
___________________________________________________________________
Added: svn:executable
+ *
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-08 15:10:27
|
Revision: 123
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=123&view=rev
Author: kdgregory
Date: 2009-09-08 15:10:15 +0000 (Tue, 08 Sep 2009)
Log Message:
-----------
more testcase repackaging
Added Paths:
-----------
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java
Removed Paths:
-------------
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBeanConverter.java
Deleted: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBeanConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBeanConverter.java 2009-09-08 14:55:08 UTC (rev 122)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBeanConverter.java 2009-09-08 15:10:15 UTC (rev 123)
@@ -1,426 +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;
-
-import java.math.BigDecimal;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-import net.sf.practicalxml.DomUtil;
-import net.sf.practicalxml.OutputUtil;
-import net.sf.practicalxml.converter.bean.AbstractBeanConverterTestCase;
-import net.sf.practicalxml.converter.bean.Bean2XmlOptions;
-import net.sf.practicalxml.converter.bean.Xml2BeanOptions;
-import net.sf.practicalxml.junit.DomAsserts;
-
-
-/**
- * Tests for the top-level <code>BeanConverter</code> methods. These are all
- * "out and back" tests to verify that we can read the XML that we produce
- * (and to show cases where we can't). Detailed tests (verifying specific
- * output) are in {@link TestBean2XmlDriver} and {@link TestXml2BeanDriver}.
- * <p>
- * Note that each conversion has a commented-out line that will print the
- * generated XML. Uncommenting these lines may help you understand how
- * conversion works in particular cases.
- */
-public class TestBeanConverter
-extends AbstractBeanConverterTestCase
-{
- public TestBeanConverter(String name)
- {
- super(name);
- }
-
-
-//----------------------------------------------------------------------------
-// Support Code
-//----------------------------------------------------------------------------
-
- private static void assertConversionFailure(
- String message, BeanConverter converter, Element elem, Class<?> klass)
- {
- try
- {
- converter.convertToJava(elem, klass);
- fail(message);
- }
- catch (ConversionException ee)
- {
-// System.out.println(ee);
- }
- }
-
-//----------------------------------------------------------------------------
-// Test Cases
-//----------------------------------------------------------------------------
-
- // an initial test to verify everything works
- public void testConvertStringDefault() throws Exception
- {
- BeanConverter outConverter = new BeanConverter();
- BeanConverter inConverter = new BeanConverter();
-
- String obj = "this is a test";
- Element root = outConverter.convertToXml(obj, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
- assertEquals("test", DomUtil.getLocalName(root));
-
- Object result = inConverter.convertToJava(root, String.class);
- assertEquals(obj, result);
- }
-
-
- public void testConvertPrimitiveDefault() throws Exception
- {
- BeanConverter outConverter = new BeanConverter();
- BeanConverter inConverter = new BeanConverter();
-
- for (PrimitiveValue value : PRIMITIVE_VALUES)
- {
- Object obj = value.getValue();
- Element root = outConverter.convertToXml(obj, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
-
- Object result = inConverter.convertToJava(root, value.getKlass());
- assertEquals(obj, result);
- }
- }
-
-
- public void testConvertPrimitiveFormatXsd() throws Exception
- {
- BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.XSD_FORMAT);
- BeanConverter inConverter = new BeanConverter(Xml2BeanOptions.EXPECT_XSD_FORMAT);
-
- for (PrimitiveValue value : PRIMITIVE_VALUES)
- {
- Object obj = value.getValue();
- Element root = outConverter.convertToXml(obj, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
-
- Object result = inConverter.convertToJava(root, value.getKlass());
- assertEquals(obj, result);
- }
- }
-
-
- public void testConvertNullDefault() throws Exception
- {
- BeanConverter outConverter = new BeanConverter();
- BeanConverter inConverter = new BeanConverter();
-
- Element root = outConverter.convertToXml(null, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
-
- Object result = inConverter.convertToJava(root, String.class);
- assertNull(result);
- }
-
-
- public void testConvertNullUseAndRequireXsiNil() throws Exception
- {
- BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.XSI_NIL);
- BeanConverter inConverter = new BeanConverter(Xml2BeanOptions.REQUIRE_XSI_NIL);
-
- Element root = outConverter.convertToXml(null, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
-
- Object result = inConverter.convertToJava(root, String.class);
- assertNull(result);
- }
-
-
- public void testConvertNullFailureRequireXsiNil() throws Exception
- {
- BeanConverter outConverter = new BeanConverter();
- BeanConverter inConverter = new BeanConverter(Xml2BeanOptions.REQUIRE_XSI_NIL);
-
- Element root = outConverter.convertToXml(null, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
-
- assertConversionFailure("accepted DOM with null entry but no xsi:nil",
- inConverter, root, String.class);
- }
-
-
- public void testPrimitiveArrayDefault() throws Exception
- {
- int[] data = new int[] { 1, 2, 4, 5 };
-
- BeanConverter outConverter = new BeanConverter();
- BeanConverter inConverter = new BeanConverter();
-
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
-
- int[] result = inConverter.convertToJava(root, int[].class);
- assertTrue(Arrays.equals(data, result));
- }
-
-
- public void testStringListDefault() throws Exception
- {
- List<String> data = Arrays.asList("foo", "bar", "baz");
-
- BeanConverter outConverter = new BeanConverter();
- BeanConverter inConverter = new BeanConverter();
-
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
-
- List<String> result = inConverter.convertToJava(root, List.class);
- assertEquals(data, result);
- }
-
-
- // demonstrates that the list will be read as List<String> even though
- // it was written as List<Integer>
- public void testIntegerListDefault() throws Exception
- {
- List<Integer> data = Arrays.asList(1, 2, 3);
- assert(data.get(0) instanceof Integer);
-
- BeanConverter outConverter = new BeanConverter();
- BeanConverter inConverter = new BeanConverter();
-
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
-
- List<?> result = inConverter.convertToJava(root, List.class);
- assertTrue(result instanceof List);
- assertTrue(result.get(0) instanceof String);
- }
-
-
- // demonstrates that you don't need to require xsi:type to use it
- public void testIntegerListWithXsiType() throws Exception
- {
- List<Integer> data = Arrays.asList(1, 2, 3);
- assert(data.get(0) instanceof Integer);
-
- BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.ADD_XSI_TYPE);
- BeanConverter inConverter = new BeanConverter();
-
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
-
- List<?> result = inConverter.convertToJava(root, List.class);
- assertEquals(data, result);
- }
-
-
- // demonstrates that the caller drives the inbound conversion
- public void testConvertListToSortedSet() throws Exception
- {
- List<String> data = Arrays.asList("foo", "bar", "baz", "bar");
-
- BeanConverter outConverter = new BeanConverter();
- BeanConverter inConverter = new BeanConverter();
-
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
-
- Set<?> result = inConverter.convertToJava(root, SortedSet.class);
- Iterator<?> itx = result.iterator();
- assertEquals("bar", itx.next());
- assertEquals("baz", itx.next());
- assertEquals("foo", itx.next());
- assertFalse(itx.hasNext());
- }
-
-
- public void testMapDefault() throws Exception
- {
- Map<String,String> data = new HashMap<String,String>();
- data.put("foo", "argle");
- data.put("bar", "bargle");
- data.put("baz", "bazgle");
-
- BeanConverter outConverter = new BeanConverter();
- BeanConverter inConverter = new BeanConverter();
-
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
-
- DomAsserts.assertCount(3, root, "/test/data");
- DomAsserts.assertCount(1, root, "/test/data[@key='foo']");
- DomAsserts.assertEquals("argle", root, "/test/data[@key='foo']");
-
- Map<?,?> result = inConverter.convertToJava(root, Map.class);
- assertEquals(data, result);
- }
-
-
- // demonstrates that the input converter handles either format by default
- public void testMapIntrospected() throws Exception
- {
- Map<String,String> data = new HashMap<String,String>();
- data.put("foo", "argle");
- data.put("bar", "bargle");
- data.put("baz", "bazgle");
-
- BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.INTROSPECT_MAPS);
- BeanConverter inConverter = new BeanConverter();
-
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
-
- DomAsserts.assertCount(0, root, "/test/data");
- DomAsserts.assertCount(1, root, "/test/foo");
- DomAsserts.assertEquals("argle", root, "/test/foo");
-
- Map<?,?> result = inConverter.convertToJava(root, Map.class);
- assertEquals(data, result);
- }
-
-
- public void testSimpleBeanDefault() throws Exception
- {
- SimpleBean data = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
-
- BeanConverter outConverter = new BeanConverter();
- BeanConverter inConverter = new BeanConverter();
-
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
-
- SimpleBean result = inConverter.convertToJava(root, SimpleBean.class);
- data.assertEquals(result);
- }
-
-
- public void testSimpleBeanRequireXsiType() throws Exception
- {
- SimpleBean data = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
-
- BeanConverter outconverter1 = new BeanConverter(Bean2XmlOptions.ADD_XSI_TYPE);
- BeanConverter outconverter2 = new BeanConverter();
- BeanConverter inConverter = new BeanConverter(Xml2BeanOptions.REQUIRE_XSI_TYPE);
-
- Element valid = outconverter1.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(valid.getOwnerDocument()));
-
- SimpleBean result = inConverter.convertToJava(valid, SimpleBean.class);
- data.assertEquals(result);
-
- Element invalid = outconverter2.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(invalid.getOwnerDocument()));
-
- assertConversionFailure("converter requiring xsi:type accepted XML without",
- inConverter, invalid, SimpleBean.class);
- }
-
-
- public void testListOfSimpleBeanWithXsiTypeAndNulls() throws Exception
- {
- SimpleBean bean1 = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
- SimpleBean bean2 = new SimpleBean("zyx", 987, null, false);
- List<SimpleBean> data = Arrays.asList(bean1, bean2);
-
- BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.ADD_XSI_TYPE);
- BeanConverter inConverter = new BeanConverter();
-
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
-
- List<SimpleBean> result = inConverter.convertToJava(root, List.class);
- assertEquals(2, result.size());
- bean1.assertEquals(result.get(0));
- bean2.assertEquals(result.get(1));
- }
-
-
- // another demonstration that caller drives input conversion
- // ... and note that we don't care about xsi:type in this case
- public void testListOfSimpleBeanToArrayOfSame() throws Exception
- {
- SimpleBean bean1 = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
- SimpleBean bean2 = new SimpleBean("zyx", 987, null, false);
- List<SimpleBean> data = Arrays.asList(bean1, bean2);
-
- BeanConverter outConverter = new BeanConverter();
- BeanConverter inConverter = new BeanConverter();
-
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
-
- SimpleBean[] result = inConverter.convertToJava(root, SimpleBean[].class);
- assertEquals(2, result.length);
- bean1.assertEquals(result[0]);
- bean2.assertEquals(result[1]);
- }
-
-
- public void testCompoundBeanDefault() throws Exception
- {
- CompoundBean data = new CompoundBean(
- new SimpleBean("abc", 123, new BigDecimal("456.789"), true),
- new int[] { 1, 5, 7, 9 },
- Arrays.asList("foo", "bar", "baz"));
-
- BeanConverter outConverter = new BeanConverter();
- BeanConverter inConverter = new BeanConverter();
-
- Element root = outConverter.convertToXml(data, "test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
-
- CompoundBean result = inConverter.convertToJava(root, CompoundBean.class);
- data.assertEquals(result);
- }
-
-
- public void testSimpleBeanWithNamespace() throws Exception
- {
- SimpleBean data = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
-
- BeanConverter outConverter = new BeanConverter();
- BeanConverter inConverter = new BeanConverter();
-
- Element root = outConverter.convertToXml(data, "urn:foo", "bar:test");
-// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
-
- Element child = DomUtil.getChild(root, "sval");
- assertEquals("urn:foo", child.getNamespaceURI());
- assertEquals("bar", child.getPrefix());
-
- SimpleBean result = inConverter.convertToJava(root, SimpleBean.class);
- data.assertEquals(result);
- }
-
-
- // this one is here just for coverage
- public void testSimpleBeanFromDocument() throws Exception
- {
- SimpleBean data = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
-
- BeanConverter outConverter = new BeanConverter();
- BeanConverter inConverter = new BeanConverter();
-
- Document dom = outConverter.convertToXml(data, "test").getOwnerDocument();
-// System.out.println(OutputUtil.compactString(dom));
-
- SimpleBean result = inConverter.convertToJava(dom, SimpleBean.class);
- data.assertEquals(result);
- }
-}
\ No newline at end of file
Copied: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java (from rev 121, branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBeanConverter.java)
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java (rev 0)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java 2009-09-08 15:10:15 UTC (rev 123)
@@ -0,0 +1,428 @@
+// 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.math.BigDecimal;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import net.sf.practicalxml.DomUtil;
+import net.sf.practicalxml.OutputUtil;
+import net.sf.practicalxml.converter.BeanConverter;
+import net.sf.practicalxml.converter.ConversionException;
+import net.sf.practicalxml.converter.bean.AbstractBeanConverterTestCase;
+import net.sf.practicalxml.converter.bean.Bean2XmlOptions;
+import net.sf.practicalxml.converter.bean.Xml2BeanOptions;
+import net.sf.practicalxml.junit.DomAsserts;
+
+
+/**
+ * Tests for the top-level <code>BeanConverter</code> methods. These are all
+ * "out and back" tests to verify that we can read the XML that we produce
+ * (and to show cases where we can't). Detailed tests (verifying specific
+ * output) are in {@link TestBean2XmlDriver} and {@link TestXml2BeanDriver}.
+ * <p>
+ * Note that each conversion has a commented-out line that will print the
+ * generated XML. Uncommenting these lines may help you understand how
+ * conversion works in particular cases.
+ */
+public class TestBeanConverter
+extends AbstractBeanConverterTestCase
+{
+ public TestBeanConverter(String name)
+ {
+ super(name);
+ }
+
+
+//----------------------------------------------------------------------------
+// Support Code
+//----------------------------------------------------------------------------
+
+ private static void assertConversionFailure(
+ String message, BeanConverter converter, Element elem, Class<?> klass)
+ {
+ try
+ {
+ converter.convertToJava(elem, klass);
+ fail(message);
+ }
+ catch (ConversionException ee)
+ {
+// System.out.println(ee);
+ }
+ }
+
+//----------------------------------------------------------------------------
+// Test Cases
+//----------------------------------------------------------------------------
+
+ // an initial test to verify everything works
+ public void testConvertStringDefault() throws Exception
+ {
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ String obj = "this is a test";
+ Element root = outConverter.convertToXml(obj, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ assertEquals("test", DomUtil.getLocalName(root));
+
+ Object result = inConverter.convertToJava(root, String.class);
+ assertEquals(obj, result);
+ }
+
+
+ public void testConvertPrimitiveDefault() throws Exception
+ {
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ for (PrimitiveValue value : PRIMITIVE_VALUES)
+ {
+ Object obj = value.getValue();
+ Element root = outConverter.convertToXml(obj, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ Object result = inConverter.convertToJava(root, value.getKlass());
+ assertEquals(obj, result);
+ }
+ }
+
+
+ public void testConvertPrimitiveFormatXsd() throws Exception
+ {
+ BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.XSD_FORMAT);
+ BeanConverter inConverter = new BeanConverter(Xml2BeanOptions.EXPECT_XSD_FORMAT);
+
+ for (PrimitiveValue value : PRIMITIVE_VALUES)
+ {
+ Object obj = value.getValue();
+ Element root = outConverter.convertToXml(obj, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ Object result = inConverter.convertToJava(root, value.getKlass());
+ assertEquals(obj, result);
+ }
+ }
+
+
+ public void testConvertNullDefault() throws Exception
+ {
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(null, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ Object result = inConverter.convertToJava(root, String.class);
+ assertNull(result);
+ }
+
+
+ public void testConvertNullUseAndRequireXsiNil() throws Exception
+ {
+ BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.XSI_NIL);
+ BeanConverter inConverter = new BeanConverter(Xml2BeanOptions.REQUIRE_XSI_NIL);
+
+ Element root = outConverter.convertToXml(null, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ Object result = inConverter.convertToJava(root, String.class);
+ assertNull(result);
+ }
+
+
+ public void testConvertNullFailureRequireXsiNil() throws Exception
+ {
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter(Xml2BeanOptions.REQUIRE_XSI_NIL);
+
+ Element root = outConverter.convertToXml(null, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ assertConversionFailure("accepted DOM with null entry but no xsi:nil",
+ inConverter, root, String.class);
+ }
+
+
+ public void testPrimitiveArrayDefault() throws Exception
+ {
+ int[] data = new int[] { 1, 2, 4, 5 };
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ int[] result = inConverter.convertToJava(root, int[].class);
+ assertTrue(Arrays.equals(data, result));
+ }
+
+
+ public void testStringListDefault() throws Exception
+ {
+ List<String> data = Arrays.asList("foo", "bar", "baz");
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ List<String> result = inConverter.convertToJava(root, List.class);
+ assertEquals(data, result);
+ }
+
+
+ // demonstrates that the list will be read as List<String> even though
+ // it was written as List<Integer>
+ public void testIntegerListDefault() throws Exception
+ {
+ List<Integer> data = Arrays.asList(1, 2, 3);
+ assert(data.get(0) instanceof Integer);
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ List<?> result = inConverter.convertToJava(root, List.class);
+ assertTrue(result instanceof List);
+ assertTrue(result.get(0) instanceof String);
+ }
+
+
+ // demonstrates that you don't need to require xsi:type to use it
+ public void testIntegerListWithXsiType() throws Exception
+ {
+ List<Integer> data = Arrays.asList(1, 2, 3);
+ assert(data.get(0) instanceof Integer);
+
+ BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.ADD_XSI_TYPE);
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ List<?> result = inConverter.convertToJava(root, List.class);
+ assertEquals(data, result);
+ }
+
+
+ // demonstrates that the caller drives the inbound conversion
+ public void testConvertListToSortedSet() throws Exception
+ {
+ List<String> data = Arrays.asList("foo", "bar", "baz", "bar");
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ Set<?> result = inConverter.convertToJava(root, SortedSet.class);
+ Iterator<?> itx = result.iterator();
+ assertEquals("bar", itx.next());
+ assertEquals("baz", itx.next());
+ assertEquals("foo", itx.next());
+ assertFalse(itx.hasNext());
+ }
+
+
+ public void testMapDefault() throws Exception
+ {
+ Map<String,String> data = new HashMap<String,String>();
+ data.put("foo", "argle");
+ data.put("bar", "bargle");
+ data.put("baz", "bazgle");
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ DomAsserts.assertCount(3, root, "/test/data");
+ DomAsserts.assertCount(1, root, "/test/data[@key='foo']");
+ DomAsserts.assertEquals("argle", root, "/test/data[@key='foo']");
+
+ Map<?,?> result = inConverter.convertToJava(root, Map.class);
+ assertEquals(data, result);
+ }
+
+
+ // demonstrates that the input converter handles either format by default
+ public void testMapIntrospected() throws Exception
+ {
+ Map<String,String> data = new HashMap<String,String>();
+ data.put("foo", "argle");
+ data.put("bar", "bargle");
+ data.put("baz", "bazgle");
+
+ BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.INTROSPECT_MAPS);
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ DomAsserts.assertCount(0, root, "/test/data");
+ DomAsserts.assertCount(1, root, "/test/foo");
+ DomAsserts.assertEquals("argle", root, "/test/foo");
+
+ Map<?,?> result = inConverter.convertToJava(root, Map.class);
+ assertEquals(data, result);
+ }
+
+
+ public void testSimpleBeanDefault() throws Exception
+ {
+ SimpleBean data = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ SimpleBean result = inConverter.convertToJava(root, SimpleBean.class);
+ data.assertEquals(result);
+ }
+
+
+ public void testSimpleBeanRequireXsiType() throws Exception
+ {
+ SimpleBean data = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
+
+ BeanConverter outconverter1 = new BeanConverter(Bean2XmlOptions.ADD_XSI_TYPE);
+ BeanConverter outconverter2 = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter(Xml2BeanOptions.REQUIRE_XSI_TYPE);
+
+ Element valid = outconverter1.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(valid.getOwnerDocument()));
+
+ SimpleBean result = inConverter.convertToJava(valid, SimpleBean.class);
+ data.assertEquals(result);
+
+ Element invalid = outconverter2.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(invalid.getOwnerDocument()));
+
+ assertConversionFailure("converter requiring xsi:type accepted XML without",
+ inConverter, invalid, SimpleBean.class);
+ }
+
+
+ public void testListOfSimpleBeanWithXsiTypeAndNulls() throws Exception
+ {
+ SimpleBean bean1 = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
+ SimpleBean bean2 = new SimpleBean("zyx", 987, null, false);
+ List<SimpleBean> data = Arrays.asList(bean1, bean2);
+
+ BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.ADD_XSI_TYPE);
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ List<SimpleBean> result = inConverter.convertToJava(root, List.class);
+ assertEquals(2, result.size());
+ bean1.assertEquals(result.get(0));
+ bean2.assertEquals(result.get(1));
+ }
+
+
+ // another demonstration that caller drives input conversion
+ // ... and note that we don't care about xsi:type in this case
+ public void testListOfSimpleBeanToArrayOfSame() throws Exception
+ {
+ SimpleBean bean1 = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
+ SimpleBean bean2 = new SimpleBean("zyx", 987, null, false);
+ List<SimpleBean> data = Arrays.asList(bean1, bean2);
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ SimpleBean[] result = inConverter.convertToJava(root, SimpleBean[].class);
+ assertEquals(2, result.length);
+ bean1.assertEquals(result[0]);
+ bean2.assertEquals(result[1]);
+ }
+
+
+ public void testCompoundBeanDefault() throws Exception
+ {
+ CompoundBean data = new CompoundBean(
+ new SimpleBean("abc", 123, new BigDecimal("456.789"), true),
+ new int[] { 1, 5, 7, 9 },
+ Arrays.asList("foo", "bar", "baz"));
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ CompoundBean result = inConverter.convertToJava(root, CompoundBean.class);
+ data.assertEquals(result);
+ }
+
+
+ public void testSimpleBeanWithNamespace() throws Exception
+ {
+ SimpleBean data = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "urn:foo", "bar:test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ Element child = DomUtil.getChild(root, "sval");
+ assertEquals("urn:foo", child.getNamespaceURI());
+ assertEquals("bar", child.getPrefix());
+
+ SimpleBean result = inConverter.convertToJava(root, SimpleBean.class);
+ data.assertEquals(result);
+ }
+
+
+ // this one is here just for coverage
+ public void testSimpleBeanFromDocument() throws Exception
+ {
+ SimpleBean data = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Document dom = outConverter.convertToXml(data, "test").getOwnerDocument();
+// System.out.println(OutputUtil.compactString(dom));
+
+ SimpleBean result = inConverter.convertToJava(dom, SimpleBean.class);
+ data.assertEquals(result);
+ }
+}
\ No newline at end of file
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-08 14:55:40
|
Revision: 122
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=122&view=rev
Author: kdgregory
Date: 2009-09-08 14:55:08 +0000 (Tue, 08 Sep 2009)
Log Message:
-----------
introduce AbstractConversionTestCase
Modified Paths:
--------------
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/AbstractBeanConverterTestCase.java
Added Paths:
-----------
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractConversionTestCase.java
Added: 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 (rev 0)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractConversionTestCase.java 2009-09-08 14:55:08 UTC (rev 122)
@@ -0,0 +1,39 @@
+// 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 net.sf.practicalxml.AbstractTestCase;
+
+
+/**
+ * A place to put common code for the conversion tests.
+ */
+public class AbstractConversionTestCase
+extends AbstractTestCase
+{
+ public AbstractConversionTestCase(String testName)
+ {
+ super(testName);
+ }
+
+//----------------------------------------------------------------------------
+// Support Code
+//----------------------------------------------------------------------------
+
+
+//----------------------------------------------------------------------------
+// Assertions
+//----------------------------------------------------------------------------
+}
Property changes on: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractConversionTestCase.java
___________________________________________________________________
Added: svn:executable
+ *
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-08 14:43:34 UTC (rev 121)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/AbstractBeanConverterTestCase.java 2009-09-08 14:55:08 UTC (rev 122)
@@ -26,8 +26,8 @@
import junit.framework.Assert;
-import net.sf.practicalxml.AbstractTestCase;
import net.sf.practicalxml.DomUtil;
+import net.sf.practicalxml.converter.AbstractConversionTestCase;
/**
@@ -36,7 +36,7 @@
* instrospected.
*/
public abstract class AbstractBeanConverterTestCase
-extends AbstractTestCase
+extends AbstractConversionTestCase
{
protected AbstractBeanConverterTestCase(String name)
{
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-08-18 20:25:55
|
Revision: 120
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=120&view=rev
Author: kdgregory
Date: 2009-08-18 20:25:47 +0000 (Tue, 18 Aug 2009)
Log Message:
-----------
refactoring - introduce ConversionStrings
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/Bean2XmlDriver.java
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/internal/DomUtilToo.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanDriver.java
Added Paths:
-----------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionStrings.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-08-18 19:54:24 UTC (rev 119)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java 2009-08-18 20:25:47 UTC (rev 120)
@@ -19,6 +19,7 @@
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;
@@ -168,7 +169,7 @@
{
Element child = super.appendValue(name, type, value);
if (child != null)
- child.setAttribute("index", String.valueOf(_index++));
+ child.setAttribute(ConversionStrings.AT_ARRAY_INDEX, String.valueOf(_index++));
return child;
}
}
@@ -198,9 +199,9 @@
}
else
{
- child = super.appendValue("data", type, value);
+ child = super.appendValue(ConversionStrings.EL_COLLECTION_ITEM, type, value);
if (child != null)
- child.setAttribute("key", name);
+ child.setAttribute(ConversionStrings.AT_MAP_KEY, name);
}
return child;
}
Modified: 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-08-18 19:54:24 UTC (rev 119)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlDriver.java 2009-08-18 20:25:47 UTC (rev 120)
@@ -29,6 +29,7 @@
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;
@@ -117,12 +118,6 @@
}
- private String getJavaXsiType(Object obj)
- {
- return "java:" + obj.getClass().getName();
- }
-
-
/**
* Introduces the XML Schema Instance namespace into the DOM tree using a
* meaningless attribute. The Xerces serializer does not attempt to promote
@@ -171,13 +166,13 @@
if (!array.getClass().isArray())
return false;
- Element parent = appender.appendContainer(name, getJavaXsiType(array));
+ 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, "data", childAppender);
+ convert(value, ConversionStrings.EL_COLLECTION_ITEM, childAppender);
}
return true;
}
@@ -188,7 +183,7 @@
if (!(obj instanceof Map))
return false;
- Element parent = appender.appendContainer(name, getJavaXsiType(obj));
+ Element parent = appender.appendContainer(name, DomUtilToo.getXsiTypeForJavaObject(obj));
Appender childAppender = new MapAppender(parent, _options);
for (Map.Entry<?,?> entry : ((Map<?,?>)obj).entrySet())
{
@@ -203,11 +198,11 @@
if (!(obj instanceof Collection))
return false;
- Element parent = appender.appendContainer(name, getJavaXsiType(obj));
+ Element parent = appender.appendContainer(name, DomUtilToo.getXsiTypeForJavaObject(obj));
Appender childAppender = new IndexedAppender(parent, _options);
for (Object value : (Collection<?>)obj)
{
- convert(value, "data", childAppender);
+ convert(value, ConversionStrings.EL_COLLECTION_ITEM, childAppender);
}
return true;
}
@@ -215,7 +210,7 @@
private boolean tryToConvertAsBean(Object bean, String name, Appender appender)
{
- Element parent = appender.appendContainer(name, getJavaXsiType(bean));
+ Element parent = appender.appendContainer(name, DomUtilToo.getXsiTypeForJavaObject(bean));
Appender childAppender = new BasicAppender(parent, _options);
try
{
Modified: 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-08-18 19:54:24 UTC (rev 119)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanDriver.java 2009-08-18 20:25:47 UTC (rev 120)
@@ -35,6 +35,7 @@
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;
@@ -84,8 +85,6 @@
// 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,
@@ -184,7 +183,7 @@
List<Element> children = DomUtil.getChildren(elem);
for (Element child : children)
{
- String key = child.getAttribute("key");
+ String key = child.getAttribute(ConversionStrings.AT_MAP_KEY);
if (StringUtils.isEmpty(key))
key = DomUtil.getLocalName(child);
Class<?> childClass = getClassFromXsiType(child);
@@ -244,9 +243,9 @@
if (xsiType == null)
return null;
- if (xsiType.startsWith("java:"))
+ String javaType = DomUtilToo.getJavaClassFromXsiType(xsiType);
+ if (javaType != null)
{
- String javaType = xsiType.substring(5);
try
{
return Class.forName(javaType);
@@ -257,6 +256,7 @@
"invalid Java type specification: " + javaType, elem, ee);
}
}
+
return _helper.getJavaType(xsiType);
}
Added: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionStrings.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionStrings.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionStrings.java 2009-08-18 20:25:47 UTC (rev 120)
@@ -0,0 +1,47 @@
+// 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.internal;
+
+
+/**
+ * Contains constants for various string values used by the conversion
+ * routines. The goal is to have all converters use the same strings
+ * (without typos) in the same location.
+ */
+public class ConversionStrings
+{
+ /**
+ * Element name used to hold unnamed items from collections and arrays.
+ */
+ public final static String EL_COLLECTION_ITEM = "data";
+
+
+ /**
+ * Attribute used to hold the element index number for collections and arrays.
+ */
+ public final static String AT_ARRAY_INDEX = "index";
+
+
+ /**
+ * Attribute used to hold the item key value for maps.
+ */
+ public final static String AT_MAP_KEY = "key";
+
+
+ /**
+ * Used to prefix Java type names in an <code>xsi:type</code> attribute.
+ */
+ public final static String JAVA_TYPE_PREFIX = "java:";
+}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/DomUtilToo.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/DomUtilToo.java 2009-08-18 19:54:24 UTC (rev 119)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/DomUtilToo.java 2009-08-18 20:25:47 UTC (rev 120)
@@ -27,7 +27,7 @@
* are not generally useful to anyone who isn't writing a converter. But if you
* are writing a converter, you'll probably use them a lot ...
* <p>
- * Note: where methods in this class reference a namespaced element or attribute
+ * Note: where methods in this class reference a namespaced element or attribute
* (eg, <code>xsi:type</code>), they do not use a prefix unless explicitly noted.
* This prevents the possibility of collisions, where the same prefix is used
* elsewhere in the DOM for elements not managed by the converter. A serializer
@@ -36,44 +36,80 @@
public class DomUtilToo
{
/**
+ * Sets the <code>xsi:nil</code> attribute to the passed value.
+ */
+ public static void setXsiNil(Element elem, boolean isNil)
+ {
+ String value = isNil ? "true" : "false";
+ elem.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil", value);
+ }
+
+
+ /**
+ * Returns the value of the <code>xsi:nil</code> attribute on the passed
+ * element, <code>false</code> if the attribute is not set.
+ */
+ public static boolean getXsiNil(Element elem)
+ {
+ String attr = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil");
+ return attr.equals("true");
+ }
+
+
+ /**
* Sets the <code>xsi:type</code> attribute to the passed value.
*/
public static void setXsiType(Element elem, String xsiType)
{
elem.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type", xsiType);
}
-
-
+
+
/**
* Returns the value of the <code>xsi:type</code> attribute on the passed
* element, <code>null</code> if the attribute is not set.
*/
public static String getXsiType(Element elem)
- {
+ {
String xsiType = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
return StringUtils.isEmpty(xsiType)
? null
: xsiType;
}
-
-
+
+
/**
- * Sets the <code>xsi:nil</code> attribute to the passed value.
+ * Returns the Java classname corresponding to an <code>xsi:type</code>
+ * value, <code>null</code> if the attribute is missing or doesn't follow
+ * the pattern for Java type names.
*/
- public static void setXsiNil(Element elem, boolean isNil)
+ public static String getJavaClassFromXsiType(String xsiType)
{
- String value = isNil ? "true" : "false";
- elem.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil", value);
+ if (!xsiType.startsWith(ConversionStrings.JAVA_TYPE_PREFIX))
+ return null;
+ return xsiType.substring(ConversionStrings.JAVA_TYPE_PREFIX.length());
}
-
-
+
+
/**
- * Returns the value of the <code>xsi:nil</code> attribute on the passed
- * element, <code>false</code> if the attribute is not set.
+ * Returns the type name to be stored in <code>xsi:type</code> for a Java
+ * class (this is a companion to {@link #getJavaClassFromXsiType}).
*/
- public static boolean getXsiNil(Element elem)
+ public static String getXsiTypeForJavaObject(Class<?> klass)
{
- String attr = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil");
- return attr.equals("true");
+ return ConversionStrings.JAVA_TYPE_PREFIX + klass.getName();
}
+
+
+ /**
+ * Returns the type name to be stored in <code>xsi:type</code> for a Java
+ * object (this is actually used more than the alternate version). Will
+ * return empty string if passed <code>null</code>.
+ */
+ public static String getXsiTypeForJavaObject(Object obj)
+ {
+ return (obj == null)
+ ? ""
+ : getXsiTypeForJavaObject(obj.getClass());
+ }
}
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanDriver.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanDriver.java 2009-08-18 19:54:24 UTC (rev 119)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanDriver.java 2009-08-18 20:25:47 UTC (rev 120)
@@ -700,10 +700,9 @@
public void testReadOnlyBean() throws Exception
{
- Xml2BeanDriver driver = new Xml2BeanDriver();
Element data = createTestData(
element("sval", text("foo")));
-
+ Xml2BeanDriver driver = new Xml2BeanDriver();
assertConversionFailure("converted bean without setter",
driver, data, ReadOnlyBean.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-08-18 19:54:39
|
Revision: 119
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=119&view=rev
Author: kdgregory
Date: 2009-08-18 19:54:24 +0000 (Tue, 18 Aug 2009)
Log Message:
-----------
remove unused file
Removed Paths:
-------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java
Deleted: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java 2009-08-18 19:50:39 UTC (rev 118)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java 2009-08-18 19:54:24 UTC (rev 119)
@@ -1,190 +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.util.Date;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.xml.XMLConstants;
-
-import org.w3c.dom.Element;
-
-import net.sf.practicalxml.DomUtil;
-import net.sf.practicalxml.converter.ConversionException;
-import net.sf.practicalxml.converter.internal.PrimitiveConversionHelper;
-import net.sf.practicalxml.internal.StringUtils;
-
-
-/**
- * Invoked by {@link Xml2BeanDriver} to convert a DOM <code>Element</code>
- * into the appropriate Java object. Unlike {@link Bean2XmlHandler}, there
- * will only be one instance of this object created during conversion; all
- * intermediate data can be held on the stack.
- */
-public class Xml2BeanHandler
-{
- private EnumSet<Xml2BeanOptions> _options;
- private PrimitiveConversionHelper _primitiveHelper;
-
-
- /**
- * Public constructor, allowing various options specifications.
- */
- public Xml2BeanHandler(Xml2BeanOptions... options)
- {
- _options = EnumSet.noneOf(Xml2BeanOptions.class);
- for (Xml2BeanOptions option : options)
- _options.add(option);
-
- _primitiveHelper = new PrimitiveConversionHelper(true);
- }
-
-
-//----------------------------------------------------------------------------
-// Public Methods
-//----------------------------------------------------------------------------
-
- public Boolean convertBoolean(Element elem)
- {
- return (Boolean)_primitiveHelper.parse(getText(elem), Boolean.class);
- }
-
-
- public Byte convertByte(Element elem)
- {
- return (Byte)_primitiveHelper.parse(getText(elem), Byte.class);
- }
-
-
- public Character convertCharacter(Element elem)
- {
- return (Character)_primitiveHelper.parse(getText(elem), Character.class);
- }
-
-
- public Date convertDate(Element elem)
- {
- throw new UnsupportedOperationException("not implemented yet");
- }
-
-
- public Double convertDouble(Element elem)
- {
- return (Double)_primitiveHelper.parse(getText(elem), Double.class);
- }
-
-
- public Float convertFloat(Element elem)
- {
- return (Float)_primitiveHelper.parse(getText(elem), Float.class);
- }
-
-
- public Integer convertInteger(Element elem)
- {
- return (Integer)_primitiveHelper.parse(getText(elem), Integer.class);
- }
-
-
- public Long convertLong(Element elem)
- {
- return (Long)_primitiveHelper.parse(getText(elem), Long.class);
- }
-
-
- public Number convertNumber(Element elem)
- {
- throw new UnsupportedOperationException("not implemented yet");
- }
-
-
- public Short convertShort(Element elem)
- {
- return (Short)_primitiveHelper.parse(getText(elem), Short.class);
- }
-
-
- public String convertString(Element elem)
- {
- return (String)_primitiveHelper.parse(getText(elem), String.class);
- }
-
-
- public List<?> convertList(Element elem)
- {
- throw new UnsupportedOperationException("not implemented yet");
- }
-
-
- public Set<?> convertSet(Element elem)
- {
- throw new UnsupportedOperationException("not implemented yet");
- }
-
-
- public Map<?,?> convertMap(Element elem)
- {
- throw new UnsupportedOperationException("not implemented yet");
- }
-
-
- public Object convertObject(Element elem)
- {
- throw new UnsupportedOperationException("not implemented yet");
- }
-
-
- public Object[] convertObjectArray(Element elem)
- {
- throw new UnsupportedOperationException("not implemented yet");
- }
-
-
-//----------------------------------------------------------------------------
-// Internals
-//----------------------------------------------------------------------------
-
- /**
- * Returns the text from a passed element, applying any low-level options
- * along the way.
- */
- private String getText(Element elem)
- {
- String text = DomUtil.getText(elem);
- if (_options.contains(Xml2BeanOptions.CONVERT_BLANK_AS_NULL) && StringUtils.isBlank(text))
- text = null;
- validateXsiNil(elem, text);
- return text;
- }
-
-
- /**
- * Checks for elements that require <code>xsi:nil</code>, and throws if missing.
- */
- private void validateXsiNil(Element elem, String text)
- {
- if (text != null)
- return;
- if (!_options.contains(Xml2BeanOptions.REQUIRE_XSI_NIL))
- return;
-
- String attr = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil");
- if ((attr == null) || !attr.equals("true"))
- throw new ConversionException("empty element without required xsi:nil");
- }
-
-}
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-08-18 19:50:47
|
Revision: 118
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=118&view=rev
Author: kdgregory
Date: 2009-08-18 19:50:39 +0000 (Tue, 18 Aug 2009)
Log Message:
-----------
refactoring
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/Bean2XmlDriver.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanDriver.java
Added Paths:
-----------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/DomUtilToo.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-08-18 19:16:50 UTC (rev 117)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java 2009-08-18 19:50:39 UTC (rev 118)
@@ -15,13 +15,11 @@
package net.sf.practicalxml.converter.bean;
import java.util.EnumSet;
-
-import javax.xml.XMLConstants;
-
import org.w3c.dom.Element;
import net.sf.practicalxml.DomUtil;
import net.sf.practicalxml.converter.ConversionException;
+import net.sf.practicalxml.converter.internal.DomUtilToo;
/**
@@ -95,7 +93,7 @@
protected void setType(Element elem, String type)
{
if (isOptionSet(Bean2XmlOptions.ADD_XSI_TYPE))
- elem.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type", type);
+ DomUtilToo.setXsiType(elem, type);
}
protected void setValue(Element elem, String value)
@@ -103,7 +101,7 @@
if (value != null)
DomUtil.setText(elem, value);
else if (isOptionSet(Bean2XmlOptions.XSI_NIL))
- elem.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil", "true");
+ DomUtilToo.setXsiNil(elem, true);
}
}
Modified: 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-08-18 19:16:50 UTC (rev 117)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlDriver.java 2009-08-18 19:50:39 UTC (rev 118)
@@ -24,13 +24,12 @@
import java.util.EnumSet;
import java.util.Map;
-import javax.xml.XMLConstants;
-
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.DomUtilToo;
import net.sf.practicalxml.converter.internal.PrimitiveConversionHelper;
@@ -145,7 +144,7 @@
if (_options.contains(Bean2XmlOptions.XSI_NIL)
&& !_options.contains(Bean2XmlOptions.ADD_XSI_TYPE))
{
- root.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil", "false");
+ DomUtilToo.setXsiNil(root, false);
}
}
Modified: 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-08-18 19:16:50 UTC (rev 117)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanDriver.java 2009-08-18 19:50:39 UTC (rev 118)
@@ -33,10 +33,9 @@
import java.util.TreeMap;
import java.util.TreeSet;
-import javax.xml.XMLConstants;
-
import net.sf.practicalxml.DomUtil;
import net.sf.practicalxml.converter.ConversionException;
+import net.sf.practicalxml.converter.internal.DomUtilToo;
import net.sf.practicalxml.converter.internal.PrimitiveConversionHelper;
import net.sf.practicalxml.internal.StringUtils;
@@ -121,9 +120,8 @@
if (_options.contains(Xml2BeanOptions.REQUIRE_XSI_NIL))
{
- String attr = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil");
- if (!attr.equals("true"))
- throw new ConversionException("missing xsi:nil", elem);
+ if (!DomUtilToo.getXsiNil(elem))
+ throw new ConversionException("missing/false xsi:nil", elem);
}
return true;
@@ -235,19 +233,6 @@
/**
- * Returns the <code>xsi:type</code> attribute value, <code>null</code> if
- * it's not set.
- */
- private String getXsiType(Element elem)
- {
- String xsiType = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
- return StringUtils.isEmpty(xsiType)
- ? null
- : xsiType;
- }
-
-
- /**
* 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
@@ -255,7 +240,7 @@
*/
private Class<?> getClassFromXsiType(Element elem)
{
- String xsiType = getXsiType(elem);
+ String xsiType = DomUtilToo.getXsiType(elem);
if (xsiType == null)
return null;
@@ -281,8 +266,8 @@
if (!_options.contains(Xml2BeanOptions.REQUIRE_XSI_TYPE))
return;
- String xsiType = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
- if (StringUtils.isEmpty(xsiType))
+ String xsiType = DomUtilToo.getXsiType(elem);
+ if (xsiType == null)
throw new ConversionException("missing xsi:type", elem);
if (xsiType.equals(_helper.getXsdType(klass)))
Added: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/DomUtilToo.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/DomUtilToo.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/DomUtilToo.java 2009-08-18 19:50:39 UTC (rev 118)
@@ -0,0 +1,79 @@
+// 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.internal;
+
+import javax.xml.XMLConstants;
+
+import org.w3c.dom.Element;
+
+import net.sf.practicalxml.internal.StringUtils;
+
+
+/**
+ * Contains static utility methods and constants used by the conversion routines.
+ * These are way too specific to go into the top-level <code>DomUtil</code>, and
+ * are not generally useful to anyone who isn't writing a converter. But if you
+ * are writing a converter, you'll probably use them a lot ...
+ * <p>
+ * Note: where methods in this class reference a namespaced element or attribute
+ * (eg, <code>xsi:type</code>), they do not use a prefix unless explicitly noted.
+ * This prevents the possibility of collisions, where the same prefix is used
+ * elsewhere in the DOM for elements not managed by the converter. A serializer
+ * will pick an appropriate prefix for output.
+ */
+public class DomUtilToo
+{
+ /**
+ * Sets the <code>xsi:type</code> attribute to the passed value.
+ */
+ public static void setXsiType(Element elem, String xsiType)
+ {
+ elem.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type", xsiType);
+ }
+
+
+ /**
+ * Returns the value of the <code>xsi:type</code> attribute on the passed
+ * element, <code>null</code> if the attribute is not set.
+ */
+ public static String getXsiType(Element elem)
+ {
+ String xsiType = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
+ return StringUtils.isEmpty(xsiType)
+ ? null
+ : xsiType;
+ }
+
+
+ /**
+ * Sets the <code>xsi:nil</code> attribute to the passed value.
+ */
+ public static void setXsiNil(Element elem, boolean isNil)
+ {
+ String value = isNil ? "true" : "false";
+ elem.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil", value);
+ }
+
+
+ /**
+ * Returns the value of the <code>xsi:nil</code> attribute on the passed
+ * element, <code>false</code> if the attribute is not set.
+ */
+ public static boolean getXsiNil(Element elem)
+ {
+ String attr = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil");
+ return attr.equals("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-08-18 19:16:56
|
Revision: 117
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=117&view=rev
Author: kdgregory
Date: 2009-08-18 19:16:50 +0000 (Tue, 18 Aug 2009)
Log Message:
-----------
another class rename: ConversionHelper back to PrimitiveConversionHelper
Modified 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/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestConversionHelper.java
Added Paths:
-----------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/PrimitiveConversionHelper.java
Removed Paths:
-------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionHelper.java
Modified: 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-08-18 18:52:26 UTC (rev 116)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlDriver.java 2009-08-18 19:16:50 UTC (rev 117)
@@ -31,7 +31,7 @@
import net.sf.practicalxml.DomUtil;
import net.sf.practicalxml.converter.ConversionException;
import net.sf.practicalxml.converter.bean.Bean2XmlAppenders.*;
-import net.sf.practicalxml.converter.internal.ConversionHelper;
+import net.sf.practicalxml.converter.internal.PrimitiveConversionHelper;
/**
@@ -41,14 +41,14 @@
*/
public class Bean2XmlDriver
{
- private ConversionHelper _helper;
+ private PrimitiveConversionHelper _helper;
private EnumSet<Bean2XmlOptions> _options = EnumSet.noneOf(Bean2XmlOptions.class);
public Bean2XmlDriver(Bean2XmlOptions... options)
{
for (Bean2XmlOptions option : options)
_options.add(option);
- _helper = new ConversionHelper(shouldUseXsdFormatting());
+ _helper = new PrimitiveConversionHelper(shouldUseXsdFormatting());
}
Modified: 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-08-18 18:52:26 UTC (rev 116)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanDriver.java 2009-08-18 19:16:50 UTC (rev 117)
@@ -37,7 +37,7 @@
import net.sf.practicalxml.DomUtil;
import net.sf.practicalxml.converter.ConversionException;
-import net.sf.practicalxml.converter.internal.ConversionHelper;
+import net.sf.practicalxml.converter.internal.PrimitiveConversionHelper;
import net.sf.practicalxml.internal.StringUtils;
import org.w3c.dom.Element;
@@ -52,7 +52,7 @@
public class Xml2BeanDriver
{
private EnumSet<Xml2BeanOptions> _options;
- private ConversionHelper _helper;
+ private PrimitiveConversionHelper _helper;
private Map<Class<?>,Map<String,Method>> _introspectedClasses;
@@ -62,7 +62,7 @@
for (Xml2BeanOptions option : options)
_options.add(option);
- _helper = new ConversionHelper(_options.contains(Xml2BeanOptions.EXPECT_XSD_FORMAT));
+ _helper = new PrimitiveConversionHelper(_options.contains(Xml2BeanOptions.EXPECT_XSD_FORMAT));
_introspectedClasses = new HashMap<Class<?>,Map<String,Method>>();
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java 2009-08-18 18:52:26 UTC (rev 116)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java 2009-08-18 19:16:50 UTC (rev 117)
@@ -25,7 +25,7 @@
import net.sf.practicalxml.DomUtil;
import net.sf.practicalxml.converter.ConversionException;
-import net.sf.practicalxml.converter.internal.ConversionHelper;
+import net.sf.practicalxml.converter.internal.PrimitiveConversionHelper;
import net.sf.practicalxml.internal.StringUtils;
@@ -38,7 +38,7 @@
public class Xml2BeanHandler
{
private EnumSet<Xml2BeanOptions> _options;
- private ConversionHelper _primitiveHelper;
+ private PrimitiveConversionHelper _primitiveHelper;
/**
@@ -50,7 +50,7 @@
for (Xml2BeanOptions option : options)
_options.add(option);
- _primitiveHelper = new ConversionHelper(true);
+ _primitiveHelper = new PrimitiveConversionHelper(true);
}
Deleted: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionHelper.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionHelper.java 2009-08-18 18:52:26 UTC (rev 116)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionHelper.java 2009-08-18 19:16:50 UTC (rev 117)
@@ -1,480 +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.internal;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-import net.sf.practicalxml.XmlUtil;
-import net.sf.practicalxml.converter.ConversionException;
-
-
-/**
- * Responsible for converting "primitive" types -- those with unambiguous
- * string representations -- to/from such a representation.
- */
-public class ConversionHelper
-{
- private static Map<String,Class<?>> XSD_TYPE_TO_JAVA_CLASS
- = new HashMap<String,Class<?>>();
- static
- {
- XSD_TYPE_TO_JAVA_CLASS.put("xsd:string", String.class);
- XSD_TYPE_TO_JAVA_CLASS.put("xsd:boolean", Boolean.class);
- XSD_TYPE_TO_JAVA_CLASS.put("xsd:byte", Byte.class);
- XSD_TYPE_TO_JAVA_CLASS.put("xsd:short", Short.class);
- XSD_TYPE_TO_JAVA_CLASS.put("xsd:int", Integer.class);
- XSD_TYPE_TO_JAVA_CLASS.put("xsd:long", Long.class);
- XSD_TYPE_TO_JAVA_CLASS.put("xsd:decimal", BigDecimal.class);
- XSD_TYPE_TO_JAVA_CLASS.put("xsd:dateTime", Date.class);
- }
-
-
- // this is not static because the helpers are inner classes
- private Map<Class<?>,ConversionHandler<?>> _helpers
- = new HashMap<Class<?>,ConversionHandler<?>>();
- {
- _helpers.put(String.class, new StringConversionHandler());
- _helpers.put(Character.class, new CharacterConversionHandler());
- _helpers.put(Boolean.class, new BooleanConversionHandler());
- _helpers.put(Byte.class, new ByteConversionHandler());
- _helpers.put(Short.class, new ShortConversionHandler());
- _helpers.put(Integer.class, new IntegerConversionHandler());
- _helpers.put(Long.class, new LongConversionHandler());
- _helpers.put(Float.class, new FloatConversionHandler());
- _helpers.put(Double.class, new DoubleConversionHandler());
- _helpers.put(BigInteger.class, new BigIntegerConversionHandler());
- _helpers.put(BigDecimal.class, new BigDecimalConversionHandler());
- _helpers.put(Date.class, new DateConversionHandler());
-
- _helpers.put(Boolean.TYPE, new BooleanConversionHandler());
- _helpers.put(Byte.TYPE, new ByteConversionHandler());
- _helpers.put(Short.TYPE, new ShortConversionHandler());
- _helpers.put(Integer.TYPE, new IntegerConversionHandler());
- _helpers.put(Long.TYPE, new LongConversionHandler());
- _helpers.put(Float.TYPE, new FloatConversionHandler());
- _helpers.put(Double.TYPE, new DoubleConversionHandler());
- }
-
- private boolean _useXsdFormatting;
-
-
- /**
- * Default constructor, which uses Java formatting.
- */
- public ConversionHelper()
- {
- // nothing to see here
- }
-
-
- /**
- * Constructor that allows selection of Java or XSD formatting.
- */
- public ConversionHelper(boolean useXsdFormatting)
- {
- _useXsdFormatting = useXsdFormatting;
- }
-
-
-//----------------------------------------------------------------------------
-// Public Methods
-//----------------------------------------------------------------------------
-
- /**
- * Returns the XSD type name to use for stringified objects of the
- * specified class, <code>null</code> if this converter can't convert
- * instances of the class.
- */
- public String getXsdType(Class<?> klass)
- {
- ConversionHandler<?> helper = _helpers.get(klass);
- return (helper == null) ? null : helper.getXsiType();
- }
-
-
- /**
- * Returns the Java type that best matches the given Schema type name,
- * <code>null</code> if we do not have an appropriate mapping.
- */
- public Class<?> getJavaType(String xsdTypename)
- {
- return XSD_TYPE_TO_JAVA_CLASS.get(xsdTypename);
- }
-
-
- /**
- * Converts the passed object into its string representation, according
- * to the options currently in effect. Passing <code>null</code> will
- * return <code>null</code>. Throws {@link ConversionException} if
- * unable to convert the passed object.
- */
- public String stringify(Object obj)
- {
- if (obj == null)
- return null;
-
- try
- {
- return getHelper(obj.getClass()).stringify(obj);
- }
- catch (Exception ee)
- {
- if (ee instanceof ConversionException)
- throw (ConversionException)ee;
- throw new ConversionException("unable to convert: " + obj, ee);
- }
- }
-
-
- /**
- * Parses the passed string into an object of the desired class. Passing
- * <code>null</code> will return <code>null</code>, passing an empty
- * string will typically throw a {@link ConversionException}.
- */
- public Object parse(String str, Class<?> klass)
- {
- if (str == null)
- return null;
-
- try
- {
- return getHelper(klass).parse(str);
- }
- catch (Exception ee)
- {
- if (ee instanceof ConversionException)
- throw (ConversionException)ee;
- throw new ConversionException("unable to parse: " + str, ee);
- }
- }
-
-
-//----------------------------------------------------------------------------
-// Internals
-//----------------------------------------------------------------------------
-
- /**
- * Returns the appropriate conversion helper or throws.
- */
- @SuppressWarnings(value="unchecked")
- private ConversionHandler getHelper(Class<?> klass)
- {
- ConversionHandler<?> helper = _helpers.get(klass);
- if (helper == null)
- throw new ConversionException("unable to get helper: " + klass.getName());
- return helper;
- }
-
-
- /**
- * Each primitive class has its own conversion handler that is responsible
- * for converting to/from a string representation. Handlers are guaranteed
- * to receive non-null objects/strings.
- * <p>
- * This interface is parameterized so that the compiler will generate
- * bridge methods for implementation classes. Elsewhere, we don't care
- * about parameterization, so wildcard or drop it (see {@link #getHelper}).
- * <p>
- * Implementation classes are expected to be inner classes, so that they
- * have access to configuration information (such as formatting rules).
- * <p>
- * Implementation classes are permitted to throw any exception; caller is
- * expected to catch them and translate to a {@link ConversionException}.
- */
- private static interface ConversionHandler<T>
- {
- public String getXsiType();
- public String stringify(T obj) throws Exception;
- public T parse(String str) throws Exception;
- }
-
-
- private class StringConversionHandler
- implements ConversionHandler<String>
- {
- public String getXsiType()
- {
- return "xsd:string";
- }
-
- public String stringify(String obj)
- {
- return String.valueOf(obj);
- }
-
- public String parse(String str)
- {
- return str;
- }
- }
-
-
- private class CharacterConversionHandler
- implements ConversionHandler<Character>
- {
- private final Character NUL = Character.valueOf('\0');
-
- public String getXsiType()
- {
- return "xsd:string";
- }
-
- public String stringify(Character obj)
- {
- if (obj.equals(NUL))
- return "";
- return obj.toString();
- }
-
- public Character parse(String str)
- {
- if (str.length() == 0)
- return NUL;
- if (str.length() > 1)
- throw new ConversionException(
- "attempted to convert multi-character string: \"" + str + "\"");
- return Character.valueOf(str.charAt(0));
- }
- }
-
-
- private class BooleanConversionHandler
- implements ConversionHandler<Boolean>
- {
- public String getXsiType()
- {
- return "xsd:boolean";
- }
-
- public String stringify(Boolean obj)
- {
- return _useXsdFormatting
- ? XmlUtil.formatXsdBoolean(obj.booleanValue())
- : obj.toString();
- }
-
- public Boolean parse(String str)
- {
- return _useXsdFormatting
- ? XmlUtil.parseXsdBoolean(str)
- : Boolean.parseBoolean(str);
- }
- }
-
-
- private class ByteConversionHandler
- implements ConversionHandler<Byte>
- {
- public String getXsiType()
- {
- return "xsd:byte";
- }
-
- public String stringify(Byte obj)
- {
- return obj.toString();
- }
-
- public Byte parse(String str)
- {
- return Byte.valueOf(str.trim());
- }
- }
-
-
- private class ShortConversionHandler
- implements ConversionHandler<Short>
- {
- public String getXsiType()
- {
- return "xsd:short";
- }
-
- public String stringify(Short obj)
- {
- return obj.toString();
- }
-
- public Short parse(String str)
- {
- return Short.valueOf(str.trim());
- }
- }
-
-
- private class IntegerConversionHandler
- implements ConversionHandler<Integer>
- {
- public String getXsiType()
- {
- return "xsd:int";
- }
-
- public String stringify(Integer obj)
- {
- return obj.toString();
- }
-
- public Integer parse(String str)
- {
- return Integer.valueOf(str.trim());
- }
- }
-
-
- private class LongConversionHandler
- implements ConversionHandler<Long>
- {
- public String getXsiType()
- {
- return "xsd:long";
- }
-
- public String stringify(Long obj)
- {
- return obj.toString();
- }
-
- public Long parse(String str)
- {
- return Long.valueOf(str.trim());
- }
- }
-
-
- private class FloatConversionHandler
- implements ConversionHandler<Float>
- {
- public String getXsiType()
- {
- return "xsd:decimal";
- }
-
- public String stringify(Float obj)
- {
- return _useXsdFormatting
- ? XmlUtil.formatXsdDecimal(obj)
- : obj.toString();
- }
-
- public Float parse(String str)
- {
- return Float.valueOf(str.trim());
- }
- }
-
-
- private class DoubleConversionHandler
- implements ConversionHandler<Double>
- {
- public String getXsiType()
- {
- return "xsd:decimal";
- }
-
- public String stringify(Double obj)
- {
- return _useXsdFormatting
- ? XmlUtil.formatXsdDecimal(obj)
- : obj.toString();
- }
-
- public Double parse(String str)
- {
- return Double.valueOf(str.trim());
- }
- }
-
-
- private class BigIntegerConversionHandler
- implements ConversionHandler<BigInteger>
- {
- public String getXsiType()
- {
- return "xsd:decimal";
- }
-
- public String stringify(BigInteger obj)
- {
- return obj.toString();
- }
-
- public BigInteger parse(String str)
- {
- return new BigInteger(str.trim());
- }
- }
-
-
- private class BigDecimalConversionHandler
- implements ConversionHandler<BigDecimal>
- {
- public String getXsiType()
- {
- return "xsd:decimal";
- }
-
- public String stringify(BigDecimal obj)
- {
- return obj.toString();
- }
-
- public BigDecimal parse(String str)
- {
- return new BigDecimal(str.trim());
- }
- }
-
-
- private class DateConversionHandler
- implements ConversionHandler<Date>
- {
- // format as specified by Date.toString() JavaDoc
- private DateFormat _defaultFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
-
- public String getXsiType()
- {
- return "xsd:dateTime";
- }
-
- public String stringify(Date obj)
- {
- return _useXsdFormatting
- ? XmlUtil.formatXsdDatetime(obj)
- : obj.toString();
- }
-
- public Date parse(String str)
- throws ParseException
- {
- if (_useXsdFormatting)
- return XmlUtil.parseXsdDatetime(str);
- else
- {
- synchronized (_defaultFormat)
- {
- return _defaultFormat.parse(str);
- }
- }
- }
- }
-}
Copied: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/PrimitiveConversionHelper.java (from rev 116, branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionHelper.java)
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/PrimitiveConversionHelper.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/PrimitiveConversionHelper.java 2009-08-18 19:16:50 UTC (rev 117)
@@ -0,0 +1,480 @@
+// 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.internal;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.practicalxml.XmlUtil;
+import net.sf.practicalxml.converter.ConversionException;
+
+
+/**
+ * Responsible for converting "primitive" types -- those with unambiguous
+ * string representations -- to/from such a representation.
+ */
+public class PrimitiveConversionHelper
+{
+ private static Map<String,Class<?>> XSD_TYPE_TO_JAVA_CLASS
+ = new HashMap<String,Class<?>>();
+ static
+ {
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:string", String.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:boolean", Boolean.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:byte", Byte.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:short", Short.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:int", Integer.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:long", Long.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:decimal", BigDecimal.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:dateTime", Date.class);
+ }
+
+
+ // this is not static because the helpers are inner classes
+ private Map<Class<?>,ConversionHandler<?>> _helpers
+ = new HashMap<Class<?>,ConversionHandler<?>>();
+ {
+ _helpers.put(String.class, new StringConversionHandler());
+ _helpers.put(Character.class, new CharacterConversionHandler());
+ _helpers.put(Boolean.class, new BooleanConversionHandler());
+ _helpers.put(Byte.class, new ByteConversionHandler());
+ _helpers.put(Short.class, new ShortConversionHandler());
+ _helpers.put(Integer.class, new IntegerConversionHandler());
+ _helpers.put(Long.class, new LongConversionHandler());
+ _helpers.put(Float.class, new FloatConversionHandler());
+ _helpers.put(Double.class, new DoubleConversionHandler());
+ _helpers.put(BigInteger.class, new BigIntegerConversionHandler());
+ _helpers.put(BigDecimal.class, new BigDecimalConversionHandler());
+ _helpers.put(Date.class, new DateConversionHandler());
+
+ _helpers.put(Boolean.TYPE, new BooleanConversionHandler());
+ _helpers.put(Byte.TYPE, new ByteConversionHandler());
+ _helpers.put(Short.TYPE, new ShortConversionHandler());
+ _helpers.put(Integer.TYPE, new IntegerConversionHandler());
+ _helpers.put(Long.TYPE, new LongConversionHandler());
+ _helpers.put(Float.TYPE, new FloatConversionHandler());
+ _helpers.put(Double.TYPE, new DoubleConversionHandler());
+ }
+
+ private boolean _useXsdFormatting;
+
+
+ /**
+ * Default constructor, which uses Java formatting.
+ */
+ public PrimitiveConversionHelper()
+ {
+ // nothing to see here
+ }
+
+
+ /**
+ * Constructor that allows selection of Java or XSD formatting.
+ */
+ public PrimitiveConversionHelper(boolean useXsdFormatting)
+ {
+ _useXsdFormatting = useXsdFormatting;
+ }
+
+
+//----------------------------------------------------------------------------
+// Public Methods
+//----------------------------------------------------------------------------
+
+ /**
+ * Returns the XSD type name to use for stringified objects of the
+ * specified class, <code>null</code> if this converter can't convert
+ * instances of the class.
+ */
+ public String getXsdType(Class<?> klass)
+ {
+ ConversionHandler<?> helper = _helpers.get(klass);
+ return (helper == null) ? null : helper.getXsiType();
+ }
+
+
+ /**
+ * Returns the Java type that best matches the given Schema type name,
+ * <code>null</code> if we do not have an appropriate mapping.
+ */
+ public Class<?> getJavaType(String xsdTypename)
+ {
+ return XSD_TYPE_TO_JAVA_CLASS.get(xsdTypename);
+ }
+
+
+ /**
+ * Converts the passed object into its string representation, according
+ * to the options currently in effect. Passing <code>null</code> will
+ * return <code>null</code>. Throws {@link ConversionException} if
+ * unable to convert the passed object.
+ */
+ public String stringify(Object obj)
+ {
+ if (obj == null)
+ return null;
+
+ try
+ {
+ return getHelper(obj.getClass()).stringify(obj);
+ }
+ catch (Exception ee)
+ {
+ if (ee instanceof ConversionException)
+ throw (ConversionException)ee;
+ throw new ConversionException("unable to convert: " + obj, ee);
+ }
+ }
+
+
+ /**
+ * Parses the passed string into an object of the desired class. Passing
+ * <code>null</code> will return <code>null</code>, passing an empty
+ * string will typically throw a {@link ConversionException}.
+ */
+ public Object parse(String str, Class<?> klass)
+ {
+ if (str == null)
+ return null;
+
+ try
+ {
+ return getHelper(klass).parse(str);
+ }
+ catch (Exception ee)
+ {
+ if (ee instanceof ConversionException)
+ throw (ConversionException)ee;
+ throw new ConversionException("unable to parse: " + str, ee);
+ }
+ }
+
+
+//----------------------------------------------------------------------------
+// Internals
+//----------------------------------------------------------------------------
+
+ /**
+ * Returns the appropriate conversion helper or throws.
+ */
+ @SuppressWarnings(value="unchecked")
+ private ConversionHandler getHelper(Class<?> klass)
+ {
+ ConversionHandler<?> helper = _helpers.get(klass);
+ if (helper == null)
+ throw new ConversionException("unable to get helper: " + klass.getName());
+ return helper;
+ }
+
+
+ /**
+ * Each primitive class has its own conversion handler that is responsible
+ * for converting to/from a string representation. Handlers are guaranteed
+ * to receive non-null objects/strings.
+ * <p>
+ * This interface is parameterized so that the compiler will generate
+ * bridge methods for implementation classes. Elsewhere, we don't care
+ * about parameterization, so wildcard or drop it (see {@link #getHelper}).
+ * <p>
+ * Implementation classes are expected to be inner classes, so that they
+ * have access to configuration information (such as formatting rules).
+ * <p>
+ * Implementation classes are permitted to throw any exception; caller is
+ * expected to catch them and translate to a {@link ConversionException}.
+ */
+ private static interface ConversionHandler<T>
+ {
+ public String getXsiType();
+ public String stringify(T obj) throws Exception;
+ public T parse(String str) throws Exception;
+ }
+
+
+ private class StringConversionHandler
+ implements ConversionHandler<String>
+ {
+ public String getXsiType()
+ {
+ return "xsd:string";
+ }
+
+ public String stringify(String obj)
+ {
+ return String.valueOf(obj);
+ }
+
+ public String parse(String str)
+ {
+ return str;
+ }
+ }
+
+
+ private class CharacterConversionHandler
+ implements ConversionHandler<Character>
+ {
+ private final Character NUL = Character.valueOf('\0');
+
+ public String getXsiType()
+ {
+ return "xsd:string";
+ }
+
+ public String stringify(Character obj)
+ {
+ if (obj.equals(NUL))
+ return "";
+ return obj.toString();
+ }
+
+ public Character parse(String str)
+ {
+ if (str.length() == 0)
+ return NUL;
+ if (str.length() > 1)
+ throw new ConversionException(
+ "attempted to convert multi-character string: \"" + str + "\"");
+ return Character.valueOf(str.charAt(0));
+ }
+ }
+
+
+ private class BooleanConversionHandler
+ implements ConversionHandler<Boolean>
+ {
+ public String getXsiType()
+ {
+ return "xsd:boolean";
+ }
+
+ public String stringify(Boolean obj)
+ {
+ return _useXsdFormatting
+ ? XmlUtil.formatXsdBoolean(obj.booleanValue())
+ : obj.toString();
+ }
+
+ public Boolean parse(String str)
+ {
+ return _useXsdFormatting
+ ? XmlUtil.parseXsdBoolean(str)
+ : Boolean.parseBoolean(str);
+ }
+ }
+
+
+ private class ByteConversionHandler
+ implements ConversionHandler<Byte>
+ {
+ public String getXsiType()
+ {
+ return "xsd:byte";
+ }
+
+ public String stringify(Byte obj)
+ {
+ return obj.toString();
+ }
+
+ public Byte parse(String str)
+ {
+ return Byte.valueOf(str.trim());
+ }
+ }
+
+
+ private class ShortConversionHandler
+ implements ConversionHandler<Short>
+ {
+ public String getXsiType()
+ {
+ return "xsd:short";
+ }
+
+ public String stringify(Short obj)
+ {
+ return obj.toString();
+ }
+
+ public Short parse(String str)
+ {
+ return Short.valueOf(str.trim());
+ }
+ }
+
+
+ private class IntegerConversionHandler
+ implements ConversionHandler<Integer>
+ {
+ public String getXsiType()
+ {
+ return "xsd:int";
+ }
+
+ public String stringify(Integer obj)
+ {
+ return obj.toString();
+ }
+
+ public Integer parse(String str)
+ {
+ return Integer.valueOf(str.trim());
+ }
+ }
+
+
+ private class LongConversionHandler
+ implements ConversionHandler<Long>
+ {
+ public String getXsiType()
+ {
+ return "xsd:long";
+ }
+
+ public String stringify(Long obj)
+ {
+ return obj.toString();
+ }
+
+ public Long parse(String str)
+ {
+ return Long.valueOf(str.trim());
+ }
+ }
+
+
+ private class FloatConversionHandler
+ implements ConversionHandler<Float>
+ {
+ public String getXsiType()
+ {
+ return "xsd:decimal";
+ }
+
+ public String stringify(Float obj)
+ {
+ return _useXsdFormatting
+ ? XmlUtil.formatXsdDecimal(obj)
+ : obj.toString();
+ }
+
+ public Float parse(String str)
+ {
+ return Float.valueOf(str.trim());
+ }
+ }
+
+
+ private class DoubleConversionHandler
+ implements ConversionHandler<Double>
+ {
+ public String getXsiType()
+ {
+ return "xsd:decimal";
+ }
+
+ public String stringify(Double obj)
+ {
+ return _useXsdFormatting
+ ? XmlUtil.formatXsdDecimal(obj)
+ : obj.toString();
+ }
+
+ public Double parse(String str)
+ {
+ return Double.valueOf(str.trim());
+ }
+ }
+
+
+ private class BigIntegerConversionHandler
+ implements ConversionHandler<BigInteger>
+ {
+ public String getXsiType()
+ {
+ return "xsd:decimal";
+ }
+
+ public String stringify(BigInteger obj)
+ {
+ return obj.toString();
+ }
+
+ public BigInteger parse(String str)
+ {
+ return new BigInteger(str.trim());
+ }
+ }
+
+
+ private class BigDecimalConversionHandler
+ implements ConversionHandler<BigDecimal>
+ {
+ public String getXsiType()
+ {
+ return "xsd:decimal";
+ }
+
+ public String stringify(BigDecimal obj)
+ {
+ return obj.toString();
+ }
+
+ public BigDecimal parse(String str)
+ {
+ return new BigDecimal(str.trim());
+ }
+ }
+
+
+ private class DateConversionHandler
+ implements ConversionHandler<Date>
+ {
+ // format as specified by Date.toString() JavaDoc
+ private DateFormat _defaultFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
+
+ public String getXsiType()
+ {
+ return "xsd:dateTime";
+ }
+
+ public String stringify(Date obj)
+ {
+ return _useXsdFormatting
+ ? XmlUtil.formatXsdDatetime(obj)
+ : obj.toString();
+ }
+
+ public Date parse(String str)
+ throws ParseException
+ {
+ if (_useXsdFormatting)
+ return XmlUtil.parseXsdDatetime(str);
+ else
+ {
+ synchronized (_defaultFormat)
+ {
+ return _defaultFormat.parse(str);
+ }
+ }
+ }
+ }
+}
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestConversionHelper.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestConversionHelper.java 2009-08-18 18:52:26 UTC (rev 116)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestConversionHelper.java 2009-08-18 19:16:50 UTC (rev 117)
@@ -18,7 +18,7 @@
import java.math.BigInteger;
import java.util.Date;
-import net.sf.practicalxml.converter.internal.ConversionHelper;
+import net.sf.practicalxml.converter.internal.PrimitiveConversionHelper;
public class TestConversionHelper
@@ -36,7 +36,7 @@
private void assertFailsConversionToObject(
String message,
- ConversionHelper helper,
+ PrimitiveConversionHelper helper,
String str,
Class<?> klass)
{
@@ -58,7 +58,7 @@
public void testClassToXsdType() throws Exception
{
- ConversionHelper helper = new ConversionHelper();
+ PrimitiveConversionHelper helper = new PrimitiveConversionHelper();
assertEquals("xsd:string", helper.getXsdType(String.class));
assertEquals("xsd:string", helper.getXsdType(Character.class));
@@ -72,7 +72,7 @@
public void testUnknownClass() throws Exception
{
- ConversionHelper helper = new ConversionHelper();
+ PrimitiveConversionHelper helper = new PrimitiveConversionHelper();
assertNull(helper.getXsdType(Class.class));
}
@@ -80,7 +80,7 @@
public void testConvertNull() throws Exception
{
- ConversionHelper helper = new ConversionHelper();
+ PrimitiveConversionHelper helper = new PrimitiveConversionHelper();
assertNull(helper.stringify(null));
assertNull(helper.parse(null, Object.class));
@@ -89,7 +89,7 @@
public void testConvertString() throws Exception
{
- ConversionHelper helper = new ConversionHelper();
+ PrimitiveConversionHelper helper = new PrimitiveConversionHelper();
assertEquals("xsd:string", helper.getXsdType(String.class));
@@ -103,7 +103,7 @@
public void testConvertCharacter() throws Exception
{
- ConversionHelper helper = new ConversionHelper();
+ PrimitiveConversionHelper helper = new PrimitiveConversionHelper();
assertEquals("xsd:string", helper.getXsdType(Character.class));
@@ -123,7 +123,7 @@
public void testConvertBooleanDefault() throws Exception
{
- ConversionHelper helper = new ConversionHelper();
+ PrimitiveConversionHelper helper = new PrimitiveConversionHelper();
// default boolean conversion is compatible with XSD type def
assertEquals("xsd:boolean", helper.getXsdType(Boolean.class));
@@ -143,7 +143,7 @@
public void testConvertBooleanXsd() throws Exception
{
- ConversionHelper helper = new ConversionHelper(true);
+ PrimitiveConversionHelper helper = new PrimitiveConversionHelper(true);
assertEquals("xsd:boolean", helper.getXsdType(Boolean.class));
@@ -167,7 +167,7 @@
public void testConvertByte() throws Exception
{
- ConversionHelper helper = new ConversionHelper();
+ PrimitiveConversionHelper helper = new PrimitiveConversionHelper();
assertEquals("xsd:byte", helper.getXsdType(Byte.class));
@@ -205,7 +205,7 @@
public void testConvertShort() throws Exception
{
- ConversionHelper helper = new ConversionHelper();
+ PrimitiveConversionHelper helper = new PrimitiveConversionHelper();
assertEquals("xsd:short", helper.getXsdType(Short.class));
@@ -243,7 +243,7 @@
public void testConvertInteger() throws Exception
{
- ConversionHelper helper = new ConversionHelper();
+ PrimitiveConversionHelper helper = new PrimitiveConversionHelper();
assertEquals("xsd:int", helper.getXsdType(Integer.class));
@@ -281,7 +281,7 @@
public void testConvertLong() throws Exception
{
- ConversionHelper helper = new ConversionHelper();
+ PrimitiveConversionHelper helper = new PrimitiveConversionHelper();
assertEquals("xsd:long", helper.getXsdType(Long.class));
@@ -319,7 +319,7 @@
public void testConvertFloatDefault() throws Exception
{
- ConversionHelper helper = new ConversionHelper();
+ PrimitiveConversionHelper helper = new PrimitiveConversionHelper();
// default float conversion is compatible with XSD type def
assertEquals("xsd:decimal", helper.getXsdType(Float.class));
@@ -351,7 +351,7 @@
public void testConvertFloatXsd() throws Exception
{
- ConversionHelper helper = new ConversionHelper(true);
+ PrimitiveConversionHelper helper = new PrimitiveConversionHelper(true);
assertEquals("xsd:decimal", helper.getXsdType(Float.class));
@@ -381,7 +381,7 @@
public void testConvertDoubleDefault() throws Exception
{
- ConversionHelper helper = new ConversionHelper();
+ PrimitiveConversionHelper helper = new PrimitiveConversionHelper();
// default double conversion is compatible with XSD type def
assertEquals("xsd:decimal", helper.getXsdType(Double.class));
@@ -413,7 +413,7 @@
public void testConvertDoubleXsd() throws Exception
{
- ConversionHelper helper = new ConversionHelper(true);
+ PrimitiveConversionHelper helper = new PrimitiveConversionHelper(true);
assertEquals("xsd:decimal", helper.getXsdType(Double.class));
@@ -444,7 +444,7 @@
public void testConvertBigInteger() throws Exception
{
- ConversionHelper helper = new ConversionHelper();
+ PrimitiveConversionHelper helper = new PrimitiveConversionHelper();
assertEquals("xsd:decimal", helper.getXsdType(BigInteger.class));
@@ -474,7 +474,7 @@
public void testConvertBigDecimal() throws Exception
{
- ConversionHelper helper = new ConversionHelper();
+ PrimitiveConversionHelper helper = new PrimitiveConversionHelper();
assertEquals("xsd:decimal", helper.getXsdType(BigDecimal.class));
@@ -500,7 +500,7 @@
public void testConvertDateDefault() throws Exception
{
- ConversionHelper helper = new ConversionHelper();
+ PrimitiveConversionHelper helper = new PrimitiveConversionHelper();
// default date conversion is NOT compatible with XSD type def,
// so this is misleading
@@ -525,7 +525,7 @@
public void testConvertDateXsd() throws Exception
{
- ConversionHelper helper = new ConversionHelper(true);
+ PrimitiveConversionHelper helper = new PrimitiveConversionHelper(true);
assertEquals("xsd:dateTime", helper.getXsdType(Date.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-08-18 18:52:34
|
Revision: 116
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=116&view=rev
Author: kdgregory
Date: 2009-08-18 18:52:26 +0000 (Tue, 18 Aug 2009)
Log Message:
-----------
add xpath into ConversionException
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/ConversionException.java
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/Xml2BeanDriver.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionHelper.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlDriver.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBeanConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanDriver.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/ConversionException.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/ConversionException.java 2009-08-18 18:19:50 UTC (rev 115)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/ConversionException.java 2009-08-18 18:52:26 UTC (rev 116)
@@ -14,16 +14,38 @@
package net.sf.practicalxml.converter;
+import org.w3c.dom.Element;
+import net.sf.practicalxml.DomUtil;
+
+
/**
* A runtime exception thrown for any conversion error. Will always have a
- * message, and typically contains a wrapped exception.
+ * message, and typically contains a wrapped exception. If thrown during
+ * a conversion <code>from</code> XML, should also have the absolute XPath
+ * of the node that caused the problem, and this is appended to the message.
*/
public class ConversionException
extends RuntimeException
{
private static final long serialVersionUID = 1L;
+ private String _xpath;
+
+
+ public ConversionException(String message, Element elem, Throwable cause)
+ {
+ super(message, cause);
+ _xpath = DomUtil.getAbsolutePath(elem);
+ }
+
+ public ConversionException(String message, Element elem)
+ {
+ super(message);
+ _xpath = DomUtil.getAbsolutePath(elem);
+ }
+
+
public ConversionException(String message, Throwable cause)
{
super(message, cause);
@@ -33,4 +55,13 @@
{
super(message);
}
+
+
+ @Override
+ public String toString()
+ {
+ return (_xpath != null)
+ ? super.getMessage() + " (" + _xpath + ")"
+ : super.getMessage();
+ }
}
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-08-18 18:19:50 UTC (rev 115)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java 2009-08-18 18:52:26 UTC (rev 116)
@@ -136,7 +136,7 @@
}
catch (Exception ee)
{
- throw new ConversionException("unable to append child", ee);
+ throw new ConversionException("unable to append child: " + name, _parent, ee);
}
}
Modified: 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-08-18 18:19:50 UTC (rev 115)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanDriver.java 2009-08-18 18:52:26 UTC (rev 116)
@@ -123,8 +123,7 @@
{
String attr = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil");
if (!attr.equals("true"))
- throw new ConversionException(
- "missing xsi:nil: " + DomUtil.getAbsolutePath(elem));
+ throw new ConversionException("missing xsi:nil", elem);
}
return true;
@@ -137,8 +136,7 @@
return null;
if (hasElementChildren(elem))
- throw new ConversionException(
- "expecting primitive; has children: " + DomUtil.getAbsolutePath(elem));
+ throw new ConversionException("expecting primitive; has children", elem);
return _helper.parse(getText(elem), klass);
}
@@ -271,9 +269,7 @@
catch (ClassNotFoundException ee)
{
throw new ConversionException(
- "invalid Java type specification (" + javaType + "): "
- + DomUtil.getAbsolutePath(elem),
- ee);
+ "invalid Java type specification: " + javaType, elem, ee);
}
}
return _helper.getJavaType(xsiType);
@@ -287,8 +283,7 @@
String xsiType = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
if (StringUtils.isEmpty(xsiType))
- throw new ConversionException(
- "missing xsi:type: " + DomUtil.getAbsolutePath(elem));
+ throw new ConversionException("missing xsi:type", elem);
if (xsiType.equals(_helper.getXsdType(klass)))
return;
@@ -298,8 +293,8 @@
return;
throw new ConversionException(
- "invalid xsi:type (\"" + xsiType + "\" for " + klass.getName() + "): "
- + DomUtil.getAbsolutePath(elem));
+ "invalid xsi:type: \"" + xsiType + "\" for " + klass.getName(),
+ elem);
}
@@ -325,9 +320,7 @@
Method setter = methodMap.get(DomUtil.getLocalName(child));
if ((setter == null) && !_options.contains(Xml2BeanOptions.IGNORE_MISSING_PROPERTIES))
{
- throw new ConversionException(
- "can't find property setter in " + beanKlass.getName() + ": "
- + DomUtil.getAbsolutePath(child));
+ throw new ConversionException("can't find property setter", child);
}
return setter;
@@ -347,9 +340,9 @@
methodMap.put(propDesc.getName(), setter);
}
}
- catch (IntrospectionException e)
+ catch (IntrospectionException ee)
{
- throw new ConversionException("unable to introspect", e);
+ throw new ConversionException("unable to introspect", ee);
}
_introspectedClasses.put(klass, methodMap);
@@ -399,9 +392,7 @@
}
catch (Exception ee)
{
- throw new ConversionException(
- "unable to instantiate bean: " + DomUtil.getAbsolutePath(elem),
- ee);
+ throw new ConversionException("unable to instantiate bean", elem, ee);
}
}
@@ -414,9 +405,7 @@
}
catch (Exception ee)
{
- throw new ConversionException(
- "unable to set property: " + DomUtil.getAbsolutePath(elem),
- ee);
+ throw new ConversionException("unable to set property", elem, ee);
}
}
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java 2009-08-18 18:19:50 UTC (rev 115)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java 2009-08-18 18:52:26 UTC (rev 116)
@@ -14,17 +14,8 @@
package net.sf.practicalxml.converter.bean;
-import net.sf.practicalxml.DomUtil;
-import net.sf.practicalxml.XmlException;
-import net.sf.practicalxml.XmlUtil;
-import net.sf.practicalxml.converter.ConversionException;
-import net.sf.practicalxml.converter.internal.ConversionHelper;
-import net.sf.practicalxml.internal.StringUtils;
-
-import java.util.Arrays;
import java.util.Date;
import java.util.EnumSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -32,7 +23,12 @@
import org.w3c.dom.Element;
+import net.sf.practicalxml.DomUtil;
+import net.sf.practicalxml.converter.ConversionException;
+import net.sf.practicalxml.converter.internal.ConversionHelper;
+import net.sf.practicalxml.internal.StringUtils;
+
/**
* Invoked by {@link Xml2BeanDriver} to convert a DOM <code>Element</code>
* into the appropriate Java object. Unlike {@link Bean2XmlHandler}, there
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionHelper.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionHelper.java 2009-08-18 18:19:50 UTC (rev 115)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionHelper.java 2009-08-18 18:52:26 UTC (rev 116)
@@ -33,7 +33,7 @@
*/
public class ConversionHelper
{
- private static Map<String,Class<?>> XSD_TYPE_TO_JAVA_CLASS
+ private static Map<String,Class<?>> XSD_TYPE_TO_JAVA_CLASS
= new HashMap<String,Class<?>>();
static
{
@@ -46,8 +46,8 @@
XSD_TYPE_TO_JAVA_CLASS.put("xsd:decimal", BigDecimal.class);
XSD_TYPE_TO_JAVA_CLASS.put("xsd:dateTime", Date.class);
}
-
-
+
+
// this is not static because the helpers are inner classes
private Map<Class<?>,ConversionHandler<?>> _helpers
= new HashMap<Class<?>,ConversionHandler<?>>();
@@ -64,7 +64,7 @@
_helpers.put(BigInteger.class, new BigIntegerConversionHandler());
_helpers.put(BigDecimal.class, new BigDecimalConversionHandler());
_helpers.put(Date.class, new DateConversionHandler());
-
+
_helpers.put(Boolean.TYPE, new BooleanConversionHandler());
_helpers.put(Byte.TYPE, new ByteConversionHandler());
_helpers.put(Short.TYPE, new ShortConversionHandler());
@@ -109,8 +109,8 @@
ConversionHandler<?> helper = _helpers.get(klass);
return (helper == null) ? null : helper.getXsiType();
}
-
-
+
+
/**
* Returns the Java type that best matches the given Schema type name,
* <code>null</code> if we do not have an appropriate mapping.
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlDriver.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlDriver.java 2009-08-18 18:19:50 UTC (rev 115)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlDriver.java 2009-08-18 18:52:26 UTC (rev 116)
@@ -66,7 +66,7 @@
}
- private void assertConversionException(String message, Bean2XmlDriver driver, Object data)
+ private void assertConversionFailure(String message, Bean2XmlDriver driver, Object data)
{
try
{
@@ -74,7 +74,9 @@
fail(message);
}
catch (ConversionException ee)
- { /* success */ }
+ {
+// System.out.println(ee);
+ }
}
@@ -337,8 +339,8 @@
data.put("%key1%", new Integer(123));
data.put("%key2%", new Integer(456));
- assertConversionException("converted map with invalid key under INTROSPECT_MAPS",
- driver, data);
+ assertConversionFailure("converted map with invalid key under INTROSPECT_MAPS",
+ driver, data);
}
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBeanConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBeanConverter.java 2009-08-18 18:19:50 UTC (rev 115)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBeanConverter.java 2009-08-18 18:52:26 UTC (rev 116)
@@ -56,7 +56,7 @@
// Support Code
//----------------------------------------------------------------------------
- private static void assertConversionError(
+ private static void assertConversionFailure(
String message, BeanConverter converter, Element elem, Class<?> klass)
{
try
@@ -65,7 +65,9 @@
fail(message);
}
catch (ConversionException ee)
- { /* success */ }
+ {
+// System.out.println(ee);
+ }
}
//----------------------------------------------------------------------------
@@ -156,7 +158,7 @@
Element root = outConverter.convertToXml(null, "test");
// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
- assertConversionError("accepted DOM with null entry but no xsi:nil",
+ assertConversionFailure("accepted DOM with null entry but no xsi:nil",
inConverter, root, String.class);
}
@@ -324,7 +326,7 @@
Element invalid = outconverter2.convertToXml(data, "test");
// System.out.println(OutputUtil.compactString(invalid.getOwnerDocument()));
- assertConversionError("converter requiring xsi:type accepted XML without",
+ assertConversionFailure("converter requiring xsi:type accepted XML without",
inConverter, invalid, SimpleBean.class);
}
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanDriver.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanDriver.java 2009-08-18 18:19:50 UTC (rev 115)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanDriver.java 2009-08-18 18:52:26 UTC (rev 116)
@@ -70,7 +70,7 @@
}
- private static void assertConversionError(
+ private static void assertConversionFailure(
String message, Xml2BeanDriver driver, Element elem, Class<?> klass)
{
try
@@ -79,7 +79,9 @@
fail(message);
}
catch (ConversionException ee)
- { /* success */ }
+ {
+// System.out.println(ee);
+ }
}
@@ -133,8 +135,8 @@
assertEquals("foo", dst);
Element invalid = createTestData(text("foo"));
- assertConversionError("converted element missing xsi:type",
- driver, invalid, String.class);
+ assertConversionFailure("converted element missing xsi:type",
+ driver, invalid, String.class);
}
@@ -143,8 +145,8 @@
Xml2BeanDriver driver = new Xml2BeanDriver(Xml2BeanOptions.REQUIRE_XSI_TYPE);
Element invalid = createTestData(text("foo"), xsiType("xsd:int"));
- assertConversionError("converted element with incorrect xsi:type",
- driver, invalid, String.class);
+ assertConversionFailure("converted element with incorrect xsi:type",
+ driver, invalid, String.class);
}
@@ -153,8 +155,8 @@
Xml2BeanDriver driver = new Xml2BeanDriver();
Element invalid = createTestData(text("foo"), element("bar"));
- assertConversionError("converted primitive with element content",
- driver, invalid, String.class);
+ assertConversionFailure("converted primitive with element content",
+ driver, invalid, String.class);
}
@@ -175,8 +177,8 @@
assertNull(driver.convert(valid, String.class));
Element invalid = createTestData();
- assertConversionError("able to convert null data with REQUIRE_XSI_NIL set",
- driver, invalid, String.class);
+ assertConversionFailure("able to convert null data with REQUIRE_XSI_NIL set",
+ driver, invalid, String.class);
}
@@ -210,8 +212,8 @@
assertNull(driver.convert(valid, String.class));
Element invalid = createTestData(text(" \t "));
- assertConversionError("able to convert blank data with CONVERT_BLANK_AS_NULL and REQUIRE_XSI_NIL set",
- driver, invalid, String.class);
+ assertConversionFailure("able to convert blank data with CONVERT_BLANK_AS_NULL and REQUIRE_XSI_NIL set",
+ driver, invalid, String.class);
}
@@ -249,8 +251,8 @@
Element invalid = createTestData(
element("foo", text("12"), xsiType("xsd:int")));
- assertConversionError("able to convert with REQUIRE_XSI_TYPE set",
- driver, invalid, int[].class);
+ assertConversionFailure("able to convert with REQUIRE_XSI_TYPE set",
+ driver, invalid, int[].class);
}
@@ -319,8 +321,8 @@
Element data = createTestData(
element("a", text("foo"), xsiType("java:foo")));
- assertConversionError("converted unknown type",
- driver, data, List.class);
+ assertConversionFailure("converted unknown type",
+ driver, data, List.class);
}
@@ -557,8 +559,8 @@
element("ival", text("123"), xsiType("xsd:int")),
element("dval", text("123.456"),xsiType("xsd:decimal")),
element("bval", text("true"), xsiType("xsd:boolean")));
- assertConversionError("didn't throw when missing xsi:type on top level",
- driver, invalid1, SimpleBean.class);
+ assertConversionFailure("didn't throw when missing xsi:type on top level",
+ driver, invalid1, SimpleBean.class);
Element invalid2 = createTestData(
xsiType("java:" + SimpleBean.class.getName()),
@@ -566,8 +568,8 @@
element("ival", text("123")),
element("dval", text("123.456")),
element("bval", text("true")));
- assertConversionError("didn't throw when missing xsi:type on component level",
- driver, invalid2, SimpleBean.class);
+ assertConversionFailure("didn't throw when missing xsi:type on component level",
+ driver, invalid2, SimpleBean.class);
}
@@ -580,7 +582,7 @@
Xml2BeanDriver driver1 = new Xml2BeanDriver();
- assertConversionError("converted bean when extra fields present in XML",
+ assertConversionFailure("converted bean when extra fields present in XML",
driver1, data, SimpleBean.class);
Xml2BeanDriver driver2 = new Xml2BeanDriver(Xml2BeanOptions.IGNORE_MISSING_PROPERTIES);
@@ -702,7 +704,7 @@
Element data = createTestData(
element("sval", text("foo")));
- assertConversionError("converted bean without setter",
- driver, data, ReadOnlyBean.class);
+ assertConversionFailure("converted bean without setter",
+ driver, data, ReadOnlyBean.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-08-18 18:19:58
|
Revision: 115
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=115&view=rev
Author: kdgregory
Date: 2009-08-18 18:19:50 +0000 (Tue, 18 Aug 2009)
Log Message:
-----------
bugfix: introspected maps with invalid keys
Modified Paths:
--------------
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/TestBean2XmlDriver.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-08-18 18:10:39 UTC (rev 114)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java 2009-08-18 18:19:50 UTC (rev 115)
@@ -21,6 +21,7 @@
import org.w3c.dom.Element;
import net.sf.practicalxml.DomUtil;
+import net.sf.practicalxml.converter.ConversionException;
/**
@@ -126,10 +127,17 @@
if (shouldSkip(value))
return null;
- Element child = DomUtil.appendChildInheritNamespace(_parent, name);
- setType(child, type);
- setValue(child, value);
- return child;
+ try
+ {
+ Element child = DomUtil.appendChildInheritNamespace(_parent, name);
+ setType(child, type);
+ setValue(child, value);
+ return child;
+ }
+ catch (Exception ee)
+ {
+ throw new ConversionException("unable to append child", ee);
+ }
}
public Element appendContainer(String name, String type)
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlDriver.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlDriver.java 2009-08-18 18:10:39 UTC (rev 114)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlDriver.java 2009-08-18 18:19:50 UTC (rev 115)
@@ -66,6 +66,18 @@
}
+ private void assertConversionException(String message, Bean2XmlDriver driver, Object data)
+ {
+ try
+ {
+ driver.convert(data, "test");
+ fail(message);
+ }
+ catch (ConversionException ee)
+ { /* success */ }
+ }
+
+
//----------------------------------------------------------------------------
// Test Cases
//----------------------------------------------------------------------------
@@ -317,6 +329,19 @@
}
+ public void testConvertMapIntrospectWithInvalidKey() throws Exception
+ {
+ Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.INTROSPECT_MAPS);
+
+ Map<String,Integer> data = new TreeMap<String,Integer>();
+ data.put("%key1%", new Integer(123));
+ data.put("%key2%", new Integer(456));
+
+ assertConversionException("converted map with invalid key under INTROSPECT_MAPS",
+ driver, data);
+ }
+
+
public void testConvertSimpleBeanDefault() throws Exception
{
Bean2XmlDriver driver = new Bean2XmlDriver();
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-08-18 18:10:51
|
Revision: 114
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=114&view=rev
Author: kdgregory
Date: 2009-08-18 18:10:39 +0000 (Tue, 18 Aug 2009)
Log Message:
-----------
rename conversion options; remove unused options
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/Bean2XmlDriver.java
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/Xml2BeanOptions.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlAppenders.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlDriver.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/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-08-18 17:57:48 UTC (rev 113)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java 2009-08-18 18:10:39 UTC (rev 114)
@@ -93,7 +93,7 @@
protected void setType(Element elem, String type)
{
- if (isOptionSet(Bean2XmlOptions.XSI_TYPE))
+ if (isOptionSet(Bean2XmlOptions.ADD_XSI_TYPE))
elem.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type", type);
}
Modified: 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-08-18 17:57:48 UTC (rev 113)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlDriver.java 2009-08-18 18:10:39 UTC (rev 114)
@@ -114,7 +114,7 @@
private boolean shouldUseXsdFormatting()
{
return _options.contains(Bean2XmlOptions.XSD_FORMAT)
- || _options.contains(Bean2XmlOptions.XSI_TYPE);
+ || _options.contains(Bean2XmlOptions.ADD_XSI_TYPE);
}
@@ -143,7 +143,7 @@
private void doXsiNamespaceHack(Element root)
{
if (_options.contains(Bean2XmlOptions.XSI_NIL)
- && !_options.contains(Bean2XmlOptions.XSI_TYPE))
+ && !_options.contains(Bean2XmlOptions.ADD_XSI_TYPE))
{
root.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil", "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-08-18 17:57:48 UTC (rev 113)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java 2009-08-18 18:10:39 UTC (rev 114)
@@ -17,39 +17,40 @@
/**
* Options used by {@link Bean2XmlHandler} to control the structure of the
- * DOM tree.
+ * generated DOM tree.
*/
public enum Bean2XmlOptions
{
/**
- * 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,
-
- /**
* 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:XXX</code>", where XXX is the XSD type name. For complex
- * types, this attribute's value will be "<code>java:XXX</code>", where
- * XXX is the fully-qualified classname.
+ * "<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>.
*/
- XSI_TYPE,
+ ADD_XSI_TYPE,
/**
- * Report null values using the <code>xsi:nil="true"</code> attribute. If
- * not present, null values are ignored, and not added to DOM tree.
+ * 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.
*/
+ INTROSPECT_MAPS,
+
+ /**
+ * 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.
+ */
XSI_NIL,
/**
- * 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.
+ * 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.
*/
- INTROSPECT_MAPS
+ XSD_FORMAT
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanOptions.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanOptions.java 2009-08-18 17:57:48 UTC (rev 113)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanOptions.java 2009-08-18 18:10:39 UTC (rev 114)
@@ -29,13 +29,11 @@
*/
CONVERT_BLANK_AS_NULL,
-
/**
* Expect data (in particular, dates) to be formatted per XML Schema spec.
*/
EXPECT_XSD_FORMAT,
-
/**
* If present, the converter ignores elements that don't correspond to
* settable properties of the bean.
@@ -44,21 +42,12 @@
/**
- * If present, the converter will look for a setter method taking a
- * <code>String</code>, in preference to a non-string method returned
- * from the bean introspector.
- */
- PREFER_STRING_SETTER,
-
-
- /**
* If present, the converter requires an <code>xsi:nil</code> attribute
* on any empty nodes, and will throw if it's not present. Default is to
* treat empty nodes as <code>null</code>.
*/
REQUIRE_XSI_NIL,
-
/**
* If present, the converter requires an <code>xsi:type</code> attribute
* on each element, and will throw if it's not present. Default behavior
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlAppenders.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlAppenders.java 2009-08-18 17:57:48 UTC (rev 113)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlAppenders.java 2009-08-18 18:10:39 UTC (rev 114)
@@ -72,7 +72,7 @@
{
Element root = DomUtil.newDocument("root");
- Appender appender = new BasicAppender(root, useOptions(Bean2XmlOptions.XSI_TYPE));
+ Appender appender = new BasicAppender(root, useOptions(Bean2XmlOptions.ADD_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.XSI_TYPE));
+ Appender appender = new BasicAppender(root, useOptions(Bean2XmlOptions.ADD_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.XSI_TYPE));
+ Appender appender = new DirectAppender(root, useOptions(Bean2XmlOptions.ADD_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.XSI_TYPE));
+ Appender appender = new DirectAppender(root, useOptions(Bean2XmlOptions.ADD_XSI_TYPE));
Element child0 = appender.appendContainer("foo", "bar");
assertSame(root, child0);
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlDriver.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlDriver.java 2009-08-18 17:57:48 UTC (rev 113)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlDriver.java 2009-08-18 18:10:39 UTC (rev 114)
@@ -128,7 +128,7 @@
public void testConvertPrimitivesWithXsiType() throws Exception
{
- Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.XSI_TYPE);
+ Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.ADD_XSI_TYPE);
for (int idx = 0 ; idx < PRIMITIVE_VALUES.length ; idx++)
{
PrimitiveValue value = PRIMITIVE_VALUES[idx];
@@ -164,7 +164,7 @@
public void testConvertPrimitiveArrayWithXsiType() throws Exception
{
- Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.XSI_TYPE);
+ Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.ADD_XSI_TYPE);
int[] data = new int[] { 1, 2, 3 };
Element root = driver.convert(data, "test");
@@ -188,7 +188,7 @@
public void testConvertStringArrayWithXsiType() throws Exception
{
- Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.XSI_TYPE);
+ Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.ADD_XSI_TYPE);
String[] data = new String[] { "foo", "bar", "baz" };
Element root = driver.convert(data, "test");
@@ -212,7 +212,7 @@
public void testConvertStringListWithXsiType() throws Exception
{
- Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.XSI_TYPE);
+ Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.ADD_XSI_TYPE);
List<String> data = new ArrayList<String>();
data.add("foo");
@@ -240,7 +240,7 @@
public void testConvertStringSetWithXsiType() throws Exception
{
- Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.XSI_TYPE);
+ Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.ADD_XSI_TYPE);
// TreeSet means that the data will be re-ordered
Set<String> data = new TreeSet<String>();
@@ -269,7 +269,7 @@
public void testConvertMapDefaultWithXsiType() throws Exception
{
- Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.XSI_TYPE);
+ Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.ADD_XSI_TYPE);
// TreeMap means that the data will be re-ordered
Map<String,Integer> data = new TreeMap<String,Integer>();
@@ -294,7 +294,7 @@
public void testConvertMapIntrospectWithXsiType() throws Exception
{
- Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.INTROSPECT_MAPS, Bean2XmlOptions.XSI_TYPE);
+ Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.INTROSPECT_MAPS, Bean2XmlOptions.ADD_XSI_TYPE);
// TreeMap means that the data will be re-ordered
Map<String,Integer> data = new TreeMap<String,Integer>();
@@ -335,7 +335,7 @@
public void testConvertSimpleBeanWithXsiType() throws Exception
{
- Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.XSI_TYPE);
+ Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.ADD_XSI_TYPE);
SimpleBean bean = new SimpleBean("zippy", 123, new BigDecimal("456.78"), true);
Element root = driver.convert(bean, "test");
@@ -383,7 +383,7 @@
public void testConvertSimpleBeanXsiNilAndXsiType() throws Exception
{
- Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.XSI_NIL, Bean2XmlOptions.XSI_TYPE);
+ Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.XSI_NIL, Bean2XmlOptions.ADD_XSI_TYPE);
SimpleBean bean = new SimpleBean(null, 123, null, true);
Element root = driver.convert(bean, "test");
@@ -399,7 +399,7 @@
public void testConvertBeanArrayWithXsiType() throws Exception
{
- Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.XSI_TYPE);
+ Bean2XmlDriver driver = new Bean2XmlDriver(Bean2XmlOptions.ADD_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/TestBeanConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBeanConverter.java 2009-08-18 17:57:48 UTC (rev 113)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBeanConverter.java 2009-08-18 18:10:39 UTC (rev 114)
@@ -216,7 +216,7 @@
List<Integer> data = Arrays.asList(1, 2, 3);
assert(data.get(0) instanceof Integer);
- BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.XSI_TYPE);
+ BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.ADD_XSI_TYPE);
BeanConverter inConverter = new BeanConverter();
Element root = outConverter.convertToXml(data, "test");
@@ -311,7 +311,7 @@
{
SimpleBean data = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
- BeanConverter outconverter1 = new BeanConverter(Bean2XmlOptions.XSI_TYPE);
+ BeanConverter outconverter1 = new BeanConverter(Bean2XmlOptions.ADD_XSI_TYPE);
BeanConverter outconverter2 = new BeanConverter();
BeanConverter inConverter = new BeanConverter(Xml2BeanOptions.REQUIRE_XSI_TYPE);
@@ -335,7 +335,7 @@
SimpleBean bean2 = new SimpleBean("zyx", 987, null, false);
List<SimpleBean> data = Arrays.asList(bean1, bean2);
- BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.XSI_TYPE);
+ BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.ADD_XSI_TYPE);
BeanConverter inConverter = new BeanConverter();
Element root = outConverter.convertToXml(data, "test");
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-08-18 17:57:56
|
Revision: 113
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=113&view=rev
Author: kdgregory
Date: 2009-08-18 17:57:48 +0000 (Tue, 18 Aug 2009)
Log Message:
-----------
create internals package, put ConversionHelper in it
Modified 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/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestConversionHelper.java
Added Paths:
-----------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionHelper.java
Removed Paths:
-------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/ConversionHelper.java
Deleted: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/ConversionHelper.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/ConversionHelper.java 2009-08-18 17:41:38 UTC (rev 112)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/ConversionHelper.java 2009-08-18 17:57:48 UTC (rev 113)
@@ -1,479 +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;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-import net.sf.practicalxml.XmlUtil;
-
-
-/**
- * Responsible for converting "primitive" types -- those with unambiguous
- * string representations -- to/from such a representation.
- */
-public class ConversionHelper
-{
- private static Map<String,Class<?>> XSD_TYPE_TO_JAVA_CLASS
- = new HashMap<String,Class<?>>();
- static
- {
- XSD_TYPE_TO_JAVA_CLASS.put("xsd:string", String.class);
- XSD_TYPE_TO_JAVA_CLASS.put("xsd:boolean", Boolean.class);
- XSD_TYPE_TO_JAVA_CLASS.put("xsd:byte", Byte.class);
- XSD_TYPE_TO_JAVA_CLASS.put("xsd:short", Short.class);
- XSD_TYPE_TO_JAVA_CLASS.put("xsd:int", Integer.class);
- XSD_TYPE_TO_JAVA_CLASS.put("xsd:long", Long.class);
- XSD_TYPE_TO_JAVA_CLASS.put("xsd:decimal", BigDecimal.class);
- XSD_TYPE_TO_JAVA_CLASS.put("xsd:dateTime", Date.class);
- }
-
-
- // this is not static because the helpers are inner classes
- private Map<Class<?>,ConversionHandler<?>> _helpers
- = new HashMap<Class<?>,ConversionHandler<?>>();
- {
- _helpers.put(String.class, new StringConversionHandler());
- _helpers.put(Character.class, new CharacterConversionHandler());
- _helpers.put(Boolean.class, new BooleanConversionHandler());
- _helpers.put(Byte.class, new ByteConversionHandler());
- _helpers.put(Short.class, new ShortConversionHandler());
- _helpers.put(Integer.class, new IntegerConversionHandler());
- _helpers.put(Long.class, new LongConversionHandler());
- _helpers.put(Float.class, new FloatConversionHandler());
- _helpers.put(Double.class, new DoubleConversionHandler());
- _helpers.put(BigInteger.class, new BigIntegerConversionHandler());
- _helpers.put(BigDecimal.class, new BigDecimalConversionHandler());
- _helpers.put(Date.class, new DateConversionHandler());
-
- _helpers.put(Boolean.TYPE, new BooleanConversionHandler());
- _helpers.put(Byte.TYPE, new ByteConversionHandler());
- _helpers.put(Short.TYPE, new ShortConversionHandler());
- _helpers.put(Integer.TYPE, new IntegerConversionHandler());
- _helpers.put(Long.TYPE, new LongConversionHandler());
- _helpers.put(Float.TYPE, new FloatConversionHandler());
- _helpers.put(Double.TYPE, new DoubleConversionHandler());
- }
-
- private boolean _useXsdFormatting;
-
-
- /**
- * Default constructor, which uses Java formatting.
- */
- public ConversionHelper()
- {
- // nothing to see here
- }
-
-
- /**
- * Constructor that allows selection of Java or XSD formatting.
- */
- public ConversionHelper(boolean useXsdFormatting)
- {
- _useXsdFormatting = useXsdFormatting;
- }
-
-
-//----------------------------------------------------------------------------
-// Public Methods
-//----------------------------------------------------------------------------
-
- /**
- * Returns the XSD type name to use for stringified objects of the
- * specified class, <code>null</code> if this converter can't convert
- * instances of the class.
- */
- public String getXsdType(Class<?> klass)
- {
- ConversionHandler<?> helper = _helpers.get(klass);
- return (helper == null) ? null : helper.getXsiType();
- }
-
-
- /**
- * Returns the Java type that best matches the given Schema type name,
- * <code>null</code> if we do not have an appropriate mapping.
- */
- public Class<?> getJavaType(String xsdTypename)
- {
- return XSD_TYPE_TO_JAVA_CLASS.get(xsdTypename);
- }
-
-
- /**
- * Converts the passed object into its string representation, according
- * to the options currently in effect. Passing <code>null</code> will
- * return <code>null</code>. Throws {@link ConversionException} if
- * unable to convert the passed object.
- */
- public String stringify(Object obj)
- {
- if (obj == null)
- return null;
-
- try
- {
- return getHelper(obj.getClass()).stringify(obj);
- }
- catch (Exception ee)
- {
- if (ee instanceof ConversionException)
- throw (ConversionException)ee;
- throw new ConversionException("unable to convert: " + obj, ee);
- }
- }
-
-
- /**
- * Parses the passed string into an object of the desired class. Passing
- * <code>null</code> will return <code>null</code>, passing an empty
- * string will typically throw a {@link ConversionException}.
- */
- public Object parse(String str, Class<?> klass)
- {
- if (str == null)
- return null;
-
- try
- {
- return getHelper(klass).parse(str);
- }
- catch (Exception ee)
- {
- if (ee instanceof ConversionException)
- throw (ConversionException)ee;
- throw new ConversionException("unable to parse: " + str, ee);
- }
- }
-
-
-//----------------------------------------------------------------------------
-// Internals
-//----------------------------------------------------------------------------
-
- /**
- * Returns the appropriate conversion helper or throws.
- */
- @SuppressWarnings(value="unchecked")
- private ConversionHandler getHelper(Class<?> klass)
- {
- ConversionHandler<?> helper = _helpers.get(klass);
- if (helper == null)
- throw new ConversionException("unable to get helper: " + klass.getName());
- return helper;
- }
-
-
- /**
- * Each primitive class has its own conversion handler that is responsible
- * for converting to/from a string representation. Handlers are guaranteed
- * to receive non-null objects/strings.
- * <p>
- * This interface is parameterized so that the compiler will generate
- * bridge methods for implementation classes. Elsewhere, we don't care
- * about parameterization, so wildcard or drop it (see {@link #getHelper}).
- * <p>
- * Implementation classes are expected to be inner classes, so that they
- * have access to configuration information (such as formatting rules).
- * <p>
- * Implementation classes are permitted to throw any exception; caller is
- * expected to catch them and translate to a {@link ConversionException}.
- */
- private static interface ConversionHandler<T>
- {
- public String getXsiType();
- public String stringify(T obj) throws Exception;
- public T parse(String str) throws Exception;
- }
-
-
- private class StringConversionHandler
- implements ConversionHandler<String>
- {
- public String getXsiType()
- {
- return "xsd:string";
- }
-
- public String stringify(String obj)
- {
- return String.valueOf(obj);
- }
-
- public String parse(String str)
- {
- return str;
- }
- }
-
-
- private class CharacterConversionHandler
- implements ConversionHandler<Character>
- {
- private final Character NUL = Character.valueOf('\0');
-
- public String getXsiType()
- {
- return "xsd:string";
- }
-
- public String stringify(Character obj)
- {
- if (obj.equals(NUL))
- return "";
- return obj.toString();
- }
-
- public Character parse(String str)
- {
- if (str.length() == 0)
- return NUL;
- if (str.length() > 1)
- throw new ConversionException(
- "attempted to convert multi-character string: \"" + str + "\"");
- return Character.valueOf(str.charAt(0));
- }
- }
-
-
- private class BooleanConversionHandler
- implements ConversionHandler<Boolean>
- {
- public String getXsiType()
- {
- return "xsd:boolean";
- }
-
- public String stringify(Boolean obj)
- {
- return _useXsdFormatting
- ? XmlUtil.formatXsdBoolean(obj.booleanValue())
- : obj.toString();
- }
-
- public Boolean parse(String str)
- {
- return _useXsdFormatting
- ? XmlUtil.parseXsdBoolean(str)
- : Boolean.parseBoolean(str);
- }
- }
-
-
- private class ByteConversionHandler
- implements ConversionHandler<Byte>
- {
- public String getXsiType()
- {
- return "xsd:byte";
- }
-
- public String stringify(Byte obj)
- {
- return obj.toString();
- }
-
- public Byte parse(String str)
- {
- return Byte.valueOf(str.trim());
- }
- }
-
-
- private class ShortConversionHandler
- implements ConversionHandler<Short>
- {
- public String getXsiType()
- {
- return "xsd:short";
- }
-
- public String stringify(Short obj)
- {
- return obj.toString();
- }
-
- public Short parse(String str)
- {
- return Short.valueOf(str.trim());
- }
- }
-
-
- private class IntegerConversionHandler
- implements ConversionHandler<Integer>
- {
- public String getXsiType()
- {
- return "xsd:int";
- }
-
- public String stringify(Integer obj)
- {
- return obj.toString();
- }
-
- public Integer parse(String str)
- {
- return Integer.valueOf(str.trim());
- }
- }
-
-
- private class LongConversionHandler
- implements ConversionHandler<Long>
- {
- public String getXsiType()
- {
- return "xsd:long";
- }
-
- public String stringify(Long obj)
- {
- return obj.toString();
- }
-
- public Long parse(String str)
- {
- return Long.valueOf(str.trim());
- }
- }
-
-
- private class FloatConversionHandler
- implements ConversionHandler<Float>
- {
- public String getXsiType()
- {
- return "xsd:decimal";
- }
-
- public String stringify(Float obj)
- {
- return _useXsdFormatting
- ? XmlUtil.formatXsdDecimal(obj)
- : obj.toString();
- }
-
- public Float parse(String str)
- {
- return Float.valueOf(str.trim());
- }
- }
-
-
- private class DoubleConversionHandler
- implements ConversionHandler<Double>
- {
- public String getXsiType()
- {
- return "xsd:decimal";
- }
-
- public String stringify(Double obj)
- {
- return _useXsdFormatting
- ? XmlUtil.formatXsdDecimal(obj)
- : obj.toString();
- }
-
- public Double parse(String str)
- {
- return Double.valueOf(str.trim());
- }
- }
-
-
- private class BigIntegerConversionHandler
- implements ConversionHandler<BigInteger>
- {
- public String getXsiType()
- {
- return "xsd:decimal";
- }
-
- public String stringify(BigInteger obj)
- {
- return obj.toString();
- }
-
- public BigInteger parse(String str)
- {
- return new BigInteger(str.trim());
- }
- }
-
-
- private class BigDecimalConversionHandler
- implements ConversionHandler<BigDecimal>
- {
- public String getXsiType()
- {
- return "xsd:decimal";
- }
-
- public String stringify(BigDecimal obj)
- {
- return obj.toString();
- }
-
- public BigDecimal parse(String str)
- {
- return new BigDecimal(str.trim());
- }
- }
-
-
- private class DateConversionHandler
- implements ConversionHandler<Date>
- {
- // format as specified by Date.toString() JavaDoc
- private DateFormat _defaultFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
-
- public String getXsiType()
- {
- return "xsd:dateTime";
- }
-
- public String stringify(Date obj)
- {
- return _useXsdFormatting
- ? XmlUtil.formatXsdDatetime(obj)
- : obj.toString();
- }
-
- public Date parse(String str)
- throws ParseException
- {
- if (_useXsdFormatting)
- return XmlUtil.parseXsdDatetime(str);
- else
- {
- synchronized (_defaultFormat)
- {
- return _defaultFormat.parse(str);
- }
- }
- }
- }
-}
Modified: 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-08-18 17:41:38 UTC (rev 112)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlDriver.java 2009-08-18 17:57:48 UTC (rev 113)
@@ -30,8 +30,8 @@
import net.sf.practicalxml.DomUtil;
import net.sf.practicalxml.converter.ConversionException;
-import net.sf.practicalxml.converter.ConversionHelper;
import net.sf.practicalxml.converter.bean.Bean2XmlAppenders.*;
+import net.sf.practicalxml.converter.internal.ConversionHelper;
/**
Modified: 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-08-18 17:41:38 UTC (rev 112)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanDriver.java 2009-08-18 17:57:48 UTC (rev 113)
@@ -37,7 +37,7 @@
import net.sf.practicalxml.DomUtil;
import net.sf.practicalxml.converter.ConversionException;
-import net.sf.practicalxml.converter.ConversionHelper;
+import net.sf.practicalxml.converter.internal.ConversionHelper;
import net.sf.practicalxml.internal.StringUtils;
import org.w3c.dom.Element;
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java 2009-08-18 17:41:38 UTC (rev 112)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java 2009-08-18 17:57:48 UTC (rev 113)
@@ -18,7 +18,7 @@
import net.sf.practicalxml.XmlException;
import net.sf.practicalxml.XmlUtil;
import net.sf.practicalxml.converter.ConversionException;
-import net.sf.practicalxml.converter.ConversionHelper;
+import net.sf.practicalxml.converter.internal.ConversionHelper;
import net.sf.practicalxml.internal.StringUtils;
import java.util.Arrays;
Copied: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionHelper.java (from rev 110, branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/ConversionHelper.java)
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionHelper.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionHelper.java 2009-08-18 17:57:48 UTC (rev 113)
@@ -0,0 +1,480 @@
+// 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.internal;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sf.practicalxml.XmlUtil;
+import net.sf.practicalxml.converter.ConversionException;
+
+
+/**
+ * Responsible for converting "primitive" types -- those with unambiguous
+ * string representations -- to/from such a representation.
+ */
+public class ConversionHelper
+{
+ private static Map<String,Class<?>> XSD_TYPE_TO_JAVA_CLASS
+ = new HashMap<String,Class<?>>();
+ static
+ {
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:string", String.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:boolean", Boolean.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:byte", Byte.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:short", Short.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:int", Integer.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:long", Long.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:decimal", BigDecimal.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:dateTime", Date.class);
+ }
+
+
+ // this is not static because the helpers are inner classes
+ private Map<Class<?>,ConversionHandler<?>> _helpers
+ = new HashMap<Class<?>,ConversionHandler<?>>();
+ {
+ _helpers.put(String.class, new StringConversionHandler());
+ _helpers.put(Character.class, new CharacterConversionHandler());
+ _helpers.put(Boolean.class, new BooleanConversionHandler());
+ _helpers.put(Byte.class, new ByteConversionHandler());
+ _helpers.put(Short.class, new ShortConversionHandler());
+ _helpers.put(Integer.class, new IntegerConversionHandler());
+ _helpers.put(Long.class, new LongConversionHandler());
+ _helpers.put(Float.class, new FloatConversionHandler());
+ _helpers.put(Double.class, new DoubleConversionHandler());
+ _helpers.put(BigInteger.class, new BigIntegerConversionHandler());
+ _helpers.put(BigDecimal.class, new BigDecimalConversionHandler());
+ _helpers.put(Date.class, new DateConversionHandler());
+
+ _helpers.put(Boolean.TYPE, new BooleanConversionHandler());
+ _helpers.put(Byte.TYPE, new ByteConversionHandler());
+ _helpers.put(Short.TYPE, new ShortConversionHandler());
+ _helpers.put(Integer.TYPE, new IntegerConversionHandler());
+ _helpers.put(Long.TYPE, new LongConversionHandler());
+ _helpers.put(Float.TYPE, new FloatConversionHandler());
+ _helpers.put(Double.TYPE, new DoubleConversionHandler());
+ }
+
+ private boolean _useXsdFormatting;
+
+
+ /**
+ * Default constructor, which uses Java formatting.
+ */
+ public ConversionHelper()
+ {
+ // nothing to see here
+ }
+
+
+ /**
+ * Constructor that allows selection of Java or XSD formatting.
+ */
+ public ConversionHelper(boolean useXsdFormatting)
+ {
+ _useXsdFormatting = useXsdFormatting;
+ }
+
+
+//----------------------------------------------------------------------------
+// Public Methods
+//----------------------------------------------------------------------------
+
+ /**
+ * Returns the XSD type name to use for stringified objects of the
+ * specified class, <code>null</code> if this converter can't convert
+ * instances of the class.
+ */
+ public String getXsdType(Class<?> klass)
+ {
+ ConversionHandler<?> helper = _helpers.get(klass);
+ return (helper == null) ? null : helper.getXsiType();
+ }
+
+
+ /**
+ * Returns the Java type that best matches the given Schema type name,
+ * <code>null</code> if we do not have an appropriate mapping.
+ */
+ public Class<?> getJavaType(String xsdTypename)
+ {
+ return XSD_TYPE_TO_JAVA_CLASS.get(xsdTypename);
+ }
+
+
+ /**
+ * Converts the passed object into its string representation, according
+ * to the options currently in effect. Passing <code>null</code> will
+ * return <code>null</code>. Throws {@link ConversionException} if
+ * unable to convert the passed object.
+ */
+ public String stringify(Object obj)
+ {
+ if (obj == null)
+ return null;
+
+ try
+ {
+ return getHelper(obj.getClass()).stringify(obj);
+ }
+ catch (Exception ee)
+ {
+ if (ee instanceof ConversionException)
+ throw (ConversionException)ee;
+ throw new ConversionException("unable to convert: " + obj, ee);
+ }
+ }
+
+
+ /**
+ * Parses the passed string into an object of the desired class. Passing
+ * <code>null</code> will return <code>null</code>, passing an empty
+ * string will typically throw a {@link ConversionException}.
+ */
+ public Object parse(String str, Class<?> klass)
+ {
+ if (str == null)
+ return null;
+
+ try
+ {
+ return getHelper(klass).parse(str);
+ }
+ catch (Exception ee)
+ {
+ if (ee instanceof ConversionException)
+ throw (ConversionException)ee;
+ throw new ConversionException("unable to parse: " + str, ee);
+ }
+ }
+
+
+//----------------------------------------------------------------------------
+// Internals
+//----------------------------------------------------------------------------
+
+ /**
+ * Returns the appropriate conversion helper or throws.
+ */
+ @SuppressWarnings(value="unchecked")
+ private ConversionHandler getHelper(Class<?> klass)
+ {
+ ConversionHandler<?> helper = _helpers.get(klass);
+ if (helper == null)
+ throw new ConversionException("unable to get helper: " + klass.getName());
+ return helper;
+ }
+
+
+ /**
+ * Each primitive class has its own conversion handler that is responsible
+ * for converting to/from a string representation. Handlers are guaranteed
+ * to receive non-null objects/strings.
+ * <p>
+ * This interface is parameterized so that the compiler will generate
+ * bridge methods for implementation classes. Elsewhere, we don't care
+ * about parameterization, so wildcard or drop it (see {@link #getHelper}).
+ * <p>
+ * Implementation classes are expected to be inner classes, so that they
+ * have access to configuration information (such as formatting rules).
+ * <p>
+ * Implementation classes are permitted to throw any exception; caller is
+ * expected to catch them and translate to a {@link ConversionException}.
+ */
+ private static interface ConversionHandler<T>
+ {
+ public String getXsiType();
+ public String stringify(T obj) throws Exception;
+ public T parse(String str) throws Exception;
+ }
+
+
+ private class StringConversionHandler
+ implements ConversionHandler<String>
+ {
+ public String getXsiType()
+ {
+ return "xsd:string";
+ }
+
+ public String stringify(String obj)
+ {
+ return String.valueOf(obj);
+ }
+
+ public String parse(String str)
+ {
+ return str;
+ }
+ }
+
+
+ private class CharacterConversionHandler
+ implements ConversionHandler<Character>
+ {
+ private final Character NUL = Character.valueOf('\0');
+
+ public String getXsiType()
+ {
+ return "xsd:string";
+ }
+
+ public String stringify(Character obj)
+ {
+ if (obj.equals(NUL))
+ return "";
+ return obj.toString();
+ }
+
+ public Character parse(String str)
+ {
+ if (str.length() == 0)
+ return NUL;
+ if (str.length() > 1)
+ throw new ConversionException(
+ "attempted to convert multi-character string: \"" + str + "\"");
+ return Character.valueOf(str.charAt(0));
+ }
+ }
+
+
+ private class BooleanConversionHandler
+ implements ConversionHandler<Boolean>
+ {
+ public String getXsiType()
+ {
+ return "xsd:boolean";
+ }
+
+ public String stringify(Boolean obj)
+ {
+ return _useXsdFormatting
+ ? XmlUtil.formatXsdBoolean(obj.booleanValue())
+ : obj.toString();
+ }
+
+ public Boolean parse(String str)
+ {
+ return _useXsdFormatting
+ ? XmlUtil.parseXsdBoolean(str)
+ : Boolean.parseBoolean(str);
+ }
+ }
+
+
+ private class ByteConversionHandler
+ implements ConversionHandler<Byte>
+ {
+ public String getXsiType()
+ {
+ return "xsd:byte";
+ }
+
+ public String stringify(Byte obj)
+ {
+ return obj.toString();
+ }
+
+ public Byte parse(String str)
+ {
+ return Byte.valueOf(str.trim());
+ }
+ }
+
+
+ private class ShortConversionHandler
+ implements ConversionHandler<Short>
+ {
+ public String getXsiType()
+ {
+ return "xsd:short";
+ }
+
+ public String stringify(Short obj)
+ {
+ return obj.toString();
+ }
+
+ public Short parse(String str)
+ {
+ return Short.valueOf(str.trim());
+ }
+ }
+
+
+ private class IntegerConversionHandler
+ implements ConversionHandler<Integer>
+ {
+ public String getXsiType()
+ {
+ return "xsd:int";
+ }
+
+ public String stringify(Integer obj)
+ {
+ return obj.toString();
+ }
+
+ public Integer parse(String str)
+ {
+ return Integer.valueOf(str.trim());
+ }
+ }
+
+
+ private class LongConversionHandler
+ implements ConversionHandler<Long>
+ {
+ public String getXsiType()
+ {
+ return "xsd:long";
+ }
+
+ public String stringify(Long obj)
+ {
+ return obj.toString();
+ }
+
+ public Long parse(String str)
+ {
+ return Long.valueOf(str.trim());
+ }
+ }
+
+
+ private class FloatConversionHandler
+ implements ConversionHandler<Float>
+ {
+ public String getXsiType()
+ {
+ return "xsd:decimal";
+ }
+
+ public String stringify(Float obj)
+ {
+ return _useXsdFormatting
+ ? XmlUtil.formatXsdDecimal(obj)
+ : obj.toString();
+ }
+
+ public Float parse(String str)
+ {
+ return Float.valueOf(str.trim());
+ }
+ }
+
+
+ private class DoubleConversionHandler
+ implements ConversionHandler<Double>
+ {
+ public String getXsiType()
+ {
+ return "xsd:decimal";
+ }
+
+ public String stringify(Double obj)
+ {
+ return _useXsdFormatting
+ ? XmlUtil.formatXsdDecimal(obj)
+ : obj.toString();
+ }
+
+ public Double parse(String str)
+ {
+ return Double.valueOf(str.trim());
+ }
+ }
+
+
+ private class BigIntegerConversionHandler
+ implements ConversionHandler<BigInteger>
+ {
+ public String getXsiType()
+ {
+ return "xsd:decimal";
+ }
+
+ public String stringify(BigInteger obj)
+ {
+ return obj.toString();
+ }
+
+ public BigInteger parse(String str)
+ {
+ return new BigInteger(str.trim());
+ }
+ }
+
+
+ private class BigDecimalConversionHandler
+ implements ConversionHandler<BigDecimal>
+ {
+ public String getXsiType()
+ {
+ return "xsd:decimal";
+ }
+
+ public String stringify(BigDecimal obj)
+ {
+ return obj.toString();
+ }
+
+ public BigDecimal parse(String str)
+ {
+ return new BigDecimal(str.trim());
+ }
+ }
+
+
+ private class DateConversionHandler
+ implements ConversionHandler<Date>
+ {
+ // format as specified by Date.toString() JavaDoc
+ private DateFormat _defaultFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
+
+ public String getXsiType()
+ {
+ return "xsd:dateTime";
+ }
+
+ public String stringify(Date obj)
+ {
+ return _useXsdFormatting
+ ? XmlUtil.formatXsdDatetime(obj)
+ : obj.toString();
+ }
+
+ public Date parse(String str)
+ throws ParseException
+ {
+ if (_useXsdFormatting)
+ return XmlUtil.parseXsdDatetime(str);
+ else
+ {
+ synchronized (_defaultFormat)
+ {
+ return _defaultFormat.parse(str);
+ }
+ }
+ }
+ }
+}
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestConversionHelper.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestConversionHelper.java 2009-08-18 17:41:38 UTC (rev 112)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestConversionHelper.java 2009-08-18 17:57:48 UTC (rev 113)
@@ -18,7 +18,9 @@
import java.math.BigInteger;
import java.util.Date;
+import net.sf.practicalxml.converter.internal.ConversionHelper;
+
public class TestConversionHelper
extends AbstractBeanConverterTestCase
{
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-08-18 17:41:55
|
Revision: 112
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=112&view=rev
Author: kdgregory
Date: 2009-08-18 17:41:38 +0000 (Tue, 18 Aug 2009)
Log Message:
-----------
change BeanConverter API, write tests for it
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/BeanConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractBeanConverterTestCase.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBeanConverter.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-08-17 20:24:04 UTC (rev 111)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/BeanConverter.java 2009-08-18 17:41:38 UTC (rev 112)
@@ -19,6 +19,8 @@
import net.sf.practicalxml.converter.bean.Bean2XmlDriver;
import net.sf.practicalxml.converter.bean.Bean2XmlOptions;
+import net.sf.practicalxml.converter.bean.Xml2BeanDriver;
+import net.sf.practicalxml.converter.bean.Xml2BeanOptions;
/**
@@ -26,11 +28,13 @@
* Originally developed to support simple web services, without the overhead
* (schema definitions and/or annotations) required by JAXB.
* <p>
- * A single instance handles 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 distinct operations.
- * Note that, depending on options settings, output generated by one converter
- * may not be valid input for another.
+ * 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.
* <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
@@ -140,15 +144,50 @@
* </table>
*
* <strong>Warning</strong>:
- * this class makes use of <code>java.beans.Introspector</code>, which holds
- * a cache of introspected objects. If you use this converter in an app-server
- * you should call <code>Introspector.flushCaches()</code> during deploy.
+ * <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.
*/
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.
+ * are members of the specified namespace and will inherit the root's
+ * prefix (if any).
*
* @param bean The source object. This can be any Java object:
* bean, collection, or simple type.
@@ -157,14 +196,10 @@
* @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 Options controlling output.
-.
*/
- public static Document generateXml(Object bean, String nsUri, String rootName,
- Bean2XmlOptions... options)
+ public Element convertToXml(Object bean, String nsUri, String rootName)
{
- Bean2XmlDriver driver = new Bean2XmlDriver(options);
- return driver.convert(bean, nsUri, rootName).getOwnerDocument();
+ return _outputDriver.convert(bean, nsUri, rootName);
}
@@ -175,13 +210,37 @@
* bean, collection, or simple type.
* @param rootName The name given to the root element of the produced
* document.
- * @param options Options controlling output.
-.
*/
- public static Document generateXml(Object bean, String rootName,
- Bean2XmlOptions... options)
+ public Element convertToXml(Object bean, String rootName)
{
- Bean2XmlDriver driver = new Bean2XmlDriver(options);
- return driver.convert(bean, rootName).getOwnerDocument();
+ return _outputDriver.convert(bean, rootName);
}
+
+
+ /**
+ * Creates a new Java object from the root of the passed <code>Document
+ * </code>.
+ *
+ * @param dom The source document.
+ * @param klass The desired class to instantiate and fill from this
+ * document.
+ */
+ public <T> T convertToJava(Document dom, Class<T> klass)
+ {
+ return convertToJava(dom.getDocumentElement(), klass);
+ }
+
+
+ /**
+ * Creates a new Java object from the the passed DOM <code>Element</code>.
+ *
+ * @param dom The source element -- this may or may not be the
+ * root element of its document.
+ * @param klass The desired class to instantiate and fill from this
+ * document.
+ */
+ public <T> T convertToJava(Element root, Class<T> klass)
+ {
+ return _inputDriver.convert(root, klass);
+ }
}
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractBeanConverterTestCase.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractBeanConverterTestCase.java 2009-08-17 20:24:04 UTC (rev 111)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractBeanConverterTestCase.java 2009-08-18 17:41:38 UTC (rev 112)
@@ -16,6 +16,7 @@
import java.math.BigDecimal;
import java.math.BigInteger;
+import java.util.Arrays;
import java.util.Date;
import java.util.List;
@@ -23,6 +24,8 @@
import org.w3c.dom.Element;
+import junit.framework.Assert;
+
import net.sf.practicalxml.AbstractTestCase;
import net.sf.practicalxml.DomUtil;
@@ -120,6 +123,15 @@
public boolean isBval() { return _bval; }
public void setBval(boolean bval) { _bval = bval; }
+
+ public void assertEquals(SimpleBean that)
+ {
+ assertNotNull(that);
+ Assert.assertEquals("sval", _sval, that._sval);
+ Assert.assertEquals("ival", _ival, that._ival);
+ Assert.assertEquals("dval", _dval, that._dval);
+ Assert.assertEquals("bval", _bval, that._bval);
+ }
}
@@ -150,6 +162,13 @@
public List<String> getStringList() { return _stringList; }
public void setStringList(List<String> list) { _stringList = list; }
+
+ public void assertEquals(CompoundBean that)
+ {
+ _simple.assertEquals(that._simple);
+ Assert.assertTrue("primArray", Arrays.equals(_primArray, that._primArray));
+ Assert.assertEquals("stringlist", _stringList, that._stringList);
+ }
}
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBeanConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBeanConverter.java 2009-08-17 20:24:04 UTC (rev 111)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBeanConverter.java 2009-08-18 17:41:38 UTC (rev 112)
@@ -14,19 +14,34 @@
package net.sf.practicalxml.converter;
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
import net.sf.practicalxml.DomUtil;
import net.sf.practicalxml.OutputUtil;
import net.sf.practicalxml.converter.bean.Bean2XmlOptions;
+import net.sf.practicalxml.converter.bean.Xml2BeanOptions;
+import net.sf.practicalxml.junit.DomAsserts;
-import javax.xml.XMLConstants;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
/**
- * Tests for the top-level <code>BeanConverter</code> methods. These are
- * minimal; the detailed testing happens in {@link TestBean2XmlDriver}
- * and {@link TestXml2BeanDriver}.
+ * Tests for the top-level <code>BeanConverter</code> methods. These are all
+ * "out and back" tests to verify that we can read the XML that we produce
+ * (and to show cases where we can't). Detailed tests (verifying specific
+ * output) are in {@link TestBean2XmlDriver} and {@link TestXml2BeanDriver}.
+ * <p>
+ * Note that each conversion has a commented-out line that will print the
+ * generated XML. Uncommenting these lines may help you understand how
+ * conversion works in particular cases.
*/
public class TestBeanConverter
extends AbstractBeanConverterTestCase
@@ -41,41 +56,368 @@
// Support Code
//----------------------------------------------------------------------------
+ private static void assertConversionError(
+ String message, BeanConverter converter, Element elem, Class<?> klass)
+ {
+ try
+ {
+ converter.convertToJava(elem, klass);
+ fail(message);
+ }
+ catch (ConversionException ee)
+ { /* success */ }
+ }
//----------------------------------------------------------------------------
// Test Cases
//----------------------------------------------------------------------------
- public void testGenerateSimpleContentSansNamespace() throws Exception
+ // an initial test to verify everything works
+ public void testConvertStringDefault() throws Exception
{
- String rootName = "argle";
- String value = "foo";
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
- Document dom = BeanConverter.generateXml(value, rootName, Bean2XmlOptions.XSI_TYPE);
-// System.out.println(OutputUtil.compactString(dom));
+ String obj = "this is a test";
+ Element root = outConverter.convertToXml(obj, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+ assertEquals("test", DomUtil.getLocalName(root));
- Element root = dom.getDocumentElement();
- assertEquals(rootName, root.getNodeName());
- assertEquals(value, root.getTextContent());
- assertEquals("xsd:string", root.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type"));
- assertEquals(0, DomUtil.getChildren(root).size());
+ Object result = inConverter.convertToJava(root, String.class);
+ assertEquals(obj, result);
}
- public void testGenerateSimpleContentWithNamespace() throws Exception
+ public void testConvertPrimitiveDefault() throws Exception
{
- String nsUri = "urn:fibble";
- String rootName = "argle:bargle";
- String value = "foo";
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
- Document dom = BeanConverter.generateXml(value, nsUri, rootName, Bean2XmlOptions.XSI_TYPE);
+ for (PrimitiveValue value : PRIMITIVE_VALUES)
+ {
+ Object obj = value.getValue();
+ Element root = outConverter.convertToXml(obj, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ Object result = inConverter.convertToJava(root, value.getKlass());
+ assertEquals(obj, result);
+ }
+ }
+
+
+ public void testConvertPrimitiveFormatXsd() throws Exception
+ {
+ BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.XSD_FORMAT);
+ BeanConverter inConverter = new BeanConverter(Xml2BeanOptions.EXPECT_XSD_FORMAT);
+
+ for (PrimitiveValue value : PRIMITIVE_VALUES)
+ {
+ Object obj = value.getValue();
+ Element root = outConverter.convertToXml(obj, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ Object result = inConverter.convertToJava(root, value.getKlass());
+ assertEquals(obj, result);
+ }
+ }
+
+
+ public void testConvertNullDefault() throws Exception
+ {
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(null, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ Object result = inConverter.convertToJava(root, String.class);
+ assertNull(result);
+ }
+
+
+ public void testConvertNullUseAndRequireXsiNil() throws Exception
+ {
+ BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.XSI_NIL);
+ BeanConverter inConverter = new BeanConverter(Xml2BeanOptions.REQUIRE_XSI_NIL);
+
+ Element root = outConverter.convertToXml(null, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ Object result = inConverter.convertToJava(root, String.class);
+ assertNull(result);
+ }
+
+
+ public void testConvertNullFailureRequireXsiNil() throws Exception
+ {
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter(Xml2BeanOptions.REQUIRE_XSI_NIL);
+
+ Element root = outConverter.convertToXml(null, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ assertConversionError("accepted DOM with null entry but no xsi:nil",
+ inConverter, root, String.class);
+ }
+
+
+ public void testPrimitiveArrayDefault() throws Exception
+ {
+ int[] data = new int[] { 1, 2, 4, 5 };
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ int[] result = inConverter.convertToJava(root, int[].class);
+ assertTrue(Arrays.equals(data, result));
+ }
+
+
+ public void testStringListDefault() throws Exception
+ {
+ List<String> data = Arrays.asList("foo", "bar", "baz");
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ List<String> result = inConverter.convertToJava(root, List.class);
+ assertEquals(data, result);
+ }
+
+
+ // demonstrates that the list will be read as List<String> even though
+ // it was written as List<Integer>
+ public void testIntegerListDefault() throws Exception
+ {
+ List<Integer> data = Arrays.asList(1, 2, 3);
+ assert(data.get(0) instanceof Integer);
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ List<?> result = inConverter.convertToJava(root, List.class);
+ assertTrue(result instanceof List);
+ assertTrue(result.get(0) instanceof String);
+ }
+
+
+ // demonstrates that you don't need to require xsi:type to use it
+ public void testIntegerListWithXsiType() throws Exception
+ {
+ List<Integer> data = Arrays.asList(1, 2, 3);
+ assert(data.get(0) instanceof Integer);
+
+ BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.XSI_TYPE);
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ List<?> result = inConverter.convertToJava(root, List.class);
+ assertEquals(data, result);
+ }
+
+
+ // demonstrates that the caller drives the inbound conversion
+ public void testConvertListToSortedSet() throws Exception
+ {
+ List<String> data = Arrays.asList("foo", "bar", "baz", "bar");
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ Set<?> result = inConverter.convertToJava(root, SortedSet.class);
+ Iterator<?> itx = result.iterator();
+ assertEquals("bar", itx.next());
+ assertEquals("baz", itx.next());
+ assertEquals("foo", itx.next());
+ assertFalse(itx.hasNext());
+ }
+
+
+ public void testMapDefault() throws Exception
+ {
+ Map<String,String> data = new HashMap<String,String>();
+ data.put("foo", "argle");
+ data.put("bar", "bargle");
+ data.put("baz", "bazgle");
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ DomAsserts.assertCount(3, root, "/test/data");
+ DomAsserts.assertCount(1, root, "/test/data[@key='foo']");
+ DomAsserts.assertEquals("argle", root, "/test/data[@key='foo']");
+
+ Map<?,?> result = inConverter.convertToJava(root, Map.class);
+ assertEquals(data, result);
+ }
+
+
+ // demonstrates that the input converter handles either format by default
+ public void testMapIntrospected() throws Exception
+ {
+ Map<String,String> data = new HashMap<String,String>();
+ data.put("foo", "argle");
+ data.put("bar", "bargle");
+ data.put("baz", "bazgle");
+
+ BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.INTROSPECT_MAPS);
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ DomAsserts.assertCount(0, root, "/test/data");
+ DomAsserts.assertCount(1, root, "/test/foo");
+ DomAsserts.assertEquals("argle", root, "/test/foo");
+
+ Map<?,?> result = inConverter.convertToJava(root, Map.class);
+ assertEquals(data, result);
+ }
+
+
+ public void testSimpleBeanDefault() throws Exception
+ {
+ SimpleBean data = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ SimpleBean result = inConverter.convertToJava(root, SimpleBean.class);
+ data.assertEquals(result);
+ }
+
+
+ public void testSimpleBeanRequireXsiType() throws Exception
+ {
+ SimpleBean data = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
+
+ BeanConverter outconverter1 = new BeanConverter(Bean2XmlOptions.XSI_TYPE);
+ BeanConverter outconverter2 = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter(Xml2BeanOptions.REQUIRE_XSI_TYPE);
+
+ Element valid = outconverter1.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(valid.getOwnerDocument()));
+
+ SimpleBean result = inConverter.convertToJava(valid, SimpleBean.class);
+ data.assertEquals(result);
+
+ Element invalid = outconverter2.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(invalid.getOwnerDocument()));
+
+ assertConversionError("converter requiring xsi:type accepted XML without",
+ inConverter, invalid, SimpleBean.class);
+ }
+
+
+ public void testListOfSimpleBeanWithXsiTypeAndNulls() throws Exception
+ {
+ SimpleBean bean1 = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
+ SimpleBean bean2 = new SimpleBean("zyx", 987, null, false);
+ List<SimpleBean> data = Arrays.asList(bean1, bean2);
+
+ BeanConverter outConverter = new BeanConverter(Bean2XmlOptions.XSI_TYPE);
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ List<SimpleBean> result = inConverter.convertToJava(root, List.class);
+ assertEquals(2, result.size());
+ bean1.assertEquals(result.get(0));
+ bean2.assertEquals(result.get(1));
+ }
+
+
+ // another demonstration that caller drives input conversion
+ // ... and note that we don't care about xsi:type in this case
+ public void testListOfSimpleBeanToArrayOfSame() throws Exception
+ {
+ SimpleBean bean1 = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
+ SimpleBean bean2 = new SimpleBean("zyx", 987, null, false);
+ List<SimpleBean> data = Arrays.asList(bean1, bean2);
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ SimpleBean[] result = inConverter.convertToJava(root, SimpleBean[].class);
+ assertEquals(2, result.length);
+ bean1.assertEquals(result[0]);
+ bean2.assertEquals(result[1]);
+ }
+
+
+ public void testCompoundBeanDefault() throws Exception
+ {
+ CompoundBean data = new CompoundBean(
+ new SimpleBean("abc", 123, new BigDecimal("456.789"), true),
+ new int[] { 1, 5, 7, 9 },
+ Arrays.asList("foo", "bar", "baz"));
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ CompoundBean result = inConverter.convertToJava(root, CompoundBean.class);
+ data.assertEquals(result);
+ }
+
+
+ public void testSimpleBeanWithNamespace() throws Exception
+ {
+ SimpleBean data = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Element root = outConverter.convertToXml(data, "urn:foo", "bar:test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ Element child = DomUtil.getChild(root, "sval");
+ assertEquals("urn:foo", child.getNamespaceURI());
+ assertEquals("bar", child.getPrefix());
+
+ SimpleBean result = inConverter.convertToJava(root, SimpleBean.class);
+ data.assertEquals(result);
+ }
+
+
+ // this one is here just for coverage
+ public void testSimpleBeanFromDocument() throws Exception
+ {
+ SimpleBean data = new SimpleBean("abc", 123, new BigDecimal("456.789"), true);
+
+ BeanConverter outConverter = new BeanConverter();
+ BeanConverter inConverter = new BeanConverter();
+
+ Document dom = outConverter.convertToXml(data, "test").getOwnerDocument();
// System.out.println(OutputUtil.compactString(dom));
- Element root = dom.getDocumentElement();
- assertEquals(nsUri, root.getNamespaceURI());
- assertEquals(rootName, root.getNodeName());
- assertEquals(value, root.getTextContent());
- assertEquals("xsd:string", root.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type"));
- assertEquals(0, DomUtil.getChildren(root).size());
+ SimpleBean result = inConverter.convertToJava(dom, SimpleBean.class);
+ data.assertEquals(result);
}
}
\ No newline at end of file
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-08-17 20:24:31
|
Revision: 111
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=111&view=rev
Author: kdgregory
Date: 2009-08-17 20:24:04 +0000 (Mon, 17 Aug 2009)
Log Message:
-----------
update comments
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/Xml2BeanDriver.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/package.html
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-08-17 17:26:40 UTC (rev 110)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/BeanConverter.java 2009-08-17 20:24:04 UTC (rev 111)
@@ -15,60 +15,162 @@
package net.sf.practicalxml.converter;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
import net.sf.practicalxml.converter.bean.Bean2XmlDriver;
import net.sf.practicalxml.converter.bean.Bean2XmlOptions;
/**
- * Converts Java objects (not just beans) to and from an XML representation.
- * This was originally developed to support RESTful web services, without the
- * class-generation hassle of JAXB.
+ * 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.
* <p>
- * The XML generated/consumed by this class obeys the following rules, with
- * options controlled by {@link Bean2XmlOptions}:
- * <ul>
- * <li> All elements inherit their parent's namespace and namespace prefix.
- * <li> Elements of sets are output using the element name "data".
- * <li> Elements of lists and arrays are output using the element name "data",
- * with an attribute "index" that contains the numeric index.
- * <li> Elements of maps are by default output using the name "data", with an
- * attribute "name" containing the actual map key. The output option
- * <code>INTROSPECT_MAPS</code> will change this behavior, but will throw
- * if the map keys are not valid XML element names.
- * <li> Values are output using <code>toString()</code>, except as overridden
- * by options.
- * <li> Null values do not generate output, unless the <code>XSI_NIL</code>
- * option is in effect.
- * </ul>
+ * A single instance handles 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 distinct operations.
+ * Note that, depending on options settings, output generated by one converter
+ * may not be valid input for another.
+ * <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>:
+ * this class makes use of <code>java.beans.Introspector</code>, which holds
+ * a cache of introspected objects. If you use this converter in an app-server
+ * you should call <code>Introspector.flushCaches()</code> during deploy.
*/
public class BeanConverter
{
/**
* Creates a new DOM document from the passed bean, in which all elements
* are members of the specified namespace.
- *
+ *
* @param bean The source object. This can be any Java object:
* bean, collection, or simple type.
* @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
+ * @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 Options controlling output.
.
*/
- public static Document generateXml(Object bean, String nsUri, String rootName,
+ public static Document generateXml(Object bean, String nsUri, String rootName,
Bean2XmlOptions... options)
{
Bean2XmlDriver driver = new Bean2XmlDriver(options);
return driver.convert(bean, nsUri, rootName).getOwnerDocument();
}
-
-
+
+
/**
* Creates a new DOM document from the passed bean, without namespace.
- *
+ *
* @param bean The source object. This can be any Java object:
* bean, collection, or simple type.
* @param rootName The name given to the root element of the produced
@@ -76,7 +178,7 @@
* @param options Options controlling output.
.
*/
- public static Document generateXml(Object bean, String rootName,
+ public static Document generateXml(Object bean, String rootName,
Bean2XmlOptions... options)
{
Bean2XmlDriver driver = new Bean2XmlDriver(options);
Modified: 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-08-17 17:26:40 UTC (rev 110)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanDriver.java 2009-08-17 20:24:04 UTC (rev 111)
@@ -48,31 +48,6 @@
* 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.
- * <p>
- * This class assumes that the source XML will be in the form produced by
- * {@link Bean2XmlDriver}: each element either contains child elements, or
- * a text node containing the element's value. However, conversion is
- * driven by the parameters passed to {@link #convert}, not by the content
- * of the XML document; this can lead to some unexpected behavior:
- * <ul>
- * <li> Bean classes are introspected, and recursively processed base on
- * the property descriptors. If the bean has multiple setter methods
- * for a property, the method selected is arbitrarily chosen by the
- * JavaBeans introspector. You can pass an option that looks for a
- * setters using <code>String</code>, but this is not recommended
- * from a performance perspective.
- * <li> JDK collection types do not carry type information, so the only
- * way to properly convert them is using an <code>xsi:type</code>
- * attribute on the child elements. If this attribute is missing
- * or cannot be interpreted, the element will be processed as if
- * it is a <code>String</code>.
- * <li> The converter will to pick an appropriate implementation class
- * if given one of the JDK collections interfaces: <code>
- * ArrayList</code> for <code>List</code> or <code>Collection</code>,
- * <code>TreeSet</code> for <code>SortedSet</code>, <code>HashSet</code>
- * for any other <code>Set</code>, and likewise <code>TreeMap</code> and
- * <code>HashMap</code> for <code>SortedMap</code> and <code>Map</code>.
- * </ul>
*/
public class Xml2BeanDriver
{
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/package.html
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/package.html 2009-08-17 17:26:40 UTC (rev 110)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/package.html 2009-08-17 20:24:04 UTC (rev 111)
@@ -1,6 +1,15 @@
<html>
<body>
This package contains classes to convert between XML and a variety of
- other formats.
+ other formats. Each conversion has a top-level convenience class in
+ this package, which handles common conversion scenarios and provides
+ overall documentation on the conversion. Sub-packages contain the
+ actual conversion classes; you may need to use those classes directly
+ for "unusual" conversions.
+ <p>
+ Any problems during conversion (in either direction) are reported via
+ {@link ConversionException}, which is a runtime exception and will
+ wrap any actual exception. If appropriate, this exception will also
+ contain the XPath to the node failing conversion.
</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-08-17 17:26:48
|
Revision: 110
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=110&view=rev
Author: kdgregory
Date: 2009-08-17 17:26:40 +0000 (Mon, 17 Aug 2009)
Log Message:
-----------
repackage
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/BeanConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlAppenders.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlDriver.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBeanConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanDriver.java
Added Paths:
-----------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/
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/Bean2XmlDriver.java
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/Xml2BeanDriver.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanOptions.java
Removed Paths:
-------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean2xml/
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/xml2bean/
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-08-17 17:13:36 UTC (rev 109)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/BeanConverter.java 2009-08-17 17:26:40 UTC (rev 110)
@@ -16,8 +16,8 @@
import org.w3c.dom.Document;
-import net.sf.practicalxml.converter.bean2xml.Bean2XmlDriver;
-import net.sf.practicalxml.converter.bean2xml.Bean2XmlOptions;
+import net.sf.practicalxml.converter.bean.Bean2XmlDriver;
+import net.sf.practicalxml.converter.bean.Bean2XmlOptions;
/**
Copied: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java (from rev 100, branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean2xml/Bean2XmlAppenders.java)
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java 2009-08-17 17:26:40 UTC (rev 110)
@@ -0,0 +1,235 @@
+// 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.util.EnumSet;
+
+import javax.xml.XMLConstants;
+
+import org.w3c.dom.Element;
+
+import net.sf.practicalxml.DomUtil;
+
+
+/**
+ * Packaging class used for XML output appenders. This class is a temporary
+ * hack, as I move intelligence into {@link Bean2XmlDriver}; the contained
+ * classes will end up in a new package, once I figure out what the package
+ * structure should be.
+ */
+public abstract class Bean2XmlAppenders
+{
+ /**
+ * An <code>Appender</code> appends children to a single node of the
+ * output tree. The driver is responsible for creating new appenders
+ * for each compound element, including the root, and providing those
+ * appenders with options to control output generation.
+ */
+ public interface Appender
+ {
+ /**
+ * Appends a value element to the current element. Value elements have
+ * associated text, but no other children.
+ *
+ * @param name Name to be associated with the node.
+ * @param type Type to be associated with the node; may or may
+ * not be written to the output, depending on the
+ * appender's options.
+ * @param value The node's value. May be <code>null</code>, in
+ * which case the appender decides whether or not
+ * to actually append the node.
+ *
+ * @return The appended element. This is a convenience for subclasses,
+ * which may want to set additional attributes after their
+ * super has done the work of appending the element.
+ * @throws ConversionException if unable to append the node.
+ */
+ public Element appendValue(String name, String type, String value);
+
+
+ /**
+ * Appends a container element to the current element. Container
+ * elements have other elements as children, and may have a type,
+ * but do not have an associated value.
+ */
+ public Element appendContainer(String name, String type);
+ }
+
+
+ /**
+ * Base class for XML appenders, providing helper methods for subclasses.
+ */
+ private static abstract class AbstractAppender
+ implements Appender
+ {
+ private EnumSet<Bean2XmlOptions> _options;
+
+ public AbstractAppender(EnumSet<Bean2XmlOptions> options)
+ {
+ _options = options;
+ }
+
+ protected boolean isOptionSet(Bean2XmlOptions option)
+ {
+ return _options.contains(option);
+ }
+
+ protected boolean shouldSkip(Object value)
+ {
+ return (value == null) && !_options.contains(Bean2XmlOptions.XSI_NIL);
+ }
+
+ protected void setType(Element elem, String type)
+ {
+ if (isOptionSet(Bean2XmlOptions.XSI_TYPE))
+ elem.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type", type);
+ }
+
+ protected void setValue(Element elem, String value)
+ {
+ if (value != null)
+ DomUtil.setText(elem, value);
+ else if (isOptionSet(Bean2XmlOptions.XSI_NIL))
+ elem.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil", "true");
+ }
+ }
+
+
+ /**
+ * Basic appender, which appends new elements to a parent.
+ */
+ public static class BasicAppender
+ extends AbstractAppender
+ {
+ private Element _parent;
+
+ public BasicAppender(Element parent, EnumSet<Bean2XmlOptions> options)
+ {
+ super(options);
+ _parent = parent;
+ }
+
+ public Element appendValue(String name, String type, String value)
+ {
+ if (shouldSkip(value))
+ return null;
+
+ Element child = DomUtil.appendChildInheritNamespace(_parent, name);
+ setType(child, type);
+ setValue(child, value);
+ return child;
+ }
+
+ public Element appendContainer(String name, String type)
+ {
+ Element child = DomUtil.appendChildInheritNamespace(_parent, name);
+ setType(child, type);
+ return child;
+ }
+ }
+
+
+ /**
+ * Appender for children of an indexed/iterated item (array, list, or set).
+ * Each element will have an incremented <code>index</code> attribute that
+ * indicates the position of the element within the iteration.
+ */
+ public static class IndexedAppender
+ extends BasicAppender
+ {
+ int _index = 0;
+
+ public IndexedAppender(Element parent, EnumSet<Bean2XmlOptions> options)
+ {
+ super(parent, options);
+ }
+
+
+ @Override
+ public Element appendValue(String name, String type, String value)
+ {
+ Element child = super.appendValue(name, type, value);
+ if (child != null)
+ child.setAttribute("index", String.valueOf(_index++));
+ return child;
+ }
+ }
+
+
+ /**
+ * Appender for children of a <code>Map</code>. Depending on options,
+ * will either create children named after the key, or a generic "data"
+ * child with the key as an attribute.
+ */
+ public static class MapAppender
+ extends BasicAppender
+ {
+ public MapAppender(Element parent, EnumSet<Bean2XmlOptions> options)
+ {
+ super(parent, options);
+ }
+
+
+ @Override
+ public Element appendValue(String name, String type, String value)
+ {
+ Element child = null;
+ if (isOptionSet(Bean2XmlOptions.INTROSPECT_MAPS))
+ {
+ child = super.appendValue(name, type, value);
+ }
+ else
+ {
+ child = super.appendValue("data", type, value);
+ if (child != null)
+ child.setAttribute("key", name);
+ }
+ return child;
+ }
+ }
+
+
+ /**
+ * An appender that sets values directly on the "parent" element. Used for
+ * the conversion root element.
+ */
+ public static class DirectAppender
+ extends AbstractAppender
+ {
+ private Element _elem;
+
+ public DirectAppender(Element elem, EnumSet<Bean2XmlOptions> options)
+ {
+ super(options);
+ _elem = elem;
+ }
+
+ public Element appendValue(String name, String type, String value)
+ {
+ if (!shouldSkip(value))
+ {
+ setType(_elem, type);
+ setValue(_elem, value);
+ }
+ return _elem;
+ }
+
+ public Element appendContainer(String name, String type)
+ {
+ setType(_elem, type);
+ return _elem;
+ }
+ }
+}
Copied: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlDriver.java (from rev 108, branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean2xml/Bean2XmlDriver.java)
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlDriver.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlDriver.java 2009-08-17 17:26:40 UTC (rev 110)
@@ -0,0 +1,259 @@
+// 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 javax.xml.XMLConstants;
+
+import org.w3c.dom.Element;
+
+import net.sf.practicalxml.DomUtil;
+import net.sf.practicalxml.converter.ConversionException;
+import net.sf.practicalxml.converter.ConversionHelper;
+import net.sf.practicalxml.converter.bean.Bean2XmlAppenders.*;
+
+
+/**
+ * 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 ConversionHelper _helper;
+ private EnumSet<Bean2XmlOptions> _options = EnumSet.noneOf(Bean2XmlOptions.class);
+
+ public Bean2XmlDriver(Bean2XmlOptions... options)
+ {
+ for (Bean2XmlOptions option : options)
+ _options.add(option);
+ _helper = new ConversionHelper(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.XSI_TYPE);
+ }
+
+
+ private String getJavaXsiType(Object obj)
+ {
+ return "java:" + obj.getClass().getName();
+ }
+
+
+ /**
+ * 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.XSI_TYPE))
+ {
+ root.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil", "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, getJavaXsiType(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, "data", childAppender);
+ }
+ return true;
+ }
+
+
+ private boolean tryToConvertAsMap(Object obj, String name, Appender appender)
+ {
+ if (!(obj instanceof Map))
+ return false;
+
+ Element parent = appender.appendContainer(name, getJavaXsiType(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, getJavaXsiType(obj));
+ Appender childAppender = new IndexedAppender(parent, _options);
+ for (Object value : (Collection<?>)obj)
+ {
+ convert(value, "data", childAppender);
+ }
+ return true;
+ }
+
+
+ private boolean tryToConvertAsBean(Object bean, String name, Appender appender)
+ {
+ Element parent = appender.appendContainer(name, getJavaXsiType(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/Bean2XmlOptions.java (from rev 100, branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean2xml/Bean2XmlOptions.java)
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java 2009-08-17 17:26:40 UTC (rev 110)
@@ -0,0 +1,55 @@
+// 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;
+
+
+/**
+ * Options used by {@link Bean2XmlHandler} to control the structure of the
+ * DOM tree.
+ */
+public enum Bean2XmlOptions
+{
+ /**
+ * 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,
+
+ /**
+ * 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:XXX</code>", where XXX is the XSD type name. For complex
+ * types, this attribute's value will be "<code>java:XXX</code>", where
+ * XXX is the fully-qualified classname.
+ * <p>
+ * <em>This option implies {@link #XSD_FORMAT} for simple types</em>.
+ */
+ XSI_TYPE,
+
+ /**
+ * Report null values using the <code>xsi:nil="true"</code> attribute. If
+ * not present, null values are ignored, and not added to DOM tree.
+ */
+ XSI_NIL,
+
+ /**
+ * 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.
+ */
+ INTROSPECT_MAPS
+}
Copied: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanDriver.java (from rev 109, branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/xml2bean/Xml2BeanDriver.java)
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanDriver.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanDriver.java 2009-08-17 17:26:40 UTC (rev 110)
@@ -0,0 +1,447 @@
+// 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 javax.xml.XMLConstants;
+
+import net.sf.practicalxml.DomUtil;
+import net.sf.practicalxml.converter.ConversionException;
+import net.sf.practicalxml.converter.ConversionHelper;
+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.
+ * <p>
+ * This class assumes that the source XML will be in the form produced by
+ * {@link Bean2XmlDriver}: each element either contains child elements, or
+ * a text node containing the element's value. However, conversion is
+ * driven by the parameters passed to {@link #convert}, not by the content
+ * of the XML document; this can lead to some unexpected behavior:
+ * <ul>
+ * <li> Bean classes are introspected, and recursively processed base on
+ * the property descriptors. If the bean has multiple setter methods
+ * for a property, the method selected is arbitrarily chosen by the
+ * JavaBeans introspector. You can pass an option that looks for a
+ * setters using <code>String</code>, but this is not recommended
+ * from a performance perspective.
+ * <li> JDK collection types do not carry type information, so the only
+ * way to properly convert them is using an <code>xsi:type</code>
+ * attribute on the child elements. If this attribute is missing
+ * or cannot be interpreted, the element will be processed as if
+ * it is a <code>String</code>.
+ * <li> The converter will to pick an appropriate implementation class
+ * if given one of the JDK collections interfaces: <code>
+ * ArrayList</code> for <code>List</code> or <code>Collection</code>,
+ * <code>TreeSet</code> for <code>SortedSet</code>, <code>HashSet</code>
+ * for any other <code>Set</code>, and likewise <code>TreeMap</code> and
+ * <code>HashMap</code> for <code>SortedMap</code> and <code>Map</code>.
+ * </ul>
+ */
+public class Xml2BeanDriver
+{
+ private EnumSet<Xml2BeanOptions> _options;
+ private ConversionHelper _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 ConversionHelper(_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))
+ {
+ String attr = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil");
+ if (!attr.equals("true"))
+ throw new ConversionException(
+ "missing xsi:nil: " + DomUtil.getAbsolutePath(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: " + DomUtil.getAbsolutePath(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("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;
+ }
+
+
+ /**
+ * Returns the <code>xsi:type</code> attribute value, <code>null</code> if
+ * it's not set.
+ */
+ private String getXsiType(Element elem)
+ {
+ String xsiType = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
+ return StringUtils.isEmpty(xsiType)
+ ? null
+ : xsiType;
+ }
+
+
+ /**
+ * 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 = getXsiType(elem);
+ if (xsiType == null)
+ return null;
+
+ if (xsiType.startsWith("java:"))
+ {
+ String javaType = xsiType.substring(5);
+ try
+ {
+ return Class.forName(javaType);
+ }
+ catch (ClassNotFoundException ee)
+ {
+ throw new ConversionException(
+ "invalid Java type specification (" + javaType + "): "
+ + DomUtil.getAbsolutePath(elem),
+ ee);
+ }
+ }
+ return _helper.getJavaType(xsiType);
+ }
+
+
+ private void validateXsiType(Element elem, Class<?> klass)
+ {
+ if (!_options.contains(Xml2BeanOptions.REQUIRE_XSI_TYPE))
+ return;
+
+ String xsiType = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
+ if (StringUtils.isEmpty(xsiType))
+ throw new ConversionException(
+ "missing xsi:type: " + DomUtil.getAbsolutePath(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() + "): "
+ + DomUtil.getAbsolutePath(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 in " + beanKlass.getName() + ": "
+ + DomUtil.getAbsolutePath(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 e)
+ {
+ throw new ConversionException("unable to introspect", e);
+ }
+
+ _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: " + DomUtil.getAbsolutePath(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: " + DomUtil.getAbsolutePath(elem),
+ ee);
+ }
+ }
+}
Copied: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java (from rev 105, branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/xml2bean/Xml2BeanHandler.java)
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanHandler.java 2009-08-17 17:26:40 UTC (rev 110)
@@ -0,0 +1,194 @@
+// 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 net.sf.practicalxml.DomUtil;
+import net.sf.practicalxml.XmlException;
+import net.sf.practicalxml.XmlUtil;
+import net.sf.practicalxml.converter.ConversionException;
+import net.sf.practicalxml.converter.ConversionHelper;
+import net.sf.practicalxml.internal.StringUtils;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.xml.XMLConstants;
+
+import org.w3c.dom.Element;
+
+
+/**
+ * Invoked by {@link Xml2BeanDriver} to convert a DOM <code>Element</code>
+ * into the appropriate Java object. Unlike {@link Bean2XmlHandler}, there
+ * will only be one instance of this object created during conversion; all
+ * intermediate data can be held on the stack.
+ */
+public class Xml2BeanHandler
+{
+ private EnumSet<Xml2BeanOptions> _options;
+ private ConversionHelper _primitiveHelper;
+
+
+ /**
+ * Public constructor, allowing various options specifications.
+ */
+ public Xml2BeanHandler(Xml2BeanOptions... options)
+ {
+ _options = EnumSet.noneOf(Xml2BeanOptions.class);
+ for (Xml2BeanOptions option : options)
+ _options.add(option);
+
+ _primitiveHelper = new ConversionHelper(true);
+ }
+
+
+//----------------------------------------------------------------------------
+// Public Methods
+//----------------------------------------------------------------------------
+
+ public Boolean convertBoolean(Element elem)
+ {
+ return (Boolean)_primitiveHelper.parse(getText(elem), Boolean.class);
+ }
+
+
+ public Byte convertByte(Element elem)
+ {
+ return (Byte)_primitiveHelper.parse(getText(elem), Byte.class);
+ }
+
+
+ public Character convertCharacter(Element elem)
+ {
+ return (Character)_primitiveHelper.parse(getText(elem), Character.class);
+ }
+
+
+ public Date convertDate(Element elem)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+
+ public Double convertDouble(Element elem)
+ {
+ return (Double)_primitiveHelper.parse(getText(elem), Double.class);
+ }
+
+
+ public Float convertFloat(Element elem)
+ {
+ return (Float)_primitiveHelper.parse(getText(elem), Float.class);
+ }
+
+
+ public Integer convertInteger(Element elem)
+ {
+ return (Integer)_primitiveHelper.parse(getText(elem), Integer.class);
+ }
+
+
+ public Long convertLong(Element elem)
+ {
+ return (Long)_primitiveHelper.parse(getText(elem), Long.class);
+ }
+
+
+ public Number convertNumber(Element elem)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+
+ public Short convertShort(Element elem)
+ {
+ return (Short)_primitiveHelper.parse(getText(elem), Short.class);
+ }
+
+
+ public String convertString(Element elem)
+ {
+ return (String)_primitiveHelper.parse(getText(elem), String.class);
+ }
+
+
+ public List<?> convertList(Element elem)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+
+ public Set<?> convertSet(Element elem)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+
+ public Map<?,?> convertMap(Element elem)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+
+ public Object convertObject(Element elem)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+
+ public Object[] convertObjectArray(Element elem)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+
+//----------------------------------------------------------------------------
+// Internals
+//----------------------------------------------------------------------------
+
+ /**
+ * Returns the text from a passed element, applying any low-level options
+ * along the way.
+ */
+ private String getText(Element elem)
+ {
+ String text = DomUtil.getText(elem);
+ if (_options.contains(Xml2BeanOptions.CONVERT_BLANK_AS_NULL) && StringUtils.isBlank(text))
+ text = null;
+ validateXsiNil(elem, text);
+ return text;
+ }
+
+
+ /**
+ * Checks for elements that require <code>xsi:nil</code>, and throws if missing.
+ */
+ private void validateXsiNil(Element elem, String text)
+ {
+ if (text != null)
+ return;
+ if (!_options.contains(Xml2BeanOptions.REQUIRE_XSI_NIL))
+ return;
+
+ String attr = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil");
+ if ((attr == null) || !attr.equals("true"))
+ throw new ConversionException("empty element without required xsi:nil");
+ }
+
+}
Copied: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanOptions.java (from rev 109, branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/xml2bean/Xml2BeanOptions.java)
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanOptions.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanOptions.java 2009-08-17 17:26:40 UTC (rev 110)
@@ -0,0 +1,69 @@
+// 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;
+
+
+
+/**
+ * Options used by {@link Xml2BeanHandler} to control the way that DOM trees
+ * are translated to Java beans.
+ */
+public enum Xml2BeanOptions
+{
+ /**
+ * If present, the converter will treat all elements with empty text nodes
+ * as if they were empty elements -- in other words, <code>null</code>.
+ * Note that this flag will interact with <code>REQUIRE_XSI_NIL</code>.
+ */
+ CONVERT_BLANK_AS_NULL,
+
+
+ /**
+ * Expect data (in particular, dates) to be formatted per XML Schema spec.
+ */
+ EXPECT_XSD_FORMAT,
+
+
+ /**
+ * If present, the converter ignores elements that don't correspond to
+ * settable properties of the bean.
+ */
+ IGNORE_MISSING_PROPERTIES,
+
+
+ /**
+ * If present, the converter will look for a setter method taking a
+ * <code>String</code>, in preference to a non-string method returned
+ * from the bean introspector.
+ */
+ PREFER_STRING_SETTER,
+
+
+ /**
+ * If present, the converter requires an <code>xsi:nil</code> attribute
+ * on any empty nodes, and will throw if it's not present. Default is to
+ * treat empty nodes as <code>null</code>.
+ */
+ REQUIRE_XSI_NIL,
+
+
+ /**
+ * If present, the converter requires an <code>xsi:type</code> attribute
+ * on each element, and will throw if it's not present. Default behavior
+ * uses the <code>xsi:type</code> value to choose between different setter
+ * methods, but otherwise ignores it.
+ */
+ REQUIRE_XSI_TYPE
+}
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlAppenders.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlAppenders.java 2009-08-17 17:13:36 UTC (rev 109)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlAppenders.java 2009-08-17 17:26:40 UTC (rev 110)
@@ -20,9 +20,9 @@
import org.w3c.dom.Element;
import net.sf.practicalxml.DomUtil;
-import net.sf.practicalxml.converter.bean2xml.Bean2XmlOptions;
+import net.sf.practicalxml.converter.bean.Bean2XmlOptions;
-import static net.sf.practicalxml.converter.bean2xml.Bean2XmlAppenders.*;
+import static net.sf.practicalxml.converter.bean.Bean2XmlAppenders.*;
public class TestBean2XmlAppenders
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlDriver.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlDriver.java 2009-08-17 17:13:36 UTC (rev 109)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBean2XmlDriver.java 2009-08-17 17:26:40 UTC (rev 110)
@@ -27,8 +27,8 @@
import net.sf.practicalxml.DomUtil;
import net.sf.practicalxml.OutputUtil;
-import net.sf.practicalxml.converter.bean2xml.Bean2XmlDriver;
-import net.sf.practicalxml.converter.bean2xml.Bean2XmlOptions;
+import net.sf.practicalxml.converter.bean.Bean2XmlDriver;
+import net.sf.practicalxml.converter.bean.Bean2XmlOptions;
import net.sf.practicalxml.junit.DomAsserts;
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBeanConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBeanConverter.java 2009-08-17 17:13:36 UTC (rev 109)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestBeanConverter.java 2009-08-17 17:26:40 UTC (rev 110)
@@ -16,7 +16,7 @@
import net.sf.practicalxml.DomUtil;
import net.sf.practicalxml.OutputUtil;
-import net.sf.practicalxml.converter.bean2xml.Bean2XmlOptions;
+import net.sf.practicalxml.converter.bean.Bean2XmlOptions;
import javax.xml.XMLConstants;
import org.w3c.dom.Document;
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanDriver.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanDriver.java 2009-08-17 17:13:36 UTC (rev 109)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanDriver.java 2009-08-17 17:26:40 UTC (rev 110)
@@ -27,8 +27,8 @@
import javax.xml.XMLConstants;
import org.w3c.dom.Element;
-import net.sf.practicalxml.converter.xml2bean.Xml2BeanDriver;
-import net.sf.practicalxml.converter.xml2bean.Xml2BeanOptions;
+import net.sf.practicalxml.converter.bean.Xml2BeanDriver;
+import net.sf.practicalxml.converter.bean.Xml2BeanOptions;
import static net.sf.practicalxml.builder.XmlBuilder.*;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|