practicalxml-commits Mailing List for Practical XML (Page 6)
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-12-31 20:43:15
|
Revision: 186
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=186&view=rev
Author: kdgregory
Date: 2009-12-31 19:33:53 +0000 (Thu, 31 Dec 2009)
Log Message:
-----------
add @since tags
Modified Paths:
--------------
trunk/src/main/java/net/sf/practicalxml/DomUtil.java
trunk/src/main/java/net/sf/practicalxml/OutputUtil.java
trunk/src/main/java/net/sf/practicalxml/XmlUtil.java
trunk/src/main/java/net/sf/practicalxml/builder/PINode.java
trunk/src/main/java/net/sf/practicalxml/builder/XmlBuilder.java
trunk/src/main/java/net/sf/practicalxml/converter/BeanConverter.java
trunk/src/main/java/net/sf/practicalxml/converter/ConversionException.java
trunk/src/main/java/net/sf/practicalxml/converter/JsonConverter.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/Introspection.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/IntrospectionCache.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanOptions.java
trunk/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java
trunk/src/main/java/net/sf/practicalxml/converter/json/Json2XmlOptions.java
trunk/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java
trunk/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java
trunk/src/main/java/net/sf/practicalxml/converter/package.html
trunk/src/main/java/net/sf/practicalxml/util/NodeListIterator.java
trunk/src/main/java/net/sf/practicalxml/util/SimpleXMLReader.java
trunk/src/main/java/net/sf/practicalxml/util/XMLFilterImplBridge.java
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-12-31 14:47:33
|
Revision: 185
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=185&view=rev
Author: kdgregory
Date: 2009-12-31 14:47:25 +0000 (Thu, 31 Dec 2009)
Log Message:
-----------
NodeListIterator - recognize when we should iterate via nextSibling links
- add an optional class-based filter
DomUtil - update getChildren() to use NodeListIterator
Modified Paths:
--------------
trunk/pom.xml
trunk/src/main/java/net/sf/practicalxml/DomUtil.java
trunk/src/main/java/net/sf/practicalxml/util/NodeListIterator.java
trunk/src/test/java/net/sf/practicalxml/TestDomUtil.java
trunk/src/test/java/net/sf/practicalxml/util/TestNodeListIterator.java
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-12-30 21:53:10
|
Revision: 184
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=184&view=rev
Author: kdgregory
Date: 2009-12-30 21:53:00 +0000 (Wed, 30 Dec 2009)
Log Message:
-----------
add SimpleXMLReader, XMLFilterImplBridge
Modified Paths:
--------------
trunk/pom.xml
Added Paths:
-----------
trunk/src/main/java/net/sf/practicalxml/util/SimpleXMLReader.java
trunk/src/main/java/net/sf/practicalxml/util/XMLFilterImplBridge.java
trunk/src/test/java/net/sf/practicalxml/util/TestSimpleXMLReader.java
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-12-11 16:29:05
|
Revision: 183
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=183&view=rev
Author: kdgregory
Date: 2009-12-11 16:28:59 +0000 (Fri, 11 Dec 2009)
Log Message:
-----------
update README to test no-diffs commit email
Modified Paths:
--------------
trunk/README.txt
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-12-07 19:23:32
|
Revision: 182
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=182&view=rev
Author: kdgregory
Date: 2009-12-07 19:23:20 +0000 (Mon, 07 Dec 2009)
Log Message:
-----------
maven - don't specify version for plugin config
Modified Paths:
--------------
trunk/pom.xml
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2009-11-30 14:09:02 UTC (rev 181)
+++ trunk/pom.xml 2009-12-07 19:23:20 UTC (rev 182)
@@ -76,7 +76,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
- <version>2.0.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -94,7 +93,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
- <version>2.4.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
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-11-30 14:09:09
|
Revision: 181
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=181&view=rev
Author: kdgregory
Date: 2009-11-30 14:09:02 +0000 (Mon, 30 Nov 2009)
Log Message:
-----------
release tag
Added Paths:
-----------
tags/rel-1.1.0/
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-11-30 14:06:17
|
Revision: 180
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=180&view=rev
Author: kdgregory
Date: 2009-11-30 14:06:09 +0000 (Mon, 30 Nov 2009)
Log Message:
-----------
1.1.0 release build
Modified Paths:
--------------
trunk/pom.xml
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2009-11-23 14:34:08 UTC (rev 179)
+++ trunk/pom.xml 2009-11-30 14:06:09 UTC (rev 180)
@@ -5,7 +5,7 @@
<groupId>net.sf.practicalxml</groupId>
<artifactId>practicalxml</artifactId>
<packaging>jar</packaging>
- <version>1.1-SNAPSHOT</version>
+ <version>1.1.0</version>
<name>practicalxml</name>
<url>http://sourceforge.net/projects/practicalxml/</url>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-11-23 14:47:25
|
Revision: 179
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=179&view=rev
Author: kdgregory
Date: 2009-11-23 14:34:08 +0000 (Mon, 23 Nov 2009)
Log Message:
-----------
merge 1.1-dev branch to trunk
Modified Paths:
--------------
trunk/pom.xml
trunk/src/main/java/net/sf/practicalxml/OutputUtil.java
trunk/src/main/java/net/sf/practicalxml/XmlUtil.java
trunk/src/main/java/net/sf/practicalxml/converter/package.html
trunk/src/main/java/net/sf/practicalxml/internal/package.html
trunk/src/main/java/net/sf/practicalxml/junit/DomAsserts.java
trunk/src/test/java/net/sf/practicalxml/AbstractTestCase.java
trunk/src/test/java/net/sf/practicalxml/TestXmlUtil.java
Added Paths:
-----------
trunk/src/main/java/net/sf/practicalxml/converter/BeanConverter.java
trunk/src/main/java/net/sf/practicalxml/converter/ConversionException.java
trunk/src/main/java/net/sf/practicalxml/converter/JsonConverter.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/
trunk/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/Introspection.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/IntrospectionCache.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanOptions.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/package.html
trunk/src/main/java/net/sf/practicalxml/converter/internal/
trunk/src/main/java/net/sf/practicalxml/converter/internal/ConversionStrings.java
trunk/src/main/java/net/sf/practicalxml/converter/internal/ConversionUtils.java
trunk/src/main/java/net/sf/practicalxml/converter/internal/JavaConversionUtils.java
trunk/src/main/java/net/sf/practicalxml/converter/internal/JsonUtils.java
trunk/src/main/java/net/sf/practicalxml/converter/internal/TypeUtils.java
trunk/src/main/java/net/sf/practicalxml/converter/json/
trunk/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java
trunk/src/main/java/net/sf/practicalxml/converter/json/Json2XmlOptions.java
trunk/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java
trunk/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java
trunk/src/main/java/net/sf/practicalxml/converter/json/package.html
trunk/src/perftest/
trunk/src/perftest/java/
trunk/src/perftest/java/net/
trunk/src/perftest/java/net/sf/
trunk/src/perftest/java/net/sf/practicalxml/
trunk/src/perftest/java/net/sf/practicalxml/perftest/
trunk/src/perftest/java/net/sf/practicalxml/perftest/AbstractPerformanceTest.java
trunk/src/perftest/java/net/sf/practicalxml/perftest/converter/
trunk/src/perftest/java/net/sf/practicalxml/perftest/converter/BeanExerciser.java
trunk/src/perftest/java/net/sf/practicalxml/perftest/converter/JsonExerciser.java
trunk/src/perftest/java/net/sf/practicalxml/perftest/package.html
trunk/src/test/java/net/sf/practicalxml/converter/
trunk/src/test/java/net/sf/practicalxml/converter/AbstractConversionTestCase.java
trunk/src/test/java/net/sf/practicalxml/converter/bean/
trunk/src/test/java/net/sf/practicalxml/converter/bean/AbstractBeanConverterTestCase.java
trunk/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java
trunk/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java
trunk/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java
trunk/src/test/java/net/sf/practicalxml/converter/bean/TestIntrospection.java
trunk/src/test/java/net/sf/practicalxml/converter/bean/TestIntrospectionCache.java
trunk/src/test/java/net/sf/practicalxml/converter/bean/TestXml2BeanConverter.java
trunk/src/test/java/net/sf/practicalxml/converter/internal/
trunk/src/test/java/net/sf/practicalxml/converter/internal/TestJavaConversionUtils.java
trunk/src/test/java/net/sf/practicalxml/converter/internal/TestJsonUtils.java
trunk/src/test/java/net/sf/practicalxml/converter/internal/TestTypeUtils.java
trunk/src/test/java/net/sf/practicalxml/converter/json/
trunk/src/test/java/net/sf/practicalxml/converter/json/TestJson2XmlConverter.java
trunk/src/test/java/net/sf/practicalxml/converter/json/TestJsonConverter.java
trunk/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java
Removed Paths:
-------------
trunk/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/Introspection.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/IntrospectionCache.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanOptions.java
trunk/src/main/java/net/sf/practicalxml/converter/bean/package.html
trunk/src/main/java/net/sf/practicalxml/converter/internal/ConversionStrings.java
trunk/src/main/java/net/sf/practicalxml/converter/internal/ConversionUtils.java
trunk/src/main/java/net/sf/practicalxml/converter/internal/JavaConversionUtils.java
trunk/src/main/java/net/sf/practicalxml/converter/internal/JsonUtils.java
trunk/src/main/java/net/sf/practicalxml/converter/internal/TypeUtils.java
trunk/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java
trunk/src/main/java/net/sf/practicalxml/converter/json/Json2XmlOptions.java
trunk/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java
trunk/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java
trunk/src/main/java/net/sf/practicalxml/converter/json/package.html
trunk/src/perftest/java/
trunk/src/perftest/java/net/
trunk/src/perftest/java/net/sf/
trunk/src/perftest/java/net/sf/practicalxml/
trunk/src/perftest/java/net/sf/practicalxml/perftest/
trunk/src/perftest/java/net/sf/practicalxml/perftest/AbstractPerformanceTest.java
trunk/src/perftest/java/net/sf/practicalxml/perftest/converter/
trunk/src/perftest/java/net/sf/practicalxml/perftest/converter/BeanExerciser.java
trunk/src/perftest/java/net/sf/practicalxml/perftest/converter/JsonExerciser.java
trunk/src/perftest/java/net/sf/practicalxml/perftest/package.html
trunk/src/test/java/net/sf/practicalxml/converter/AbstractConversionTestCase.java
trunk/src/test/java/net/sf/practicalxml/converter/bean/
trunk/src/test/java/net/sf/practicalxml/converter/bean/AbstractBeanConverterTestCase.java
trunk/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java
trunk/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java
trunk/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java
trunk/src/test/java/net/sf/practicalxml/converter/bean/TestIntrospection.java
trunk/src/test/java/net/sf/practicalxml/converter/bean/TestIntrospectionCache.java
trunk/src/test/java/net/sf/practicalxml/converter/bean/TestXml2BeanConverter.java
trunk/src/test/java/net/sf/practicalxml/converter/internal/
trunk/src/test/java/net/sf/practicalxml/converter/internal/TestJavaConversionUtils.java
trunk/src/test/java/net/sf/practicalxml/converter/internal/TestJsonUtils.java
trunk/src/test/java/net/sf/practicalxml/converter/internal/TestTypeUtils.java
trunk/src/test/java/net/sf/practicalxml/converter/json/
trunk/src/test/java/net/sf/practicalxml/converter/json/TestJson2XmlConverter.java
trunk/src/test/java/net/sf/practicalxml/converter/json/TestJsonConverter.java
trunk/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java
Property Changed:
----------------
trunk/
Property changes on: trunk
___________________________________________________________________
Added: svn:mergeinfo
+ /trunk:128
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-11-23 13:55:14
|
Revision: 178
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=178&view=rev
Author: kdgregory
Date: 2009-11-23 13:55:04 +0000 (Mon, 23 Nov 2009)
Log Message:
-----------
Bean2XmlOptions: rename INTROSPECT_MAPS to MAP_KEYS_AS_ELEMENT_NAME
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java 2009-10-28 18:29:33 UTC (rev 177)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java 2009-11-23 13:55:04 UTC (rev 178)
@@ -200,7 +200,7 @@
public Element appendValue(String name, Class<?> klass, String value)
{
Element child = null;
- if (isOptionSet(Bean2XmlOptions.INTROSPECT_MAPS))
+ if (isOptionSet(Bean2XmlOptions.MAP_KEYS_AS_ELEMENT_NAME))
{
child = super.appendValue(name, klass, value);
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-10-28 18:29:33 UTC (rev 177)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-11-23 13:55:04 UTC (rev 178)
@@ -134,7 +134,7 @@
// I think it's more clear to express the rules this way, rather than
// as an if-condition with nested sub-conditions
boolean addCnvNS = _options.contains(Bean2XmlOptions.USE_INDEX_ATTR);
- addCnvNS |= !_options.contains(Bean2XmlOptions.INTROSPECT_MAPS);
+ addCnvNS |= !_options.contains(Bean2XmlOptions.MAP_KEYS_AS_ELEMENT_NAME);
addCnvNS &= _options.contains(Bean2XmlOptions.USE_TYPE_ATTR);
if (addCnvNS)
{
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-10-28 18:29:33 UTC (rev 177)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java 2009-11-23 13:55:04 UTC (rev 178)
@@ -35,7 +35,7 @@
* 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,
+ MAP_KEYS_AS_ELEMENT_NAME,
/**
* If the value is <code>null</code>, add an element containing a single
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java 2009-10-28 18:29:33 UTC (rev 177)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java 2009-11-23 13:55:04 UTC (rev 178)
@@ -275,7 +275,7 @@
{
Element root = DomUtil.newDocument("root");
- Appender appender = new MapAppender(root, useOptions(Bean2XmlOptions.INTROSPECT_MAPS));
+ Appender appender = new MapAppender(root, useOptions(Bean2XmlOptions.MAP_KEYS_AS_ELEMENT_NAME));
Element child0 = appender.appendValue("foo", String.class, "baz");
Element child1 = appender.appendValue("argle", String.class, "wargle");
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java 2009-10-28 18:29:33 UTC (rev 177)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java 2009-11-23 13:55:04 UTC (rev 178)
@@ -525,7 +525,7 @@
public void testConvertMapIntrospectWithXsiType() throws Exception
{
- Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.INTROSPECT_MAPS, Bean2XmlOptions.USE_TYPE_ATTR);
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.MAP_KEYS_AS_ELEMENT_NAME, Bean2XmlOptions.USE_TYPE_ATTR);
// TreeMap means that the data will be re-ordered
Map<String,Integer> data = new TreeMap<String,Integer>();
@@ -550,7 +550,7 @@
public void testFailMapIntrospectWithInvalidKey() throws Exception
{
- Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.INTROSPECT_MAPS);
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.MAP_KEYS_AS_ELEMENT_NAME);
Map<String,Integer> data = new TreeMap<String,Integer>();
data.put("%key1%", new Integer(123));
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-10-28 18:29:33 UTC (rev 177)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java 2009-11-23 13:55:04 UTC (rev 178)
@@ -274,7 +274,7 @@
data.put("bar", "bargle");
data.put("baz", "bazgle");
- Document dom = BeanConverter.convertToXml(data, "test", Bean2XmlOptions.INTROSPECT_MAPS);
+ Document dom = BeanConverter.convertToXml(data, "test", Bean2XmlOptions.MAP_KEYS_AS_ELEMENT_NAME);
// System.out.println(OutputUtil.compactString(dom));
DomAsserts.assertCount(0, dom, "/test/data");
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-10-28 18:29:41
|
Revision: 177
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=177&view=rev
Author: kdgregory
Date: 2009-10-28 18:29:33 +0000 (Wed, 28 Oct 2009)
Log Message:
-----------
move performance tests into their own top-level src folder (not part of normal build)
Added Paths:
-----------
branches/dev-1.1/src/perftest/
branches/dev-1.1/src/perftest/java/
branches/dev-1.1/src/perftest/java/net/
branches/dev-1.1/src/perftest/java/net/sf/
branches/dev-1.1/src/perftest/java/net/sf/practicalxml/
branches/dev-1.1/src/perftest/java/net/sf/practicalxml/perftest/
branches/dev-1.1/src/perftest/java/net/sf/practicalxml/perftest/AbstractPerformanceTest.java
branches/dev-1.1/src/perftest/java/net/sf/practicalxml/perftest/converter/
branches/dev-1.1/src/perftest/java/net/sf/practicalxml/perftest/converter/BeanExerciser.java
branches/dev-1.1/src/perftest/java/net/sf/practicalxml/perftest/converter/JsonExerciser.java
branches/dev-1.1/src/perftest/java/net/sf/practicalxml/perftest/package.html
Removed Paths:
-------------
branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/
Copied: branches/dev-1.1/src/perftest/java/net/sf/practicalxml/perftest/AbstractPerformanceTest.java (from rev 176, branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/AbstractPerformanceTest.java)
===================================================================
--- branches/dev-1.1/src/perftest/java/net/sf/practicalxml/perftest/AbstractPerformanceTest.java (rev 0)
+++ branches/dev-1.1/src/perftest/java/net/sf/practicalxml/perftest/AbstractPerformanceTest.java 2009-10-28 18:29:33 UTC (rev 177)
@@ -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.perftest;
+
+import java.util.Random;
+
+
+/**
+ * Contains utility methods useful for performance testing.
+ */
+public class AbstractPerformanceTest
+{
+ /**
+ * Creates a fixed-length string containing characters from a contiguous
+ * range of values.
+ *
+ * @param size The size of the string.
+ * @param base The lowest character value for string contents. To
+ * create strings containing any ASCII printable, pass
+ * ' '; to create strings containing uppercase values,
+ * pass 'A'.
+ * @param range The number of contiguous characters for the strings.
+ * To create strings containing any ASCII printable,
+ * pass 96; to reate strings containing alphas, pass
+ * 26.
+ */
+ protected static String randomString(int size, char base, int range)
+ {
+ Random rnd = new Random();
+
+ StringBuilder buf = new StringBuilder(size);
+ for (int ii = 0 ; ii < size ; ii++)
+ buf.append((char)(base + rnd.nextInt(range)));
+ return buf.toString();
+ }
+}
Copied: branches/dev-1.1/src/perftest/java/net/sf/practicalxml/perftest/converter/BeanExerciser.java (from rev 176, branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/converter/BeanExerciser.java)
===================================================================
--- branches/dev-1.1/src/perftest/java/net/sf/practicalxml/perftest/converter/BeanExerciser.java (rev 0)
+++ branches/dev-1.1/src/perftest/java/net/sf/practicalxml/perftest/converter/BeanExerciser.java 2009-10-28 18:29:33 UTC (rev 177)
@@ -0,0 +1,145 @@
+// 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.perftest.converter;
+
+import org.w3c.dom.Document;
+
+import net.sf.practicalxml.converter.BeanConverter;
+import net.sf.practicalxml.converter.bean.Bean2XmlOptions;
+import net.sf.practicalxml.converter.bean.Xml2BeanOptions;
+import net.sf.practicalxml.perftest.AbstractPerformanceTest;
+
+
+/**
+ * Excercises {@link net.sf.practicalxml.converter.BeanConverter} by building
+ * a shallow-but-wide XML documents with string data, and doing lots of out-
+ * and-back conversions.
+ */
+public class BeanExerciser
+extends AbstractPerformanceTest
+{
+ private final static int REPS = 10000;
+ private final static int VALUE_SIZE = 100;
+
+
+ public static void main(String[] argv)
+ throws Exception
+ {
+ // move this inside the loop to get a sense of real-world relative
+ // performance -- will take a significant percentage of overall time
+ MyDataClass src = MyDataClass.newInstance();
+
+ long start = System.currentTimeMillis();
+ for (int ii = 0 ; ii < REPS ; ii++)
+ {
+ Document dom = BeanConverter.convertToXml(src, "foo", Bean2XmlOptions.CACHE_INTROSPECTIONS);
+ MyDataClass dst = BeanConverter.convertToJava(dom, MyDataClass.class, Xml2BeanOptions.CACHE_INTROSPECTIONS);
+ }
+ long finish = System.currentTimeMillis();
+
+ System.out.println("time for " + REPS + ": " + (finish - start) + " ms");
+ }
+
+
+ /**
+ * A bean-style class containing lots of fields.
+ */
+ public static class MyDataClass
+ {
+ private String _str01;
+ private String _str02;
+ private String _str03;
+ private String _str04;
+ private String _str05;
+ private String _str06;
+ private String _str08;
+ private String _str09;
+ private String _str10;
+ private String _str11;
+ private String _str12;
+ private String _str13;
+ private String _str14;
+ private String _str15;
+ private String _str16;
+ private String _str17;
+ private String _str18;
+ private String _str19;
+ private String _str20;
+
+ public String getStr01() { return _str01; }
+ public String getStr02() { return _str02; }
+ public String getStr03() { return _str03; }
+ public String getStr04() { return _str04; }
+ public String getStr05() { return _str05; }
+ public String getStr06() { return _str06; }
+ public String getStr08() { return _str08; }
+ public String getStr09() { return _str09; }
+ public String getStr10() { return _str10; }
+ public String getStr11() { return _str11; }
+ public String getStr12() { return _str12; }
+ public String getStr13() { return _str13; }
+ public String getStr14() { return _str14; }
+ public String getStr15() { return _str15; }
+ public String getStr16() { return _str16; }
+ public String getStr17() { return _str17; }
+ public String getStr18() { return _str18; }
+ public String getStr19() { return _str19; }
+ public String getStr20() { return _str20; }
+
+ public void setStr01(String val) { _str01 = val; }
+ public void setStr02(String val) { _str02 = val; }
+ public void setStr03(String val) { _str03 = val; }
+ public void setStr04(String val) { _str04 = val; }
+ public void setStr05(String val) { _str05 = val; }
+ public void setStr06(String val) { _str06 = val; }
+ public void setStr08(String val) { _str08 = val; }
+ public void setStr09(String val) { _str09 = val; }
+ public void setStr10(String val) { _str10 = val; }
+ public void setStr11(String val) { _str11 = val; }
+ public void setStr12(String val) { _str12 = val; }
+ public void setStr13(String val) { _str13 = val; }
+ public void setStr14(String val) { _str14 = val; }
+ public void setStr15(String val) { _str15 = val; }
+ public void setStr16(String val) { _str16 = val; }
+ public void setStr17(String val) { _str17 = val; }
+ public void setStr18(String val) { _str18 = val; }
+ public void setStr19(String val) { _str19 = val; }
+ public void setStr20(String val) { _str20 = val; }
+
+ public static MyDataClass newInstance()
+ {
+ MyDataClass result = new MyDataClass();
+ result.setStr01(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr02(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr03(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr04(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr05(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr06(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr08(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr09(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr10(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr11(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr12(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr13(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr14(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr15(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr16(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr17(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr18(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr19(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr20(randomString(VALUE_SIZE, ' ', 96));
+ return result;
+ }
+ }
+}
Copied: branches/dev-1.1/src/perftest/java/net/sf/practicalxml/perftest/converter/JsonExerciser.java (from rev 176, branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/converter/JsonExerciser.java)
===================================================================
--- branches/dev-1.1/src/perftest/java/net/sf/practicalxml/perftest/converter/JsonExerciser.java (rev 0)
+++ branches/dev-1.1/src/perftest/java/net/sf/practicalxml/perftest/converter/JsonExerciser.java 2009-10-28 18:29:33 UTC (rev 177)
@@ -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.perftest.converter;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import net.sf.practicalxml.DomUtil;
+import net.sf.practicalxml.converter.JsonConverter;
+import net.sf.practicalxml.perftest.AbstractPerformanceTest;
+
+
+/**
+ * Excercises {@link net.sf.practicalxml.converter.JsonConverter} by building
+ * a shallow-but-wide XML documents with string data, and doing lots of out-
+ * and-back conversions.
+ */
+public class JsonExerciser
+extends AbstractPerformanceTest
+{
+ private final static int REPS = 10000;
+ private final static int NUM_ELEMENTS = 20;
+ private final static int KEY_SIZE = 10;
+ private final static int VALUE_SIZE = 100;
+
+
+ public static void main(String[] argv)
+ throws Exception
+ {
+ // move this inside the loop to get a sense of real-world relative
+ // performance -- will take a significant percentage of overall time
+ Document src = createDoc();
+
+ long start = System.currentTimeMillis();
+ for (int ii = 0 ; ii < REPS ; ii++)
+ {
+ String json = JsonConverter.convertToJson(src);
+ Document dst = JsonConverter.convertToXml(json, "foo");
+ }
+ long finish = System.currentTimeMillis();
+
+ System.out.println("time for " + REPS + ": " + (finish - start) + " ms");
+ }
+
+
+ private static Document createDoc()
+ {
+ Element root = DomUtil.newDocument("foo");
+ for (int ii = 0 ; ii < NUM_ELEMENTS ; ii++)
+ {
+ String name = randomString(KEY_SIZE, 'a', 26);
+ String value = randomString(VALUE_SIZE, ' ', 96);
+ Element elem = DomUtil.appendChild(root, name);
+ elem.setTextContent(value);
+ }
+ return root.getOwnerDocument();
+ }
+}
Copied: branches/dev-1.1/src/perftest/java/net/sf/practicalxml/perftest/package.html (from rev 176, branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/package.html)
===================================================================
--- branches/dev-1.1/src/perftest/java/net/sf/practicalxml/perftest/package.html (rev 0)
+++ branches/dev-1.1/src/perftest/java/net/sf/practicalxml/perftest/package.html 2009-10-28 18:29:33 UTC (rev 177)
@@ -0,0 +1,9 @@
+<html>
+<body>
+
+ This package contains programs meant to exercise portions of the library,
+ for use with a profiler. Generally they work by constructing documents
+ with lots of random string data.
+
+</body>
+</html>
\ 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-10-27 21:31:11
|
Revision: 176
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=176&view=rev
Author: kdgregory
Date: 2009-10-27 21:31:00 +0000 (Tue, 27 Oct 2009)
Log Message:
-----------
add simple performance tests for converters
Added Paths:
-----------
branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/
branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/AbstractPerformanceTest.java
branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/converter/
branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/converter/BeanExerciser.java
branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/converter/JsonExerciser.java
branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/package.html
Added: branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/AbstractPerformanceTest.java
===================================================================
--- branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/AbstractPerformanceTest.java (rev 0)
+++ branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/AbstractPerformanceTest.java 2009-10-27 21:31:00 UTC (rev 176)
@@ -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.perftest;
+
+import java.util.Random;
+
+
+/**
+ * Contains utility methods useful for performance testing.
+ */
+public class AbstractPerformanceTest
+{
+ /**
+ * Creates a fixed-length string containing characters from a contiguous
+ * range of values.
+ *
+ * @param size The size of the string.
+ * @param base The lowest character value for string contents. To
+ * create strings containing any ASCII printable, pass
+ * ' '; to create strings containing uppercase values,
+ * pass 'A'.
+ * @param range The number of contiguous characters for the strings.
+ * To create strings containing any ASCII printable,
+ * pass 96; to reate strings containing alphas, pass
+ * 26.
+ */
+ protected static String randomString(int size, char base, int range)
+ {
+ Random rnd = new Random();
+
+ StringBuilder buf = new StringBuilder(size);
+ for (int ii = 0 ; ii < size ; ii++)
+ buf.append((char)(base + rnd.nextInt(range)));
+ return buf.toString();
+ }
+}
Added: branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/converter/BeanExerciser.java
===================================================================
--- branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/converter/BeanExerciser.java (rev 0)
+++ branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/converter/BeanExerciser.java 2009-10-27 21:31:00 UTC (rev 176)
@@ -0,0 +1,145 @@
+// 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.perftest.converter;
+
+import org.w3c.dom.Document;
+
+import net.sf.practicalxml.converter.BeanConverter;
+import net.sf.practicalxml.converter.bean.Bean2XmlOptions;
+import net.sf.practicalxml.converter.bean.Xml2BeanOptions;
+import net.sf.practicalxml.perftest.AbstractPerformanceTest;
+
+
+/**
+ * Excercises {@link net.sf.practicalxml.converter.BeanConverter} by building
+ * a shallow-but-wide XML documents with string data, and doing lots of out-
+ * and-back conversions.
+ */
+public class BeanExerciser
+extends AbstractPerformanceTest
+{
+ private final static int REPS = 10000;
+ private final static int VALUE_SIZE = 100;
+
+
+ public static void main(String[] argv)
+ throws Exception
+ {
+ // move this inside the loop to get a sense of real-world relative
+ // performance -- will take a significant percentage of overall time
+ MyDataClass src = MyDataClass.newInstance();
+
+ long start = System.currentTimeMillis();
+ for (int ii = 0 ; ii < REPS ; ii++)
+ {
+ Document dom = BeanConverter.convertToXml(src, "foo", Bean2XmlOptions.CACHE_INTROSPECTIONS);
+ MyDataClass dst = BeanConverter.convertToJava(dom, MyDataClass.class, Xml2BeanOptions.CACHE_INTROSPECTIONS);
+ }
+ long finish = System.currentTimeMillis();
+
+ System.out.println("time for " + REPS + ": " + (finish - start) + " ms");
+ }
+
+
+ /**
+ * A bean-style class containing lots of fields.
+ */
+ public static class MyDataClass
+ {
+ private String _str01;
+ private String _str02;
+ private String _str03;
+ private String _str04;
+ private String _str05;
+ private String _str06;
+ private String _str08;
+ private String _str09;
+ private String _str10;
+ private String _str11;
+ private String _str12;
+ private String _str13;
+ private String _str14;
+ private String _str15;
+ private String _str16;
+ private String _str17;
+ private String _str18;
+ private String _str19;
+ private String _str20;
+
+ public String getStr01() { return _str01; }
+ public String getStr02() { return _str02; }
+ public String getStr03() { return _str03; }
+ public String getStr04() { return _str04; }
+ public String getStr05() { return _str05; }
+ public String getStr06() { return _str06; }
+ public String getStr08() { return _str08; }
+ public String getStr09() { return _str09; }
+ public String getStr10() { return _str10; }
+ public String getStr11() { return _str11; }
+ public String getStr12() { return _str12; }
+ public String getStr13() { return _str13; }
+ public String getStr14() { return _str14; }
+ public String getStr15() { return _str15; }
+ public String getStr16() { return _str16; }
+ public String getStr17() { return _str17; }
+ public String getStr18() { return _str18; }
+ public String getStr19() { return _str19; }
+ public String getStr20() { return _str20; }
+
+ public void setStr01(String val) { _str01 = val; }
+ public void setStr02(String val) { _str02 = val; }
+ public void setStr03(String val) { _str03 = val; }
+ public void setStr04(String val) { _str04 = val; }
+ public void setStr05(String val) { _str05 = val; }
+ public void setStr06(String val) { _str06 = val; }
+ public void setStr08(String val) { _str08 = val; }
+ public void setStr09(String val) { _str09 = val; }
+ public void setStr10(String val) { _str10 = val; }
+ public void setStr11(String val) { _str11 = val; }
+ public void setStr12(String val) { _str12 = val; }
+ public void setStr13(String val) { _str13 = val; }
+ public void setStr14(String val) { _str14 = val; }
+ public void setStr15(String val) { _str15 = val; }
+ public void setStr16(String val) { _str16 = val; }
+ public void setStr17(String val) { _str17 = val; }
+ public void setStr18(String val) { _str18 = val; }
+ public void setStr19(String val) { _str19 = val; }
+ public void setStr20(String val) { _str20 = val; }
+
+ public static MyDataClass newInstance()
+ {
+ MyDataClass result = new MyDataClass();
+ result.setStr01(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr02(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr03(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr04(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr05(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr06(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr08(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr09(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr10(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr11(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr12(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr13(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr14(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr15(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr16(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr17(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr18(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr19(randomString(VALUE_SIZE, ' ', 96));
+ result.setStr20(randomString(VALUE_SIZE, ' ', 96));
+ return result;
+ }
+ }
+}
Added: branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/converter/JsonExerciser.java
===================================================================
--- branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/converter/JsonExerciser.java (rev 0)
+++ branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/converter/JsonExerciser.java 2009-10-27 21:31:00 UTC (rev 176)
@@ -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.perftest.converter;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import net.sf.practicalxml.DomUtil;
+import net.sf.practicalxml.converter.JsonConverter;
+import net.sf.practicalxml.perftest.AbstractPerformanceTest;
+
+
+/**
+ * Excercises {@link net.sf.practicalxml.converter.JsonConverter} by building
+ * a shallow-but-wide XML documents with string data, and doing lots of out-
+ * and-back conversions.
+ */
+public class JsonExerciser
+extends AbstractPerformanceTest
+{
+ private final static int REPS = 10000;
+ private final static int NUM_ELEMENTS = 20;
+ private final static int KEY_SIZE = 10;
+ private final static int VALUE_SIZE = 100;
+
+
+ public static void main(String[] argv)
+ throws Exception
+ {
+ // move this inside the loop to get a sense of real-world relative
+ // performance -- will take a significant percentage of overall time
+ Document src = createDoc();
+
+ long start = System.currentTimeMillis();
+ for (int ii = 0 ; ii < REPS ; ii++)
+ {
+ String json = JsonConverter.convertToJson(src);
+ Document dst = JsonConverter.convertToXml(json, "foo");
+ }
+ long finish = System.currentTimeMillis();
+
+ System.out.println("time for " + REPS + ": " + (finish - start) + " ms");
+ }
+
+
+ private static Document createDoc()
+ {
+ Element root = DomUtil.newDocument("foo");
+ for (int ii = 0 ; ii < NUM_ELEMENTS ; ii++)
+ {
+ String name = randomString(KEY_SIZE, 'a', 26);
+ String value = randomString(VALUE_SIZE, ' ', 96);
+ Element elem = DomUtil.appendChild(root, name);
+ elem.setTextContent(value);
+ }
+ return root.getOwnerDocument();
+ }
+}
Added: branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/package.html
===================================================================
--- branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/package.html (rev 0)
+++ branches/dev-1.1/src/example/java/net/sf/practicalxml/perftest/package.html 2009-10-27 21:31:00 UTC (rev 176)
@@ -0,0 +1,9 @@
+<html>
+<body>
+
+ This package contains programs meant to exercise portions of the library,
+ for use with a profiler. Generally they work by constructing documents
+ with lots of random string data.
+
+</body>
+</html>
\ 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-10-27 20:40:07
|
Revision: 175
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=175&view=rev
Author: kdgregory
Date: 2009-10-27 20:39:52 +0000 (Tue, 27 Oct 2009)
Log Message:
-----------
replace StringBuffer by StringBuilder (oops)
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/JsonUtils.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/JsonUtils.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/JsonUtils.java 2009-10-27 19:20:51 UTC (rev 174)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/JsonUtils.java 2009-10-27 20:39:52 UTC (rev 175)
@@ -33,7 +33,7 @@
if (src == null)
return "";
- StringBuffer buf = new StringBuffer(src.length() + 20);
+ StringBuilder buf = new StringBuilder(src.length() + 20);
for (int ii = 0 ; ii < src.length() ; ii++)
{
char c = src.charAt(ii);
@@ -81,7 +81,7 @@
if (src == null)
return "";
- StringBuffer buf = new StringBuffer(src.length());
+ StringBuilder buf = new StringBuilder(src.length());
for (int ii = 0 ; ii < src.length() ; )
{
char c = src.charAt(ii++);
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-10-27 19:21:03
|
Revision: 174
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=174&view=rev
Author: kdgregory
Date: 2009-10-27 19:20:51 +0000 (Tue, 27 Oct 2009)
Log Message:
-----------
Xml2JsonConverter with USE_XSI_TYPE treats List and Set subclasses as arrays
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java 2009-10-27 18:43:03 UTC (rev 173)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java 2009-10-27 19:20:51 UTC (rev 174)
@@ -272,6 +272,10 @@
return false;
if (klass.isArray())
return true;
+ if (List.class.isAssignableFrom(klass))
+ return true;
+ if (Set.class.isAssignableFrom(klass))
+ return true;
return false;
}
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-10-27 18:43:03 UTC (rev 173)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java 2009-10-27 19:20:51 UTC (rev 174)
@@ -13,6 +13,9 @@
// limitations under the License.
package net.sf.practicalxml.converter.json;
+import java.util.ArrayList;
+import java.util.TreeSet;
+
import org.w3c.dom.Element;
import net.sf.practicalxml.builder.ElementNode;
@@ -130,6 +133,30 @@
}
+ public void testListPerXsiType() throws Exception
+ {
+ convertAndAssert(
+ "{\"value\": [123, 456]}",
+ element("data",
+ element("value", conversionType("java:" + ArrayList.class.getName()),
+ element("foo", text("123"), conversionType("xsd:int")),
+ element("bar", text("456"), conversionType("xsd:int")))),
+ Xml2JsonOptions.USE_XSI_TYPE);
+ }
+
+
+ public void testSetPerXsiType() throws Exception
+ {
+ convertAndAssert(
+ "{\"value\": [123, 456]}",
+ element("data",
+ element("value", conversionType("java:" + TreeSet.class.getName()),
+ element("foo", text("123"), conversionType("xsd:int")),
+ element("bar", text("456"), conversionType("xsd:int")))),
+ Xml2JsonOptions.USE_XSI_TYPE);
+ }
+
+
public void testEmptyArrayPerXsiType() throws Exception
{
convertAndAssert(
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-10-27 18:43:11
|
Revision: 173
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=173&view=rev
Author: kdgregory
Date: 2009-10-27 18:43:03 +0000 (Tue, 27 Oct 2009)
Log Message:
-----------
Move all converter-managed attributes into their own namespace
Replace use of xsi:type with practicalxml:type
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java
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/package.html
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/ConversionUtils.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/JavaConversionUtils.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/package.html
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractConversionTestCase.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/AbstractBeanConverterTestCase.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestXml2BeanConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/internal/TestJavaConversionUtils.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java
Added Paths:
-----------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/TypeUtils.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/internal/TestTypeUtils.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-10-26 15:03:54 UTC (rev 172)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java 2009-10-27 18:43:03 UTC (rev 173)
@@ -21,6 +21,7 @@
import net.sf.practicalxml.converter.ConversionException;
import net.sf.practicalxml.converter.internal.ConversionStrings;
import net.sf.practicalxml.converter.internal.ConversionUtils;
+import net.sf.practicalxml.converter.internal.TypeUtils;
/**
@@ -44,9 +45,8 @@
* 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 klass Java class for this node. May (depending on options)
+ * be stored in the <code>type</code> attribute.
* @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.
@@ -56,7 +56,7 @@
* 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);
+ public Element appendValue(String name, Class<?> klass, String value);
/**
@@ -64,7 +64,7 @@
* 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);
+ public Element appendContainer(String name, Class<?> klass);
}
@@ -93,10 +93,10 @@
&& !_options.contains(Bean2XmlOptions.NULL_AS_XSI_NIL);
}
- protected void setType(Element elem, String type)
+ protected void setType(Element elem, Class<?> klass)
{
- if (isOptionSet(Bean2XmlOptions.XSI_TYPE))
- ConversionUtils.setXsiType(elem, type);
+ if (isOptionSet(Bean2XmlOptions.USE_TYPE_ATTR))
+ TypeUtils.setType(elem, klass);
}
protected void setValue(Element elem, String value)
@@ -125,7 +125,7 @@
_parent = parent;
}
- public Element appendValue(String name, String type, String value)
+ public Element appendValue(String name, Class<?> klass, String value)
{
if (shouldSkip(value))
return null;
@@ -133,7 +133,7 @@
try
{
Element child = DomUtil.appendChildInheritNamespace(_parent, name);
- setType(child, type);
+ setType(child, klass);
setValue(child, value);
return child;
}
@@ -143,10 +143,10 @@
}
}
- public Element appendContainer(String name, String type)
+ public Element appendContainer(String name, Class<?> klass)
{
Element child = DomUtil.appendChildInheritNamespace(_parent, name);
- setType(child, type);
+ setType(child, klass);
return child;
}
}
@@ -169,11 +169,14 @@
@Override
- public Element appendValue(String name, String type, String value)
+ public Element appendValue(String name, Class<?> klass, String value)
{
- Element child = super.appendValue(name, type, value);
- if ((child != null) && isOptionSet(Bean2XmlOptions.SEQUENCE_INDEXES))
- child.setAttribute(ConversionStrings.AT_ARRAY_INDEX, String.valueOf(_index++));
+ Element child = super.appendValue(name, klass, value);
+ if ((child != null) && isOptionSet(Bean2XmlOptions.USE_INDEX_ATTR))
+ ConversionUtils.setAttribute(
+ child,
+ ConversionStrings.AT_ARRAY_INDEX,
+ String.valueOf(_index++));
return child;
}
}
@@ -194,18 +197,21 @@
@Override
- public Element appendValue(String name, String type, String value)
+ public Element appendValue(String name, Class<?> klass, String value)
{
Element child = null;
if (isOptionSet(Bean2XmlOptions.INTROSPECT_MAPS))
{
- child = super.appendValue(name, type, value);
+ child = super.appendValue(name, klass, value);
}
else
{
- child = super.appendValue(ConversionStrings.EL_COLLECTION_ITEM, type, value);
+ child = super.appendValue(ConversionStrings.EL_COLLECTION_ITEM, klass, value);
if (child != null)
- child.setAttribute(ConversionStrings.AT_MAP_KEY, name);
+ ConversionUtils.setAttribute(
+ child,
+ ConversionStrings.AT_MAP_KEY,
+ name);
}
return child;
}
@@ -227,20 +233,20 @@
_elem = elem;
}
- public Element appendValue(String name, String type, String value)
+ public Element appendValue(String name, Class<?> klass, String value)
{
if (!shouldSkip(value))
{
- setType(_elem, type);
+ setType(_elem, klass);
setValue(_elem, value);
}
return _elem;
}
- public Element appendContainer(String name, String type)
+ public Element appendContainer(String name, Class<?> klass)
{
- setType(_elem, type);
+ setType(_elem, klass);
return _elem;
}
}
-}
+}
\ No newline at end of file
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-10-26 15:03:54 UTC (rev 172)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-10-27 18:43:03 UTC (rev 173)
@@ -75,7 +75,7 @@
public Element convert(Object obj, String nsUri, String rootName)
{
Element root = DomUtil.newDocument(nsUri, rootName);
- doXsiNamespaceHack(root);
+ doNamespaceHack(root);
convert(obj, rootName, new DirectAppender(root, _options));
return root;
}
@@ -110,50 +110,49 @@
private boolean shouldUseXsdFormatting()
{
return _options.contains(Bean2XmlOptions.XSD_FORMAT)
- || _options.contains(Bean2XmlOptions.XSI_TYPE);
+ || _options.contains(Bean2XmlOptions.USE_TYPE_ATTR);
}
/**
- * 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.
+ * Introduces namespaces at the root level, because the Xerces serializer
+ * does not attempt to promote namespace definitions above the element in
+ * which they first appear. This means that the same declaration may be
+ * repeated at multiple places throughout a tree.
* <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.
+ * Will only introduce namespaces appropriate to the options in effect
+ * (ie, if you don't enable <code>xsi:nil</code>, then there's no need
+ * to declare the XML Schema Instance namespace).
*/
- private void doXsiNamespaceHack(Element root)
+ private void doNamespaceHack(Element root)
{
- if (_options.contains(Bean2XmlOptions.NULL_AS_XSI_NIL)
- && !_options.contains(Bean2XmlOptions.XSI_TYPE))
+ if (_options.contains(Bean2XmlOptions.NULL_AS_XSI_NIL))
{
ConversionUtils.setXsiNil(root, false);
}
+
+ // I think it's more clear to express the rules this way, rather than
+ // as an if-condition with nested sub-conditions
+ boolean addCnvNS = _options.contains(Bean2XmlOptions.USE_INDEX_ATTR);
+ addCnvNS |= !_options.contains(Bean2XmlOptions.INTROSPECT_MAPS);
+ addCnvNS &= _options.contains(Bean2XmlOptions.USE_TYPE_ATTR);
+ if (addCnvNS)
+ {
+ ConversionUtils.setAttribute(root, ConversionStrings.AT_DUMMY, "");
+ }
}
private void convertAsNull(Class<?> klass, String name, Appender appender)
{
- appender.appendValue(
- name,
- JavaConversionUtils.java2XsiType(klass),
- null);
+ appender.appendValue(name, klass, null);
}
private void convertAsPrimitive(Object obj, String name, Appender appender)
{
appender.appendValue(
- name,
- JavaConversionUtils.java2XsiType(obj),
+ name, obj.getClass(),
JavaConversionUtils.stringify(obj, _useXsdFormatting));
}
@@ -164,7 +163,7 @@
Appender childAppender = appender;
if (!_options.contains(Bean2XmlOptions.SEQUENCE_AS_REPEATED_ELEMENTS))
{
- Element parent = appender.appendContainer(name, JavaConversionUtils.java2XsiType(array));
+ Element parent = appender.appendContainer(name, array.getClass());
childAppender = new IndexedAppender(parent, _options);
}
@@ -179,7 +178,7 @@
private void convertAsMap(Object obj, String name, Appender appender)
{
- Element parent = appender.appendContainer(name, JavaConversionUtils.java2XsiType(obj));
+ Element parent = appender.appendContainer(name, obj.getClass());
Appender childAppender = new MapAppender(parent, _options);
for (Map.Entry<?,?> entry : ((Map<?,?>)obj).entrySet())
{
@@ -194,7 +193,7 @@
Appender childAppender = appender;
if (!_options.contains(Bean2XmlOptions.SEQUENCE_AS_REPEATED_ELEMENTS))
{
- Element parent = appender.appendContainer(name, JavaConversionUtils.java2XsiType(obj));
+ Element parent = appender.appendContainer(name, obj.getClass());
childAppender = new IndexedAppender(parent, _options);
}
@@ -207,7 +206,7 @@
private void convertAsBean(Object bean, String name, Appender appender)
{
- Element parent = appender.appendContainer(name, JavaConversionUtils.java2XsiType(bean));
+ Element parent = appender.appendContainer(name, bean.getClass());
Appender childAppender = new BasicAppender(parent, _options);
Introspection ispec = _introspections.lookup(bean.getClass());
for (String propName : ispec.propertyNames())
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-10-26 15:03:54 UTC (rev 172)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java 2009-10-27 18:43:03 UTC (rev 173)
@@ -64,21 +64,29 @@
SEQUENCE_AS_REPEATED_ELEMENTS,
/**
+ * Sequences (arrays, lists, sets) will name their elements according to
+ * the parent element, with any trailing "s" removed. For example, if the
+ * parent is named "products", each child will be named "product", rather
+ * than the default "data". If the parent is named "foo", each child will
+ * also be named "foo" (since there's no "s" to remove).
+ */
+ SEQUENCE_NAMED_BY_PARENT,
+
+ /**
* Will add an <code>index</code> attribute to the child elements of
* sequences (arrays, lists, sets); the value of this attribute is the
* element's position in the sequence (numbered from 0). This index is
* not terribly useful, so is no longer default behavior.
*/
- SEQUENCE_INDEXES,
+ USE_INDEX_ATTR,
/**
- * Sequences (arrays, lists, sets) will name their elements according to
- * the parent element, with any trailing "s" removed. For example, if the
- * parent is named "products", each child will be named "product", rather
- * than the default "data". If the parent is named "foo", each child will
- * also be named "foo" (since there's no "s" to remove).
+ * Will add a <code>type</code> attribute to each element; see package
+ * docs for more details.
+ * <p>
+ * <em>This option implies {@link #XSD_FORMAT}</em>.
*/
- SEQUENCE_NAMED_BY_PARENT,
+ USE_TYPE_ATTR,
/**
* Outputs values using formats defined by XML Schema, rather than Java's
@@ -86,16 +94,5 @@
* 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: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
+ XSD_FORMAT
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java 2009-10-26 15:03:54 UTC (rev 172)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java 2009-10-27 18:43:03 UTC (rev 173)
@@ -34,6 +34,7 @@
import net.sf.practicalxml.converter.internal.ConversionStrings;
import net.sf.practicalxml.converter.internal.ConversionUtils;
import net.sf.practicalxml.converter.internal.JavaConversionUtils;
+import net.sf.practicalxml.converter.internal.TypeUtils;
import net.sf.practicalxml.internal.StringUtils;
import org.w3c.dom.Element;
@@ -161,9 +162,7 @@
List<Element> children = DomUtil.getChildren(elem);
for (Element child : children)
{
- Class<?> childClass = getClassFromXsiType(child);
- if (childClass == null)
- childClass = String.class;
+ Class<?> childClass = getCollectionElementClass(child);
result.add(convertWithoutCast(child, childClass));
}
return result;
@@ -179,12 +178,10 @@
List<Element> children = DomUtil.getChildren(elem);
for (Element child : children)
{
- String key = child.getAttribute(ConversionStrings.AT_MAP_KEY);
+ String key = ConversionUtils.getAttribute(child, ConversionStrings.AT_MAP_KEY);
if (StringUtils.isEmpty(key))
key = DomUtil.getLocalName(child);
- Class<?> childClass = getClassFromXsiType(child);
- if (childClass == null)
- childClass = String.class;
+ Class<?> childClass = getCollectionElementClass(child);
result.put(key, convertWithoutCast(child, childClass));
}
return result;
@@ -227,47 +224,19 @@
}
- /**
- * 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)
+ private void validateXsiType(Element elem, Class<?> klass)
{
- String xsiType = ConversionUtils.getXsiType(elem);
- if (xsiType == null)
- return null;
-
- Class<?> klass = JavaConversionUtils.xsiType2JavaClass(xsiType);
- if (klass != null)
- return klass;
-
- throw new ConversionException(
- "invalid Java type specification: " + xsiType,
- elem);
+ if (_options.contains(Xml2BeanOptions.REQUIRE_TYPE))
+ TypeUtils.validateType(elem, klass);
}
- private void validateXsiType(Element elem, Class<?> klass)
+ private Class<?> getCollectionElementClass(Element child)
{
- if (!_options.contains(Xml2BeanOptions.REQUIRE_XSI_TYPE))
- return;
-
- String xsiType = ConversionUtils.getXsiType(elem);
- if (xsiType == null)
- throw new ConversionException("missing xsi:type", elem);
-
- if (xsiType.equals(JavaConversionUtils.java2XsiType(klass)))
- return;
-
- Class<?> xsiKlass = getClassFromXsiType(elem);
- if (klass.isAssignableFrom(xsiKlass))
- return;
-
- throw new ConversionException(
- "invalid xsi:type: \"" + xsiType + "\" for " + klass.getName(),
- elem);
+ Class<?> childClass = TypeUtils.getType(child, false);
+ return (childClass != null)
+ ? childClass
+ : String.class;
}
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-10-26 15:03:54 UTC (rev 172)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanOptions.java 2009-10-27 18:43:03 UTC (rev 173)
@@ -49,19 +49,18 @@
*/
IGNORE_MISSING_PROPERTIES,
+ /**
+ * If present, the converter requires a <code>type</code> attribute on
+ * each element, and will use that attribute to verify that the element
+ * can be converted to the desired type.
+ */
+ REQUIRE_TYPE,
+
/**
* 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
+ REQUIRE_XSI_NIL
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/package.html
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/package.html 2009-10-26 15:03:54 UTC (rev 172)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/package.html 2009-10-27 18:43:03 UTC (rev 173)
@@ -10,22 +10,25 @@
Objects are processed recursively, and cycles are <em>not</em> detected
(although this may change).
<p>
-XML may be generated with namespaces. However, namespaces are ignored when
-converting to Java objects; the local names drive conversion.
+On output, the caller may specify a namespace: all elements will have this
+namespace. On input, namespaces are ignored: bean properties are identified
+by element local names. The converter will use its own namespace for any
+converter-specific attributes (eg, <code>type</code>); this namespace is
+defined by {@link net.sf.practicalxml.converter.internal.ConversionStrings#NS_CONVERSION}). The converter will also apply attributes from the XML Schema Instance
+namespace; all documentation refers to these attributes with an "xsi" prefix
+(eg: <code>xsi:nil</code>).
<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.
+The most important of the converter-specific attributes is <code>type</code>.
+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.
+On input, the desired type is specified by the caller or by introspection.
+The <code>type</code> attribute, if any, is used to validate whether the
+element matches this desired type (except in the case of collection elements,
+described below).
<p>
Additional conversion rules are as follows:
@@ -75,8 +78,8 @@
output in iterator order.
<td>The collection is processed as it if were an array (qv), with one (major)
difference: since all collections inherently contain Objects, there is no
- type information to drive conversion. If an <code>xsi:type</code> attribute
- is present, it will be used to drive conversion. Otherwise, the element will
+ type information to drive conversion. If a <code>type</code> attribute is
+ present, it will be used to drive conversion. Otherwise, the element will
be converted as a <code>String</code> (which will fail for complex types,
because string conversion assumes a single text node).
<p>
@@ -107,10 +110,10 @@
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).
+ If the <code>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:
Modified: 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 2009-10-26 15:03:54 UTC (rev 172)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionStrings.java 2009-10-27 18:43:03 UTC (rev 173)
@@ -23,38 +23,46 @@
public class ConversionStrings
{
/**
+ * Namespace for attributes defined by the converter.
+ */
+ public final static String NS_CONVERSION = "http://practicalxml.sourceforge.net/Converter";
+
+
+ /**
+ * Name of root element, where not specified by caller.
+ */
+ public final static String EL_DEFAULT_ROOT = "data";
+
+
+ /**
* 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.
+ * A dummy attribute used to declare the conversion namespace at the root.
*/
- public final static String AT_ARRAY_INDEX = "index";
+ public final static String AT_DUMMY = "ix";
/**
- * Attribute used to hold the item key value for maps.
+ * Attribute used to hold the type of an element. Belongs to the
+ * {@link #NS_CONVERSION} namespace.
*/
- public final static String AT_MAP_KEY = "key";
+ public final static String AT_TYPE = "type";
/**
- * Prefix for <code>xsi:type</code> values for elements holding primitive
- * values as defined by XML Schema. Note that we define a specific prefix
- * that may or may not correspond to a namespace defined in the instance
- * doc; we do not do namespace resolution on the value. Instance documents
- * produced by tools other than <code>BeanConverter</code> must use the
- * same prefix.
+ * Attribute used to hold the element index number for collections and
+ * arrays. Belongs to the {@link #NS_CONVERSION} namespace.
*/
- public final static String XSD_TYPE_PREFIX = "xsd:";
+ public final static String AT_ARRAY_INDEX = "index";
/**
- * Prefix for <code>xsi:type</code> values for elements holding Java
- * objects as serialized by <code>BeanConverter</code>. Again, this is
- * an explicit value, and does not correspond to any namespace.
+ * Attribute used to hold the item key value for maps. Belongs to the
+ * {@link #NS_CONVERSION} namespace.
*/
- public final static String JAVA_TYPE_PREFIX = "java:";
+ public final static String AT_MAP_KEY = "key";
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionUtils.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionUtils.java 2009-10-26 15:03:54 UTC (rev 172)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/ConversionUtils.java 2009-10-27 18:43:03 UTC (rev 173)
@@ -18,7 +18,6 @@
import org.w3c.dom.Element;
-import net.sf.practicalxml.internal.StringUtils;
/**
@@ -36,44 +35,40 @@
public class ConversionUtils
{
/**
- * Sets the <code>xsi:nil</code> attribute to the passed value.
+ * Retrieves an arbitrary attribute within the "conversion" namespace.
*/
- public static void setXsiNil(Element elem, boolean isNil)
+ public static String getAttribute(Element elem, String name)
{
- String value = isNil ? "true" : "false";
- elem.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil", value);
+ return elem.getAttributeNS(ConversionStrings.NS_CONVERSION, name);
}
/**
- * Returns the value of the <code>xsi:nil</code> attribute on the passed
- * element, <code>false</code> if the attribute is not set.
+ * Sets an arbitrary attribute within the "conversion" namespace.
*/
- public static boolean getXsiNil(Element elem)
+ public static void setAttribute(Element elem, String name, String value)
{
- String attr = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil");
- return attr.equals("true");
+ elem.setAttributeNS(ConversionStrings.NS_CONVERSION, name, value);
}
/**
- * Sets the <code>xsi:type</code> attribute to the passed value.
+ * Sets the <code>xsi:nil</code> attribute to the passed value.
*/
- public static void setXsiType(Element elem, String xsiType)
+ public static void setXsiNil(Element elem, boolean isNil)
{
- elem.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type", xsiType);
+ String value = isNil ? "true" : "false";
+ elem.setAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil", value);
}
/**
- * Returns the value of the <code>xsi:type</code> attribute on the passed
- * element, <code>null</code> if the attribute is not set.
+ * 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 String getXsiType(Element elem)
+ public static boolean getXsiNil(Element elem)
{
- String xsiType = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
- return StringUtils.isEmpty(xsiType)
- ? null
- : xsiType;
+ String attr = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil");
+ return attr.equals("true");
}
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/JavaConversionUtils.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/JavaConversionUtils.java 2009-10-26 15:03:54 UTC (rev 172)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/JavaConversionUtils.java 2009-10-27 18:43:03 UTC (rev 173)
@@ -23,83 +23,20 @@
import java.util.HashMap;
import java.util.Map;
+
import net.sf.practicalxml.XmlUtil;
import net.sf.practicalxml.converter.ConversionException;
-import net.sf.practicalxml.internal.StringUtils;
/**
- * Static utility methods for conversion to/from Java.
- * <p>
- * Many of these methods deal with <code>xsi:type</code> attribute values
- * ("<code>xsi</code>" being any prefix that refers to the XML Schema
- * Instance namespace). The conversion library deals with two sets of values
- * for this attribute: those beginning with "xsd:", and those beginning with
- * "java:". These prefixes are literal values; we do not do any sort of
- * namespace resolution.
- * <p>
- * In the case of "<code>xsd:</code>" values, the portion after the prefix
- * corresponds to a subset of the built-in datatypes defined by
- * <a href="http://www.w3.org/TR/xmlschema-2/#built-in-datatypes">XML Schema
- * Part 2</a>. In the case of "<code>java:</code>" values, the portion after
- * the prefix must be a fully-qualified Java classname (which need not be
- * resolvable by the current JVM).
+ * Handles conversion of primitive Java types to and from a string value. In
+ * this usage, "primitive" indicates that the Java object has a simple string
+ * serialization; this includes, for example, <code>java.util.Date</code>.
*/
public class JavaConversionUtils
{
- /**
- * Translation from <code>xsi:type</code> values to Java primitive
- * (wrapper) classes. Note the lack of any prefix -- and that we
- * don't support the full set of primitives defined for XML Schema.
- */
- private static Map<String,Class<?>> _xsiType2Java
- = new HashMap<String,Class<?>>();
- static
- {
- _xsiType2Java.put("string", String.class);
- _xsiType2Java.put("boolean", Boolean.class);
- _xsiType2Java.put("byte", Byte.class);
- _xsiType2Java.put("short", Short.class);
- _xsiType2Java.put("int", Integer.class);
- _xsiType2Java.put("long", Long.class);
- _xsiType2Java.put("decimal", BigDecimal.class);
- _xsiType2Java.put("dateTime", Date.class);
- }
- /**
- * Translation from Java primitive wrappers (and the associated non-
- * wrapper "class") to an appropriate <code>xsi:type</code> value.
- * Again, note the lack of prefix.
- */
- private static Map<Class<?>,String> _java2XsiType
- = new HashMap<Class<?>,String>();
- static
- {
- _java2XsiType.put(String.class, "string");
- _java2XsiType.put(Character.class, "string");
- _java2XsiType.put(Boolean.class, "boolean");
- _java2XsiType.put(Byte.class, "byte");
- _java2XsiType.put(Short.class, "short");
- _java2XsiType.put(Integer.class, "int");
- _java2XsiType.put(Long.class, "long");
- _java2XsiType.put(Float.class, "decimal");
- _java2XsiType.put(Double.class, "decimal");
- _java2XsiType.put(BigInteger.class, "decimal");
- _java2XsiType.put(BigDecimal.class, "decimal");
- _java2XsiType.put(Date.class, "dateTime");
-
- _java2XsiType.put(Character.TYPE, "string");
- _java2XsiType.put(Boolean.TYPE, "boolean");
- _java2XsiType.put(Byte.TYPE, "byte");
- _java2XsiType.put(Short.TYPE, "short");
- _java2XsiType.put(Integer.TYPE, "int");
- _java2XsiType.put(Long.TYPE, "long");
- _java2XsiType.put(Float.TYPE, "decimal");
- _java2XsiType.put(Double.TYPE, "decimal");
- }
-
-
private static Map<Class<?>,ConversionHandler<?>> _helpers
= new HashMap<Class<?>,ConversionHandler<?>>();
static
@@ -149,88 +86,11 @@
*/
public static boolean isPrimitive(Class<?> klass)
{
- return _java2XsiType.containsKey(klass);
+ return _helpers.containsKey(klass);
}
/**
- * Returns the <code>xsi:type</code> value for an arbitrary Java class,
- * <code>null</code> if passed <code>null</code>.
- */
- public static String java2XsiType(Class<?> klass)
- {
- if (klass == null)
- return null;
-
- String type = _java2XsiType.get(klass);
- return (type != null)
- ? ConversionStrings.XSD_TYPE_PREFIX + type
- : ConversionStrings.JAVA_TYPE_PREFIX + klass.getName();
- }
-
-
- /**
- * Returns the <code>xsi:type</code> value for a Java object,
- * <code>null</code> if passed <code>null</code>.
- */
- public static String java2XsiType(Object obj)
- {
- return (obj == null)
- ? null
- : java2XsiType(obj.getClass());
- }
-
-
- /**
- * Returns the Java classname to be used for a given <code>xsi:type</code>
- * value, <code>null</code> if unable to determine the type (typically
- * because it doesn't follow the expected format).
- */
- public static String xsiType2JavaClassname(String xsiType)
- {
- if (StringUtils.isEmpty(xsiType))
- return null;
-
- if (xsiType.startsWith(ConversionStrings.XSD_TYPE_PREFIX))
- {
- String typeSansPrefix = xsiType.substring(ConversionStrings.XSD_TYPE_PREFIX.length());
- Class<?> klass = _xsiType2Java.get(typeSansPrefix);
- return (klass == null)
- ? null
- : klass.getName();
- }
- else if (xsiType.startsWith(ConversionStrings.JAVA_TYPE_PREFIX))
- {
- return xsiType.substring(ConversionStrings.JAVA_TYPE_PREFIX.length());
- }
-
- return null;
- }
-
-
- /**
- * Returns the Java class object to be used for a given <code>xsi:type</code>.
- *
- * @throws ConversionException if unable to determine or resolve the type.
- */
- public static Class<?> xsiType2JavaClass(String xsiType)
- {
- String className = xsiType2JavaClassname(xsiType);
- if (className == null)
- throw new ConversionException("null type specification");
-
- try
- {
- return Class.forName(className);
- }
- catch (ClassNotFoundException ee)
- {
- throw new ConversionException("invalid type specification: " + xsiType, ee);
- }
- }
-
-
- /**
* Converts a Java primitive object to a string representation. Returns
* <code>null</code> if passed <code>null</code>.
*
@@ -240,7 +100,7 @@
* String.valueOf()</code>. If <code>true</code>,
* will attempt to use the format specified by XML
* Schema for the datatype returned from {@link
- * #java2XsiType}.
+ * TypeUtils#java2XsiType}.
*
* @throws ConversionException if the passed object does not have a string
* representation (ie, is not a primitive value).
@@ -267,7 +127,7 @@
* Parses the passed string as a Java primitive object of the specified
* type. Will attempt to use the built-in parsing functions for the type,
* or a format defined by XML Schema for the type that would be returned
- * by {@link #java2XsiType} for the passed class. Returns <code>null</code>
+ * by {@link TypeUtils#java2XsiType} for the passed class. Returns <code>null</code>
* if passed <code>null</code>.
*
* @param value String representation.
Added: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/TypeUtils.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/TypeUtils.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/TypeUtils.java 2009-10-27 18:43:03 UTC (rev 173)
@@ -0,0 +1,245 @@
+// 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.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.w3c.dom.Element;
+
+import net.sf.practicalxml.converter.ConversionException;
+import net.sf.practicalxml.internal.StringUtils;
+
+
+/**
+ * Constants and static methods for working with elements that declare their
+ * type using the <code>{practicalxml}:type</code> attribute (the actual
+ * namespace is defined by
+ * {@link net.sf.practicalxml.converter.internal.ConversionStrings}).
+ * <p>
+ * The values for this attribute take two forms: those representing simple
+ * types defined by XML Schema, indicated by the prefix "xsd:", and those
+ * representing arbitrary Java types, indicated by the prefix "java:". In
+ * the latter case, the post-prefix portion contains the value returned by
+ * <code>Class.getName()</code>.
+ */
+public class TypeUtils
+{
+ /**
+ * Translation from <code>xsi:type</code> values to Java primitive
+ * (wrapper) classes. Note the lack of any prefix -- and that we
+ * don't support the full set of primitives defined for XML Schema.
+ */
+ private static Map<String,Class<?>> _xsiType2Java
+ = new HashMap<String,Class<?>>();
+
+ static
+ {
+ _xsiType2Java.put("string", String.class);
+ _xsiType2Java.put("boolean", Boolean.class);
+ _xsiType2Java.put("byte", Byte.class);
+ _xsiType2Java.put("short", Short.class);
+ _xsiType2Java.put("int", Integer.class);
+ _xsiType2Java.put("long", Long.class);
+ _xsiType2Java.put("decimal", BigDecimal.class);
+ _xsiType2Java.put("dateTime", Date.class);
+ }
+
+
+ /**
+ * Translation from Java primitive wrappers (and the associated non-
+ * wrapper "class") to an appropriate <code>xsi:type</code> value.
+ * Again, note the lack of prefix.
+ */
+ private static Map<Class<?>,String> _java2XsiType
+ = new HashMap<Class<?>,String>();
+ static
+ {
+ _java2XsiType.put(String.class, "string");
+ _java2XsiType.put(Character.class, "string");
+ _java2XsiType.put(Boolean.class, "boolean");
+ _java2XsiType.put(Byte.class, "byte");
+ _java2XsiType.put(Short.class, "short");
+ _java2XsiType.put(Integer.class, "int");
+ _java2XsiType.put(Long.class, "long");
+ _java2XsiType.put(Float.class, "decimal");
+ _java2XsiType.put(Double.class, "decimal");
+ _java2XsiType.put(BigInteger.class, "decimal");
+ _java2XsiType.put(BigDecimal.class, "decimal");
+ _java2XsiType.put(Date.class, "dateTime");
+
+ _java2XsiType.put(Character.TYPE, "string");
+ _java2XsiType.put(Boolean.TYPE, "boolean");
+ _java2XsiType.put(Byte.TYPE, "byte");
+ _java2XsiType.put(Short.TYPE, "short");
+ _java2XsiType.put(Integer.TYPE, "int");
+ _java2XsiType.put(Long.TYPE, "long");
+ _java2XsiType.put(Float.TYPE, "decimal");
+ _java2XsiType.put(Double.TYPE, "decimal");
+ }
+
+
+//----------------------------------------------------------------------------
+// Constants
+//----------------------------------------------------------------------------
+
+ /**
+ * Prefix for <code>xsi:type</code> values for elements holding primitive
+ * values as defined by XML Schema. Note that we define a specific prefix
+ * that may or may not correspond to a namespace defined in the instance
+ * doc; we do not do namespace resolution on the value. Instance documents
+ * produced by tools other than <code>BeanConverter</code> must use the
+ * same prefix.
+ */
+ public final static String XSD_TYPE_PREFIX = "xsd:";
+
+
+ /**
+ * Prefix for <code>xsi:type</code> values for elements holding Java
+ * objects as serialized by <code>BeanConverter</code>. Again, this is
+ * an explicit value, and does not correspond to any namespace.
+ */
+ public final static String JAVA_TYPE_PREFIX = "java:";
+
+
+//----------------------------------------------------------------------------
+// Public Methods
+//----------------------------------------------------------------------------
+
+ /**
+ * Returns the <code>{practicalxml}:type</code> value for the passed
+ * Java class.
+ */
+ public static String class2type(Class<?> klass)
+ {
+ String type = _java2XsiType.get(klass);
+ return (type != null)
+ ? XSD_TYPE_PREFIX + type
+ : JAVA_TYPE_PREFIX + klass.getName();
+ }
+
+
+ /**
+ * Sets the <code>{practicalxml}:type</code> attribute to a value
+ * appropriate for the passed Java class. Does nothing if passed
+ * <code>null</code>
+ */
+ public static void setType(Element elem, Class<?> klass)
+ {
+ if (klass == null)
+ return;
+ ConversionUtils.setAttribute(elem, ConversionStrings.AT_TYPE, class2type(klass));
+ }
+
+
+ /**
+ * Returns the value of the passed element's <code>{practicalxml}:type</code>
+ * attribute, <code>null</code> if the attribute is not set or contains
+ * an empty string.
+ * <p>
+ * Most callers should use {@link #getType} rather than this method.
+ */
+ public static String getTypeValue(Element elem)
+ {
+ String type = ConversionUtils.getAttribute(elem, ConversionStrings.AT_TYPE);
+ return (StringUtils.isEmpty(type))
+ ? null
+ : type;
+ }
+
+
+ /**
+ * Returns the Java class corresponding to the passed element's
+ * <code>{practicalxml}:type</code> attribute. Optionally returns
+ * <code>null</code> or throws if unable to convert the attribute.
+ *
+ * @throws ConversionException if unable to determine Java type for
+ * any reason, when <code>throwIfFail</code> is set.
+ */
+ public static Class<?> getType(Element elem, boolean throwIfFail)
+ {
+ String type = getTypeValue(elem);
+ if (type == null)
+ {
+ if (throwIfFail)
+ throw new ConversionException("missing type", elem);
+ else
+ return null;
+ }
+
+ Class<?> klass = null;
+ if (type.startsWith(XSD_TYPE_PREFIX))
+ klass = lookupXsdType(type);
+ else if (type.startsWith(JAVA_TYPE_PREFIX))
+ klass = resolveJavaType(type);
+
+ if (klass == null)
+ throw new ConversionException("unable to resolve type: " + type, elem);
+
+ return klass;
+ }
+
+
+ /**
+ * Validates that the stated type of the element is assignable to the
+ * passed class.
+ *
+ * @throws ConversionException if unable to resolve element's type or if
+ * an object of that type is not assignable to the passed class.
+ */
+ public static void validateType(Element elem, Class<?> klass)
+ {
+ Class<?> elemKlass = getType(elem, true);
+ if (klass.isAssignableFrom(elemKlass))
+ return;
+
+ // the primitive "TYPE" classes aren't assignable to the primitive
+ // wrapper class returned in previous step, so handle that case here
+ if (class2type(klass).equals(class2type(elemKlass)))
+ return;
+
+ throw new ConversionException(
+ "invalid type: \"" + getTypeValue(elem) + "\" for " + klass.getName(),
+ elem);
+ }
+
+
+//----------------------------------------------------------------------------
+// Internals
+//----------------------------------------------------------------------------
+
+ private static Class<?> lookupXsdType(String value)
+ {
+ value = value.substring(XSD_TYPE_PREFIX.length());
+ return _xsiType2Java.get(value);
+ }
+
+
+ private static Class<?> resolveJavaType(String value)
+ {
+ value = value.substring(JAVA_TYPE_PREFIX.length());
+ try
+ {
+ return Class.forName(value);
+ }
+ catch (ClassNotFoundException ee)
+ {
+ return null;
+ }
+ }
+}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java 2009-10-26 15:03:54 UTC (rev 172)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Json2XmlConverter.java 2009-10-27 18:43:03 UTC (rev 173)
@@ -21,6 +21,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.JsonUtils;
@@ -64,7 +65,7 @@
*/
public Element convert()
{
- return convert("data");
+ return convert(ConversionStrings.EL_DEFAULT_ROOT);
}
@@ -162,7 +163,7 @@
private void parseArray(Element parent)
{
- String childName = "data";
+ String childName = ConversionStrings.EL_COLLECTION_ITEM;
if (_options.contains(Json2XmlOptions.ARRAYS_AS_REPEATED_ELEMENTS))
{
// we come in here with the assumption that array elements will
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-10-26 15:03:54 UTC (rev 172)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java 2009-10-27 18:43:03 UTC (rev 173)
@@ -24,9 +24,8 @@
import java.util.Set;
import net.sf.practicalxml.DomUtil;
-import net.sf.practicalxml.converter.internal.ConversionUtils;
import net.sf.practicalxml.converter.internal.JsonUtils;
-import net.sf.practicalxml.internal.StringUtils;
+import net.sf.practicalxml.converter.internal.TypeUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -129,7 +128,7 @@
private StringBuilder appendText(StringBuilder buf, Element elem)
{
String text = DomUtil.getText(elem);
- String type = ConversionUtils.getXsiType(elem);
+ String type = TypeUtils.getTypeValue(elem);
String quote = "\"";
if (_options.contains(Xml2JsonOptions.USE_XSI_TYPE) && _unquotedXsd.contains(type))
quote = "";
@@ -268,10 +267,10 @@
if (!_options.contains(Xml2JsonOptions.USE_XSI_TYPE))
return false;
- String type = ConversionUtils.getXsiType(elem);
- if (StringUtils.isEmpty(type))
+ Class<?> klass = TypeUtils.getType(elem, false);
+ if (klass == null)
return false;
- if (type.startsWith("java:["))
+ if (klass.isArray())
return true;
return false;
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/package.html
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/package.html 2009-10-26 15:03:54 UTC (rev 172)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/package.html 2009-10-27 18:43:03 UTC (rev 173)
@@ -22,7 +22,8 @@
<dd> JSON supports numbers and boolean literals in addition to quote-delimited
strings. The JSON to XML conversion will handle these values transparently.
The default XML to JSON conversion writes all content as quote-delimited
- strings (although this may change).
+ strings, will optionally look for a <code>type</code> attribute and use it
+ to generate unquoted values.
<dt> Arrays, XML to JSON
<dd> XML does not have a defined array construct, but may repeat elements; JSON
has a defined array construct, and repeated elements will overwrite the
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractConversionTestCase.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractConversionTestCase.java 2009-10-26 15:03:54 UTC (rev 172)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractConversionTestCase.java 2009-10-27 18:43:03 UTC (rev 173)
@@ -21,6 +21,7 @@
import org.w3c.dom.Element;
import net.sf.practicalxml.AbstractTestCase;
+import net.sf.practicalxml.converter.internal.ConversionStrings;
/**
@@ -34,18 +35,23 @@
super(testName);
}
+
//----------------------------------------------------------------------------
// Support Code
//----------------------------------------------------------------------------
- protected static net.sf.practicalxml.builder.Node xsiType(String typeName)
+ protected static net.sf.practicalxml.builder.Node conversionAttr(String name, String value)
{
- return attribute(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI,
- "type",
- typeName);
+ return attribute(ConversionStrings.NS_CONVERSION, name, value);
}
+ protected static net.sf.practicalxml.builder.Node conversionType(String value)
+ {
+ return conversionAttr(ConversionStrings.AT_TYPE, value);
+ }
+
+
protected static net.sf.practicalxml.builder.Node xsiNil(boolean isNil)
{
return attribute(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI,
@@ -58,10 +64,9 @@
// Assertions
//----------------------------------------------------------------------------
- protected void assertXsiType(String message, Element elem, String expectedType)
+ protected void assertAttribute(Element elem, String name, String expected)
{
- String attr = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
- assertEquals(message, expectedType, attr);
+ assertEquals(expected, elem.getAttributeNS(ConversionStrings.NS_CONVERSION, name));
}
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-10-26 15:03:54 UTC (rev 172)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/AbstractBeanConverterTestCase.java 2009-10-27 18:43:03 UTC (rev 173)
@@ -26,6 +26,7 @@
import net.sf.practicalxml.DomUtil;
import net.sf.practicalxml.converter.AbstractConversionTestCase;
+import net.sf.practicalxml.converter.internal.ConversionStrings;
/**
@@ -184,7 +185,7 @@
{
assertName(message, elem, expectedName);
assertValue(message, elem, expectedValue);
- assertXsiType(message, elem, expectedType);
+ assertType(message, elem, expectedType);
assertXsiNil(message, elem, isNil);
}
@@ -205,7 +206,7 @@
message += " ";
assertName(message + "name", elem, expectedName);
- assertXsiType(message + "xsi:type", elem, expectedType);
+ assertType(message + "type", elem, expectedType);
assertValue(message + "value", elem, expectedValue);
}
@@ -216,6 +217,13 @@
}
+ protected void assertType(String message, Element elem, String expected)
+ {
+ String attr = elem.getAttributeNS(ConversionStrings.NS_CONVERSION, "type");
+ assertEquals(message, expected, attr);
+ }
+
+
protected void assertValue(String message, Element elem, String expectedValue)
{
assertEquals(message, expectedValue, DomUtil.getText(elem));
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java 2009-10-26 15:03:54 UTC (rev 172)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java 2009-10-27 18:43:03 UTC (rev 173)
@@ -56,7 +56,7 @@
Element root = DomUtil.newDocument("root");
Appender appender = new BasicAppender(root, useOptions());
- Element child = appender.appendValue("foo", "bar", "baz");
+ Element child = appender.appendValue("foo", String.class, "baz");
assertNull(child.getNamespaceURI());
assertNameTypeValue(child, "foo", "", "baz");
@@ -72,11 +72,11 @@
{
Element root = DomUtil.newDocument("root");
- Appender appender = new BasicAppender(root, useOptions(Bean2XmlOptions.XSI_TYPE));
- Element child = appender.appendValue("foo", "bar", "baz");
+ Appender appender = new BasicAppender(root, useOptions(Bean2XmlOptions.USE_TYPE_ATTR));
+ Element child = appender.appendValue("foo", String.class, "baz");
assertNull(child.getNamespaceURI());
- assertNameTypeValue(child, "foo", "bar", "baz");
+ assertNameTypeValue(child, "foo", "xsd:string", "baz");
}
@@ -85,7 +85,7 @@
Element root = DomUtil.newDocument("root");
Appender appender = new BasicAppender(root, useOptions());
- Element child = appender.appendValue("foo", "bar", null);
+ Element child = appender.appendValue("foo", null, null);
assertNull(child);
@@ -99,13 +99,13 @@
Element root = DomUtil.newDocument("root");
Appender appender = new BasicAppender(root, useOptions(Bean2XmlOptions.NULL_AS_XSI_NIL));
- Element child0 = appender.appendValue("foo", "bar", "baz");
- Element child1 = appender.appendValue("argle", "bargle", null);
+ Element child0 = appender.appendValue("foo", null, "baz");
+ Element child1 = appender.appendValue("argle", null, null);
assertXsiNil(child0, false);
assertNull(child1.getNamespaceURI());
- assertNameTypeValue(child1, "argle","", null);
+ assertNameTypeValue(child1, "argle", "", null);
assertXsiNil(child1, true);
}
@@ -115,8 +115,8 @@
Element root = DomUtil.newDocument("root");
Appender appender = new BasicAppender(root, useOptions());
- Element child0 = appender.appendContainer("foo", "bar");
- Element child1 = appender.appendContainer("argle", "bargle");
+ Element child0 = appender.appendContainer("foo", String[].class);
+ Element child1 = appender.appendContainer("argle", String[].class);
assertChildCount(root, 2);
assertNameTypeValue(child0, "foo", "", null);
@@ -128,13 +128,13 @@
{
Element root = DomUtil.newDocument("root");
- Appender appender = new BasicAppender(root, useOptions(Bean2XmlOptions.XSI_TYPE));
- Element child0 = appender.appendContainer("foo", "bar");
- Element child1 = appender.appendContainer("argle", "bargle");
+ Appender appender = new BasicAppender(root, useOptions(Bean2XmlOptions.USE_TYPE_ATTR));
+ Element child0 = appender.appendContainer("foo", String[].class);
+ E...
[truncated message content] |
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-10-26 15:04:02
|
Revision: 172
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=172&view=rev
Author: kdgregory
Date: 2009-10-26 15:03:54 +0000 (Mon, 26 Oct 2009)
Log Message:
-----------
rename internal functions
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/JavaConversionUtils.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/internal/TestJavaConversionUtils.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-10-24 18:46:31 UTC (rev 171)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-10-26 15:03:54 UTC (rev 172)
@@ -154,7 +154,7 @@
appender.appendValue(
name,
JavaConversionUtils.java2XsiType(obj),
- JavaConversionUtils.java2String(obj, _useXsdFormatting));
+ JavaConversionUtils.stringify(obj, _useXsdFormatting));
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java 2009-10-24 18:46:31 UTC (rev 171)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java 2009-10-26 15:03:54 UTC (rev 172)
@@ -131,7 +131,7 @@
if (hasElementChildren(elem))
throw new ConversionException("expecting primitive; has children", elem);
- return JavaConversionUtils.string2Java(getText(elem), klass, _useXsdFormat);
+ return JavaConversionUtils.parse(getText(elem), klass, _useXsdFormat);
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/JavaConversionUtils.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/JavaConversionUtils.java 2009-10-24 18:46:31 UTC (rev 171)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/internal/JavaConversionUtils.java 2009-10-26 15:03:54 UTC (rev 172)
@@ -245,7 +245,7 @@
* @throws ConversionException if the passed object does not have a string
* representation (ie, is not a primitive value).
*/
- public static String java2String(Object value, boolean useXsdFormat)
+ public static String stringify(Object value, boolean useXsdFormat)
{
if (value == null)
return null;
@@ -278,7 +278,7 @@
*
* @throws ConversionException if unable to parse.
*/
- public static Object string2Java(String value, Class<?> klass, boolean useXsdFormat)
+ public static Object parse(String value, Class<?> klass, boolean useXsdFormat)
{
if (value == null)
return null;
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/internal/TestJavaConversionUtils.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/internal/TestJavaConversionUtils.java 2009-10-24 18:46:31 UTC (rev 171)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/internal/TestJavaConversionUtils.java 2009-10-26 15:03:54 UTC (rev 172)
@@ -41,7 +41,7 @@
{
try
{
- JavaConversionUtils.string2Java(str, klass, useXsdFormat);
+ JavaConversionUtils.parse(str, klass, useXsdFormat);
fail(message);
}
catch (ConversionException ee)
@@ -81,8 +81,8 @@
public void testConvertNull() throws Exception
{
- assertNull(JavaConversionUtils.java2String(null, false));
- assertNull(JavaConversionUtils.string2Java(null, Object.class, false));
+ assertNull(JavaConversionUtils.stringify(null, false));
+ assertNull(JavaConversionUtils.parse(null, Object.class, false));
}
@@ -90,11 +90,11 @@
{
assertEquals("xsd:string", JavaConversionUtils.java2XsiType(String.class));
- assertEquals("foo", JavaConversionUtils.java2String("foo", false));
- assertEquals("foo", JavaConversionUtils.string2Java("foo", String.class, false));
+ assertEquals("foo", JavaConversionUtils.stringify("foo", false));
+ assertEquals("foo", JavaConversionUtils.parse("foo", String.class, false));
- assertEquals("", JavaConversionUtils.java2String("", false));
- assertEquals("", JavaConversionUtils.string2Java("", String.class, false));
+ assertEquals("", JavaConversionUtils.stringify("", false));
+ assertEquals("", JavaConversionUtils.parse("", String.class, false));
}
@@ -103,12 +103,12 @@
assertEquals("xsd:string", JavaConversionUtils.java2XsiType(Character.class));
Character simple = Character.valueOf('A');
- assertEquals("A", JavaConversionUtils.java2String(simple, false));
- assertEquals(simple, JavaConversionUtils.string2Java("A", Character.class, false));
+ assertEquals("A", JavaConversionUtils.stringify(simple, false));
+ assertEquals(simple, JavaConversionUtils.parse("A", Character.class, false));
Character nul = Character.valueOf('\0');
- assertEquals("", JavaConversionUtils.java2String(nul, false));
- assertEquals(nul, JavaConversionUtils.string2Java("", Character.class, false));
+ assertEquals("", JavaConversionUtils.stringify(nul, false));
+ assertEquals(nul, JavaConversionUtils.parse("", Character.class, false));
assertFailsConversionToObject(
"converted multi-character string",
@@ -122,15 +122,15 @@
assertEquals("xsd:boolean", JavaConversionUtils.java2XsiType(Boolean.class));
String sTrue = Boolean.TRUE.toString();
- assertEquals(sTrue, JavaConversionUtils.java2String(Boolean.TRUE, false));
- assertEquals(Boolean.TRUE, JavaConversionUtils.string2Java(sTrue, Boolean.class, false));
+ assertEquals(sTrue, JavaConversionUtils.stringify(Boolean.TRUE, false));
+ assertEquals(Boolean.TRUE, JavaConversionUtils.parse(sTrue, Boolean.class, false));
String sFalse = Boolean.FALSE.toString();
- assertEquals(sFalse, JavaConversionUtils.java2String(Boolean.FALSE, false));
- assertEquals(Boolean.FALSE, JavaConversionUtils.string2Java(sFalse, Boolean.class, false));
+ assertEquals(sFalse, JavaConversionUtils.stringify(Boolean.FALSE, false));
+ assertEquals(Boolean.FALSE, JavaConversionUtils.parse(sFalse, Boolean.class, false));
- assertEquals(Boolean.FALSE, JavaConversionUtils.string2Java("ix", Boolean.class, false));
- assertEquals(Boolean.FALSE, JavaConversionUtils.string2Java("", Boolean.class, false));
+ assertEquals(Boolean.FALSE, JavaConversionUtils.parse("ix", Boolean.class, false));
+ assertEquals(Boolean.FALSE, JavaConversionUtils.parse("", Boolean.class, false));
}
@@ -138,13 +138,13 @@
{
assertEquals("xsd:boolean", JavaConversionUtils.java2XsiType(Boolean.class));
- assertEquals("true", JavaConversionUtils.java2String(Boolean.TRUE, true));
- assertEquals(Boolean.TRUE, JavaConversionUtils.string2Java("true", Boolean.class, true));
- assertEquals(Boolean.TRUE, JavaConversionUtils.string2Java("1", Boolean.class, true));
+ assertEquals("true", JavaConversionUtils.stringify(Boolean.TRUE, true));
+ assertEquals(Boolean.TRUE, JavaConversionUtils.parse("true", Boolean.class, true));
+ assertEquals(Boolean.TRUE, JavaConversionUtils.parse("1", Boolean.class, true));
- assertEquals("false", JavaConversionUtils.java2String(Boolean.FALSE, true));
- assertEquals(Boolean.FALSE, JavaConversionUtils.string2Java("false", Boolean.class, true));
- assertEquals(Boolean.FALSE, JavaConversionUtils.string2Java("0", Boolean.class, true));
+ assertEquals("false", JavaConversionUtils.stringify(Boolean.FALSE, true));
+ assertEquals(Boolean.FALSE, JavaConversionUtils.parse("false", Boolean.class, true));
+ assertEquals(Boolean.FALSE, JavaConversionUtils.parse("0", Boolean.class, true));
assertFailsConversionToObject(
"converted multi-character string",
@@ -162,17 +162,17 @@
String str1 = "123";
Byte val1 = Byte.valueOf((byte)123);
- assertEquals(str1, JavaConversionUtils.java2String(val1, false));
- assertEquals(val1, JavaConversionUtils.string2Java(str1, Byte.class, false));
+ assertEquals(str1, JavaConversionUtils.stringify(val1, false));
+ assertEquals(val1, JavaConversionUtils.parse(str1, Byte.class, false));
String str2 = "-123";
Byte val2 = Byte.valueOf((byte)-123);
- assertEquals(str2, JavaConversionUtils.java2String(val2, false));
- assertEquals(val2, JavaConversionUtils.string2Java(str2, Byte.class, false));
+ assertEquals(str2, JavaConversionUtils.stringify(val2, false));
+ assertEquals(val2, JavaConversionUtils.parse(str2, Byte.class, false));
String str3 = " -123 ";
Byte val3 = Byte.valueOf((byte)-123);
- assertEquals(val3, JavaConversionUtils.string2Java(str3, Byte.class, false));
+ assertEquals(val3, JavaConversionUtils.parse(str3, Byte.class, false));
assertFailsConversionToObject(
"converted too-large value",
@@ -198,17 +198,17 @@
String str1 = "12345";
Short val1 = Short.valueOf((short)12345);
- assertEquals(str1, JavaConversionUtils.java2String(val1, false));
- assertEquals(val1, JavaConversionUtils.string2Java(str1, Short.class, false));
+ assertEquals(str1, JavaConversionUtils.stringify(val1, false));
+ assertEquals(val1, JavaConversionUtils.parse(str1, Short.class, false));
String str2 = "-12345";
Short val2 = Short.valueOf((short)-12345);
- assertEquals(str2, JavaConversionUtils.java2String(val2, false));
- assertEquals(val2, JavaConversionUtils.string2Java(str2, Short.class, false));
+ assertEquals(str2, JavaConversionUtils.stringify(val2, false));
+ assertEquals(val2, JavaConversionUtils.parse(str2, Short.class, false));
String str3 = " -12345 ";
Short val3 = Short.valueOf((short)-12345);
- assertEquals(val3, JavaConversionUtils.string2Java(str3, Short.class, false));
+ assertEquals(val3, JavaConversionUtils.parse(str3, Short.class, false));
assertFailsConversionToObject(
"converted too-large value",
@@ -234,17 +234,17 @@
String str1 = "1234567";
Integer val1 = Integer.valueOf(1234567);
- assertEquals(str1, JavaConversionUtils.java2String(val1, false));
- assertEquals(val1, JavaConversionUtils.string2Java(str1, Integer.class, false));
+ assertEquals(str1, JavaConversionUtils.stringify(val1, false));
+ assertEquals(val1, JavaConversionUtils.parse(str1, Integer.class, false));
String str2 = "-1234567";
Integer val2 = Integer.valueOf(-1234567);
- assertEquals(str2, JavaConversionUtils.java2String(val2, false));
- assertEquals(val2, JavaConversionUtils.string2Java(str2, Integer.class, false));
+ assertEquals(str2, JavaConversionUtils.stringify(val2, false));
+ assertEquals(val2, JavaConversionUtils.parse(str2, Integer.class, false));
String str3 = " -1234567 ";
Integer val3 = Integer.valueOf(-1234567);
- assertEquals(val3, JavaConversionUtils.string2Java(str3, Integer.class, false));
+ assertEquals(val3, JavaConversionUtils.parse(str3, Integer.class, false));
assertFailsConversionToObject(
"converted too-large value",
@@ -270,17 +270,17 @@
String str1 = "1234567890";
Long val1 = Long.valueOf(1234567890L);
- assertEquals(str1, JavaConversionUtils.java2String(val1, false));
- assertEquals(val1, JavaConversionUtils.string2Java(str1, Long.class, false));
+ assertEquals(str1, JavaConversionUtils.stringify(val1, false));
+ assertEquals(val1, JavaConversionUtils.parse(str1, Long.class, false));
String str2 = "-1234567890";
Long val2 = Long.valueOf(-1234567890L);
- assertEquals(str2, JavaConversionUtils.java2String(val2, false));
- assertEquals(val2, JavaConversionUtils.string2Java(str2, Long.class, false));
+ assertEquals(str2, JavaConversionUtils.stringify(val2, false));
+ assertEquals(val2, JavaConversionUtils.parse(str2, Long.class, false));
String str3 = " -1234567890 ";
Long val3 = Long.valueOf(-1234567890L);
- assertEquals(val3, JavaConversionUtils.string2Java(str3, Long.class, false));
+ assertEquals(val3, JavaConversionUtils.parse(str3, Long.class, false));
assertFailsConversionToObject(
"converted too-large value",
@@ -308,17 +308,17 @@
// note: for default-format tests, strings are generated from values
Float val1 = Float.valueOf(1234f);
String str1 = val1.toString();
- assertEquals(str1, JavaConversionUtils.java2String(val1, false));
- assertEquals(val1, JavaConversionUtils.string2Java(str1, Float.class, false));
+ assertEquals(str1, JavaConversionUtils.stringify(val1, false));
+ assertEquals(val1, JavaConversionUtils.parse(str1, Float.class, false));
Float val2 = Float.valueOf(-1234f);
String str2 = val2.toString();
- assertEquals(str2, JavaConversionUtils.java2String(val2, false));
- assertEquals(val2, JavaConversionUtils.string2Java(str2, Float.class, false));
+ assertEquals(str2, JavaConversionUtils.stringify(val2, false));
+ assertEquals(val2, JavaConversionUtils.parse(str2, Float.class, false));
String str3 = " -1234.5 ";
Float val3 = Float.valueOf(-1234.5f);
- assertEquals(val3, JavaConversionUtils.string2Java(str3, Float.class, false));
+ assertEquals(val3, JavaConversionUtils.parse(str3, Float.class, false));
assertFailsConversionToObject(
"converted non-numeric value",
@@ -336,17 +336,17 @@
String str1 = "1234.0";
Float val1 = Float.valueOf(1234f);
- assertEquals(str1, JavaConversionUtils.java2String(val1, false));
- assertEquals(val1, JavaConversionUtils.string2Java(str1, Float.class, false));
+ assertEquals(str1, JavaConversionUtils.stringify(val1, false));
+ assertEquals(val1, JavaConversionUtils.parse(str1, Float.class, false));
String str2 = "-1234.0";
Float val2 = Float.valueOf(-1234f);
- assertEquals(str2, JavaConversionUtils.java2String(val2, false));
- assertEquals(val2, JavaConversionUtils.string2Java(str2, Float.class, false));
+ assertEquals(str2, JavaConversionUtils.stringify(val2, false));
+ assertEquals(val2, JavaConversionUtils.parse(str2, Float.class, false));
String str3 = " -1234.5 ";
Float val3 = Float.valueOf(-1234.5f);
- assertEquals(val3, JavaConversionUtils.string2Java(str3, Float.class, false));
+ assertEquals(val3, JavaConversionUtils.parse(str3, Float.class, false));
assertFailsConversionToObject(
"converted non-numeric value",
@@ -366,17 +366,17 @@
// note: for default-format tests, strings are generated from values
Double val1 = Double.valueOf(1234567890.5);
String str1 = val1.toString();
- assertEquals(str1, JavaConversionUtils.java2String(val1, false));
- assertEquals(val1, JavaConversionUtils.string2Java(str1, Double.class, false));
+ assertEquals(str1, JavaConversionUtils.stringify(val1, false));
+ assertEquals(val1, JavaConversionUtils.parse(str1, Double.class, false));
Double val2 = Double.valueOf(-1234567890.1);
String str2 = val2.toString();
- assertEquals(str2, JavaConversionUtils.java2String(val2, false));
- assertEquals(val2, JavaConversionUtils.string2Java(str2, Double.class, false));
+ assertEquals(str2, JavaConversionUtils.stringify(val2, false));
+ assertEquals(val2, JavaConversionUtils.parse(str2, Double.class, false));
String str3 = " -1234.5 ";
Double val3 = Double.valueOf(-1234.5);
- assertEquals(val3, JavaConversionUtils.string2Java(str3, Double.class, false));
+ assertEquals(val3, JavaConversionUtils.parse(str3, Double.class, false));
assertFailsConversionToObject(
"converted non-numeric value",
@@ -395,17 +395,17 @@
// while for XSD-format tests, we want to verify the strings
String str1 = "1234567890.5";
Double val1 = Double.valueOf(1234567890.5);
- assertEquals(str1, JavaConversionUtils.java2String(val1, true));
- assertEquals(val1, JavaConversionUtils.string2Java(str1, Double.class, true));
+ assertEquals(str1, JavaConversionUtils.stringify(val1, true));
+ assertEquals(val1, JavaConversionUtils.parse(str1, Double.class, true));
String str2 = "-1234567890.1";
Double val2 = Double.valueOf(-1234567890.1);
- assertEquals(str2, JavaConversionUtils.java2String(val2, true));
- assertEquals(val2, JavaConversionUtils.string2Java(str2, Double.class, true));
+ assertEquals(str2, JavaConversionUtils.stringify(val2, true));
+ assertEquals(val2, JavaConversionUtils.parse(str2, Double.class, true));
String str3 = " -1234.5 ";
Double val3 = Double.valueOf(-1234.5);
- assertEquals(val3, JavaConversionUtils.string2Java(str3, Double.class, true));
+ assertEquals(val3, JavaConversionUtils.parse(str3, Double.class, true));
assertFailsConversionToObject(
"converted non-numeric value",
@@ -423,13 +423,13 @@
String str1 = "123456789012345678901234567890";
BigInteger val1 = new BigInteger(str1);
- assertEquals(str1, JavaConversionUtils.java2String(val1, false));
- assertEquals(val1, JavaConversionUtils.string2Java(str1, BigInteger.class, false));
+ assertEquals(str1, JavaConversionUtils.stringify(val1, false));
+ assertEquals(val1, JavaConversionUtils.parse(str1, BigInteger.class, false));
String str2 = "-123456789012345678901234567890";
BigInteger val2 = new BigInteger(str2);
- assertEquals(str2, JavaConversionUtils.java2String(val2, false));
- assertEquals(val2, JavaConversionUtils.string2Java(str2, BigInteger.class, false));
+ assertEquals(str2, JavaConversionUtils.stringify(val2, false));
+ assertEquals(val2, JavaConversionUtils.parse(str2, BigInteger.class, false));
assertFailsConversionToObject(
"converted non-integer value",
@@ -451,13 +451,13 @@
String str1 = "12345678901234567890.123456789";
BigDecimal val1 = new BigDecimal(str1);
- assertEquals(str1, JavaConversionUtils.java2String(val1, false));
- assertEquals(val1, JavaConversionUtils.string2Java(str1, BigDecimal.class, false));
+ assertEquals(str1, JavaConversionUtils.stringify(val1, false));
+ assertEquals(val1, JavaConversionUtils.parse(str1, BigDecimal.class, false));
String str2 = "-12345678901234567890.123456789";
BigDecimal val2 = new BigDecimal(str2);
- assertEquals(str2, JavaConversionUtils.java2String(val2, false));
- assertEquals(val2, JavaConversionUtils.string2Java(str2, BigDecimal.class, false));
+ assertEquals(str2, JavaConversionUtils.stringify(val2, false));
+ assertEquals(val2, JavaConversionUtils.parse(str2, BigDecimal.class, false));
assertFailsConversionToObject(
"converted non-numeric value",
@@ -478,8 +478,8 @@
// for default conversion, we create string from value
Date val1 = new Date(1247551703000L);
String str1 = val1.toString();
- assertEquals(str1, JavaConversionUtils.java2String(val1, false));
- assertEquals(val1, JavaConversionUtils.string2Java(str1, Date.class, false));
+ assertEquals(str1, JavaConversionUtils.stringify(val1, false));
+ assertEquals(val1, JavaConversionUtils.parse(str1, Date.class, false));
assertFailsConversionToObject(
@@ -498,8 +498,8 @@
Date val1 = new Date(1247551703000L);
String str1 = "2009-07-14T06:08:23";
- assertEquals(str1, JavaConversionUtils.java2String(val1, true));
- assertEquals(val1, JavaConversionUtils.string2Java(str1, Date.class, true));
+ assertEquals(str1, JavaConversionUtils.stringify(val1, true));
+ assertEquals(val1, JavaConversionUtils.parse(str1, Date.class, true));
assertFailsConversionToObject(
"converted non-date value",
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-10-20 20:54:09
|
Revision: 170
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=170&view=rev
Author: kdgregory
Date: 2009-10-20 20:54:00 +0000 (Tue, 20 Oct 2009)
Log Message:
-----------
add Xml2JsonOptions.USE_XSI_TYPE
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java 2009-10-15 20:49:36 UTC (rev 169)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonConverter.java 2009-10-20 20:54:00 UTC (rev 170)
@@ -17,13 +17,19 @@
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import javax.xml.XMLConstants;
+
import net.sf.practicalxml.DomUtil;
+import net.sf.practicalxml.internal.StringUtils;
import org.w3c.dom.Element;
+import org.w3c.dom.Node;
/**
@@ -31,6 +37,38 @@
*/
public class Xml2JsonConverter
{
+ /**
+ * Lookup table for XSD types that can potentially be unquoted.
+ */
+ private static Set<String> _unquotedXsd = new HashSet<String>();
+ static
+ {
+ _unquotedXsd.add("xsd:boolean");
+ _unquotedXsd.add("xsd:byte");
+ _unquotedXsd.add("xsd:decimal");
+ _unquotedXsd.add("xsd:double");
+ _unquotedXsd.add("xsd:float");
+ _unquotedXsd.add("xsd:int");
+ _unquotedXsd.add("xsd:integer");
+ _unquotedXsd.add("xsd:long");
+ _unquotedXsd.add("xsd:negativeInteger");
+ _unquotedXsd.add("xsd:nonNegativeInteger");
+ _unquotedXsd.add("xsd:nonPositiveInteger");
+ _unquotedXsd.add("xsd:positiveInteger");
+ _unquotedXsd.add("xsd:short");
+ _unquotedXsd.add("xsd:unsignedByte");
+ _unquotedXsd.add("xsd:unsignedInt");
+ _unquotedXsd.add("xsd:unsignedLong");
+ _unquotedXsd.add("xsd:unsignedShort");
+ }
+
+
+//----------------------------------------------------------------------------
+// Instance variables and constructors
+//----------------------------------------------------------------------------
+
+
+
private EnumSet<Xml2JsonOptions> _options = EnumSet.noneOf(Xml2JsonOptions.class);
@@ -66,11 +104,11 @@
if (_options.contains(Xml2JsonOptions.WRAP_WITH_PARENS))
{
buf.append("(");
- append(buf, elem);
+ appendObject(buf, elem);
buf.append(")");
}
else
- append(buf, elem);
+ appendObject(buf, elem);
return buf;
}
@@ -79,26 +117,36 @@
// Internals
//----------------------------------------------------------------------------
- // yes, this method is just a restatement of convert(Element,StringBuilder)
- // I want all the internal appenders named "append".
private StringBuilder append(StringBuilder buf, Element elem)
{
- List<Element> children = DomUtil.getChildren(elem);
+ if (isSimple(elem))
+ return appendText(buf, elem);
+
+ return appendObject(buf, elem);
+ }
+
+
+ private StringBuilder appendText(StringBuilder buf, Element elem)
+ {
String text = DomUtil.getText(elem);
+ String type = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
+ String quote = "\"";
+ if (_options.contains(Xml2JsonOptions.USE_XSI_TYPE) && _unquotedXsd.contains(type))
+ quote = "";
- if ((children.size() > 0) || (text == null))
- return appendObject(buf, children);
- else
- return appendText(buf, text);
+ buf.append(quote)
+ .append(JsonUtil.escape(text))
+ .append(quote);
+ return buf;
}
- private StringBuilder appendObject(StringBuilder buf, List<Element> children)
+ private StringBuilder appendObject(StringBuilder buf, Element elem)
{
List<String> names = new ArrayList<String>();
Map<String,List<Element>> arrays = new HashMap<String,List<Element>>();
Map<String,Element> nonArrays = new HashMap<String,Element>();
- categorizeChildren(children, names, arrays, nonArrays);
+ categorizeChildren(elem, names, arrays, nonArrays);
buf.append("{");
for (Iterator<String> itx = names.iterator() ; itx.hasNext() ; )
@@ -132,62 +180,100 @@
}
+ private StringBuilder appendFieldName(StringBuilder buf, String name)
+ {
+ if (_options.contains(Xml2JsonOptions.UNQUOTED_FIELD_NAMES))
+ {
+ buf.append(name);
+ }
+ else
+ {
+ buf.append('"')
+ .append(name)
+ .append('"');
+ }
+
+ buf.append(": ");
+ return buf;
+ }
+
+
/**
* Examines the children of the passed element and categorizes them as
* "array" or "not array", while tracking the first appearance of the
* element name in document order.
*/
private void categorizeChildren(
- List<Element> children, List<String> names,
- Map<String,List<Element>> arrays, Map<String,Element> nonArrays)
+ Element elem,
+ List<String> names,
+ Map<String,List<Element>> arrays,
+ Map<String,Element> nonArrays)
{
- for (Element child : children)
+ for (Element child : DomUtil.getChildren(elem))
{
String name = DomUtil.getLocalName(child);
+ if (!arrays.containsKey(name) && !nonArrays.containsKey(name))
+ names.add(name);
+
if (arrays.containsKey(name))
{
- arrays.get(name).add(child);
+ getArray(name, arrays).add(child);
}
else if (nonArrays.containsKey(name))
{
+ List<Element> array = getArray(name, arrays);
Element prev = nonArrays.remove(name);
- List<Element> list = new ArrayList<Element>(2);
- list.add(prev);
- list.add(child);
- arrays.put(name, list);
+ array.add(prev);
+ array.add(child);
}
+ else if (isArrayParent(child))
+ {
+ List<Element> array = getArray(name, arrays);
+ for (Element grandchild : DomUtil.getChildren(child))
+ array.add(grandchild);
+ }
else
{
nonArrays.put(name, child);
- names.add(name);
}
}
}
- private StringBuilder appendFieldName(StringBuilder buf, String name)
+ private List<Element> getArray(String name, Map<String,List<Element>> arrays)
{
- if (_options.contains(Xml2JsonOptions.UNQUOTED_FIELD_NAMES))
+ List<Element> array = arrays.get(name);
+ if (array == null)
{
- buf.append(name);
+ array = new ArrayList<Element>();
+ arrays.put(name, array);
}
- else
+ return array;
+ }
+
+
+ private boolean isSimple(Element elem)
+ {
+ for (Node child = elem.getFirstChild() ; child != null ; child = child.getNextSibling())
{
- buf.append('"')
- .append(name)
- .append('"');
+ if (child instanceof Element)
+ return false;
}
-
- buf.append(": ");
- return buf;
+ return true;
}
- private StringBuilder appendText(StringBuilder buf, String text)
+ private boolean isArrayParent(Element elem)
{
- buf.append('"')
- .append(JsonUtil.escape(text))
- .append('"');
- return buf;
+ if (!_options.contains(Xml2JsonOptions.USE_XSI_TYPE))
+ return false;
+
+ String type = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
+ if (StringUtils.isEmpty(type))
+ return false;
+ if (type.startsWith("java:["))
+ return true;
+
+ return false;
}
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java 2009-10-15 20:49:36 UTC (rev 169)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/json/Xml2JsonOptions.java 2009-10-20 20:54:00 UTC (rev 170)
@@ -16,7 +16,7 @@
/**
- * Options to control conversion from XML documents to JSON strings
+ * Options to control conversion from XML documents to JSON strings.
*/
public enum Xml2JsonOptions
{
@@ -32,6 +32,25 @@
UNQUOTED_FIELD_NAMES,
/**
+ * If enabled, the converter will look for an <code>xsi:type</code>
+ * attribute (<code>type</code> in XML Schema Instance namespace), and
+ * apply the following rules:
+ * <ul>
+ * <li> If the attribute value begins with "xsd:", and the portion after
+ * the ":" is one of the XSD primitive numeric or boolean types, the
+ * element's value will be emitted without quotes.
+ * <li> If the attribute value begins with "java:", and the portion
+ * after the ":" corresponds to a Java array type or standard
+ * collection type, then the element's content will be emitted
+ * as a JSON array (assumes zero or more sub-elements).
+ * </ul>
+ * These rules are designed to allow use of XML produced by {@link
+ * net.sf.practicalxml.converter.BeanConverter}, preserving knowledge
+ * about the bean structure.
+ */
+ USE_XSI_TYPE,
+
+ /**
* If enabled, the entire string is wrapped by parentheses. This is
* needed for strings that will be passed to <code>eval()</code>.
* Note that the resulting string is not acceptable to {@link
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-10-15 20:49:36 UTC (rev 169)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/json/TestXml2JsonConverter.java 2009-10-20 20:54:00 UTC (rev 170)
@@ -87,8 +87,24 @@
}
- public void testArray() throws Exception
+ public void testPrimitivesWithXsiType() throws Exception
{
+ // unquoted field names for readability
+ convertAndAssert(
+ "{int: 123, boolean: true, decimal: 1234567890.1234567890, "
+ + "intWithoutType: \"123456\"}",
+ element("data",
+ element("int", text("123"), xsiType("xsd:int")),
+ element("boolean", text("true"), xsiType("xsd:boolean")),
+ element("decimal", text("1234567890.1234567890"), xsiType("xsd:decimal")),
+ element("intWithoutType", text("123456"))),
+ Xml2JsonOptions.UNQUOTED_FIELD_NAMES,
+ Xml2JsonOptions.USE_XSI_TYPE);
+ }
+
+
+ public void testArrayAsRepeatedElement() throws Exception
+ {
// note that "argle" elements are not adjacent, must become adjacent
convertAndAssert(
"{\"foo\": \"bar\", \"argle\": [\"bargle\", \"wargle\"], \"baz\": \"bar\"}",
@@ -100,6 +116,30 @@
}
+ public void testArrayPerXsiType() throws Exception
+ {
+ // note: using xsi:type implies that numbers won't be quoted
+ // also: array member name is ignored
+ convertAndAssert(
+ "{\"value\": [123, 456]}",
+ element("data",
+ element("value", xsiType("java:" + int[].class.getName()),
+ element("foo", text("123"), xsiType("xsd:int")),
+ element("bar", text("456"), xsiType("xsd:int")))),
+ Xml2JsonOptions.USE_XSI_TYPE);
+ }
+
+
+ public void testEmptyArrayPerXsiType() throws Exception
+ {
+ convertAndAssert(
+ "{\"value\": []}",
+ element("data",
+ element("value", xsiType("java:" + int[].class.getName()))),
+ Xml2JsonOptions.USE_XSI_TYPE);
+ }
+
+
public void testArrayWithNestedObject() throws Exception
{
convertAndAssert(
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-10-15 20:49:45
|
Revision: 169
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=169&view=rev
Author: kdgregory
Date: 2009-10-15 20:49:36 +0000 (Thu, 15 Oct 2009)
Log Message:
-----------
removing release tags that don't correspond to released files
Removed Paths:
-------------
tags/rel-1.0.1/
tags/rel-1.0.2/
tags/rel-1.0.3/
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-10-15 20:48:37
|
Revision: 168
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=168&view=rev
Author: kdgregory
Date: 2009-10-15 20:48:29 +0000 (Thu, 15 Oct 2009)
Log Message:
-----------
release tag
Added Paths:
-----------
tags/rel-1.0.5/
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-10-15 20:21:11
|
Revision: 167
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=167&view=rev
Author: kdgregory
Date: 2009-10-15 20:21:03 +0000 (Thu, 15 Oct 2009)
Log Message:
-----------
add distributionManagement section that deploys to local directory
Modified Paths:
--------------
trunk/pom.xml
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2009-10-15 19:56:40 UTC (rev 166)
+++ trunk/pom.xml 2009-10-15 20:21:03 UTC (rev 167)
@@ -138,9 +138,20 @@
<dependencies>
<dependency>
+ <!-- note, scope is not limited to testing:
+ DOMAsserts depends on Asserts -->
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.2</version>
</dependency>
</dependencies>
+
+
+ <distributionManagement>
+ <repository>
+ <id>build</id>
+ <name>PracticalXML Build-Deploy Directory</name>
+ <url>file://${project.build.directory}/deploy</url>
+ </repository>
+ </distributionManagement>
</project>
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-10-15 19:56:47
|
Revision: 166
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=166&view=rev
Author: kdgregory
Date: 2009-10-15 19:56:40 +0000 (Thu, 15 Oct 2009)
Log Message:
-----------
fix typo
Modified Paths:
--------------
trunk/src/main/java/net/sf/practicalxml/ParseUtil.java
Modified: trunk/src/main/java/net/sf/practicalxml/ParseUtil.java
===================================================================
--- trunk/src/main/java/net/sf/practicalxml/ParseUtil.java 2009-10-13 22:15:48 UTC (rev 165)
+++ trunk/src/main/java/net/sf/practicalxml/ParseUtil.java 2009-10-15 19:56:40 UTC (rev 166)
@@ -233,7 +233,7 @@
}
catch (ParserConfigurationException e)
{
- throw new XmlException("unable to confiure parser", e);
+ throw new XmlException("unable to configure parser", e);
}
}
}
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-10-13 22:15:55
|
Revision: 165
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=165&view=rev
Author: kdgregory
Date: 2009-10-13 22:15:48 +0000 (Tue, 13 Oct 2009)
Log Message:
-----------
rename option: CACHE_INTROSPECTIONS is active voice, INTROSPECTION_CACHE isn't
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanOptions.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-10-13 18:35:12 UTC (rev 164)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-10-13 22:15:48 UTC (rev 165)
@@ -47,7 +47,7 @@
for (Bean2XmlOptions option : options)
_options.add(option);
_helper = new PrimitiveConversionHelper(shouldUseXsdFormatting());
- _introspections = new IntrospectionCache(_options.contains(Bean2XmlOptions.INTROSPECTION_CACHE));
+ _introspections = new IntrospectionCache(_options.contains(Bean2XmlOptions.CACHE_INTROSPECTIONS));
}
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-10-13 18:35:12 UTC (rev 164)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java 2009-10-13 22:15:48 UTC (rev 165)
@@ -22,6 +22,15 @@
public enum Bean2XmlOptions
{
/**
+ * Will use a shared static introspection cache for all conversions.
+ * <p>
+ * <strong>Warning</strong>: if you use this option, do not store this
+ * library in a shared app-server classpath. If you do, the cache will
+ * prevent class unloading, and you will run out of permgen space.
+ */
+ CACHE_INTROSPECTIONS,
+
+ /**
* 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.
@@ -88,14 +97,5 @@
* <p>
* <em>This option implies {@link #XSD_FORMAT} for simple types</em>.
*/
- XSI_TYPE,
-
- /**
- * Will use a shared static introspection cache for all conversions.
- * <p>
- * <strong>Warning</strong>: if you use this option, do not store this
- * library in a shared app-server classpath. If you do, the cache will
- * prevent class unloading, and you will run out of permgen space.
- */
- INTROSPECTION_CACHE
+ XSI_TYPE
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java 2009-10-13 18:35:12 UTC (rev 164)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java 2009-10-13 22:15:48 UTC (rev 165)
@@ -59,7 +59,7 @@
_options.add(option);
_helper = new PrimitiveConversionHelper(_options.contains(Xml2BeanOptions.EXPECT_XSD_FORMAT));
- _introspections = new IntrospectionCache(_options.contains(Xml2BeanOptions.INTROSPECTION_CACHE));
+ _introspections = new IntrospectionCache(_options.contains(Xml2BeanOptions.CACHE_INTROSPECTIONS));
}
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-10-13 18:35:12 UTC (rev 164)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanOptions.java 2009-10-13 22:15:48 UTC (rev 165)
@@ -23,6 +23,15 @@
public enum Xml2BeanOptions
{
/**
+ * Will use a shared static introspection cache for all conversions.
+ * <p>
+ * <strong>Warning</strong>: if you use this option, do not store this
+ * library in a shared app-server classpath. If you do, the cache will
+ * prevent class unloading, and you will run out of permgen space.
+ */
+ CACHE_INTROSPECTIONS,
+
+ /**
* 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>.
@@ -54,14 +63,5 @@
* uses the <code>xsi:type</code> value to choose between different setter
* methods, but otherwise ignores it.
*/
- REQUIRE_XSI_TYPE,
-
- /**
- * Will use a shared static introspection cache for all conversions.
- * <p>
- * <strong>Warning</strong>: if you use this option, do not store this
- * library in a shared app-server classpath. If you do, the cache will
- * prevent class unloading, and you will run out of permgen space.
- */
- INTROSPECTION_CACHE
+ REQUIRE_XSI_TYPE
}
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-10-13 18:35:34
|
Revision: 164
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=164&view=rev
Author: kdgregory
Date: 2009-10-13 18:35:12 +0000 (Tue, 13 Oct 2009)
Log Message:
-----------
replace java.beans.Introspector with homegrown alternative
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/Bean2XmlConverter.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/Xml2BeanConverter.java
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/package.html
Added Paths:
-----------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Introspection.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/IntrospectionCache.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestIntrospection.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestIntrospectionCache.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-10-10 18:19:28 UTC (rev 163)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/BeanConverter.java 2009-10-13 18:35:12 UTC (rev 164)
@@ -33,12 +33,6 @@
* {@link net.sf.practicalxml.converter.bean.Bean2XmlConverter} and
* {@link net.sf.practicalxml.converter.bean.Xml2BeanConverter}. If static
* methods and throwaway objects offend you then use those classes directly.
- * <p>
- * <strong>Warning</strong>:
- * Bean-to-XML conversion uses <code>java.beans.Introspector</code>, which
- * holds a cache of introspected objects. If you use this conversion in an
- * app-server you should call <code>Introspector.flushCaches()</code> during
- * deploy.
*/
public class BeanConverter
{
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-10-10 18:19:28 UTC (rev 163)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-10-13 18:35:12 UTC (rev 164)
@@ -14,12 +14,7 @@
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;
@@ -42,14 +37,17 @@
*/
public class Bean2XmlConverter
{
+ private EnumSet<Bean2XmlOptions> _options;
private PrimitiveConversionHelper _helper;
- private EnumSet<Bean2XmlOptions> _options = EnumSet.noneOf(Bean2XmlOptions.class);
+ private IntrospectionCache _introspections;
public Bean2XmlConverter(Bean2XmlOptions... options)
{
+ _options = EnumSet.noneOf(Bean2XmlOptions.class);
for (Bean2XmlOptions option : options)
_options.add(option);
_helper = new PrimitiveConversionHelper(shouldUseXsdFormatting());
+ _introspections = new IntrospectionCache(_options.contains(Bean2XmlOptions.INTROSPECTION_CACHE));
}
@@ -225,33 +223,20 @@
{
Element parent = appender.appendContainer(name, DomUtilToo.getXsiTypeForJavaObject(bean));
Appender childAppender = new BasicAppender(parent, _options);
- try
- {
- BeanInfo info = Introspector.getBeanInfo(bean.getClass(), Object.class);
- PropertyDescriptor[] props = info.getPropertyDescriptors();
- for (int ii = 0 ; ii < props.length ; ii++)
- convertBeanProperty(bean, props[ii], childAppender);
- }
- catch (IntrospectionException ee)
- {
- throw new ConversionException("introspection failure", ee);
- }
+ Introspection ispec = _introspections.lookup(bean.getClass());
+ for (String propName : ispec.propertyNames())
+ convertBeanProperty(bean, ispec, propName, childAppender);
return true;
}
private void convertBeanProperty(
- Object bean, PropertyDescriptor propDesc, Appender appender)
+ Object bean, Introspection ispec, String propName, 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);
+ value = ispec.getter(propName).invoke(bean);
}
catch (Exception ee)
{
@@ -259,9 +244,9 @@
}
if (value == null)
- tryToConvertAsPrimitiveOrNull(null, type, name, appender);
+ tryToConvertAsPrimitiveOrNull(null, ispec.type(propName), propName, appender);
else
- convert(value, name, appender);
+ convert(value, propName, appender);
}
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-10-10 18:19:28 UTC (rev 163)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java 2009-10-13 18:35:12 UTC (rev 164)
@@ -88,5 +88,14 @@
* <p>
* <em>This option implies {@link #XSD_FORMAT} for simple types</em>.
*/
- XSI_TYPE
+ XSI_TYPE,
+
+ /**
+ * Will use a shared static introspection cache for all conversions.
+ * <p>
+ * <strong>Warning</strong>: if you use this option, do not store this
+ * library in a shared app-server classpath. If you do, the cache will
+ * prevent class unloading, and you will run out of permgen space.
+ */
+ INTROSPECTION_CACHE
}
Added: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Introspection.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Introspection.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Introspection.java 2009-10-13 18:35:12 UTC (rev 164)
@@ -0,0 +1,251 @@
+// 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.Introspector;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import net.sf.practicalxml.converter.ConversionException;
+
+
+/**
+ * A replacement for <code>java.beans.Introspector</code> that is tailored to
+ * the operation of <code>BeanConverter</code>:
+ * <dl>
+ * <dt>Identifies multiple accessor methods
+ * <dd><code>javax.beans.Introspector</code> looks at parameter type, and
+ * attempts to match getters and setters. This method looks only at the
+ * method name, and will return any method whose name starts with "get"
+ * or "is".
+ * <dt>Ignores case in name comparison
+ * <dd><code>javax.beans.Introspector</code> has camel-casing rules that do
+ * not always correspond to programmer intent -- in particular, two
+ * initial capitals are not camelcased.
+ * <dt>Resolves of multiple setter methods for same property
+ * <dd>In the case where there are multiple getters/setters with the same
+ * name, the following ranking is applied:
+ * <ol>
+ * <li> Methods defined by subclass, over those defined by superclass.
+ * The subclass is assumed to be more specific.
+ * <li> Methods that get/take primitive values.
+ * <li> Methods that get/take primitive wrappers.
+ * <li> Methods that get/take <code>String</code>. Driven by the use of
+ * this introspector to translate to/from a text format.
+ * <li> Methods that get/take arbitrary objects.
+ * </ol>
+ * <dt>Resolves multiple getter methods for same property
+ * <dd>For class hierarchies that define covariant return types, will use
+ * the most specific type.
+ * <dt>Ignores properties defined by <code>Object</code>
+ * <dd><code>javax.beans.Introspector</code> allows specific control over the
+ * parts of the class hierarchy to be introspected; by default, it will
+ * include methods defined by <code>Object</code>. We don't care about
+ * those, but assume any other class in the hierarchy to be important.
+ * </dl>
+ * <p>
+ * Also unlike <code>javax.beans.Introspector</code>, instances of this
+ * class are constructed around a target class (thus the different name).
+ * Use {@link IntrospectionCache} for caching and lookup services.
+ * <p>
+ * Instances of this class are read-only (and threadsafe) once constructed.
+ */
+public class Introspection
+{
+ private Set<String> _propNames;
+ private Set<String> _propNamesPublic;
+ private Map<String,Method> _getters;
+ private Map<String,Method> _setters;
+
+
+ /**
+ * Introspects the specified class, per the rules above.
+ *
+ * @throws ConversionException on any error.
+ */
+ public Introspection(Class<?> klass)
+ {
+ _propNames = new HashSet<String>();
+ _propNamesPublic = Collections.unmodifiableSet(_propNames);
+ _getters = new HashMap<String,Method>();
+ _setters = new HashMap<String,Method>();
+
+ introspect(klass);
+ }
+
+//----------------------------------------------------------------------------
+// Public Methods
+//----------------------------------------------------------------------------
+
+ /**
+ * Returns the property names for the specified class. These names are
+ * generated from getter methods -- any method beginning with "get"
+ * or "is". The returned set is unmodifiable, and will be empty if
+ * there are no properties with bean-style getter methods.
+ * <p>
+ * Names are processed by <code>Introspector.decapitalize()</code>, so
+ * will be consistent with the bean specification.
+ */
+ public Set<String> propertyNames()
+ {
+ return _propNamesPublic;
+ }
+
+
+ /**
+ * Returns the getter method for the named property, <code>null</code>
+ * no method is known (all properties returned by {@link #propertyNames}
+ * must have getters, but may not have setters).
+ */
+ public Method getter(String propName)
+ {
+ return _getters.get(propName.toLowerCase());
+ }
+
+
+ /**
+ * Returns the setter method for the named property, <code>null</code>
+ * if unable to find a method.
+ */
+ public Method setter(String propName)
+ {
+ return _setters.get(propName.toLowerCase());
+ }
+
+
+ /**
+ * Returns the type of the named property, taken from the return type
+ * of the property's getter. Will be <code>null</code> if the property
+ * isn't known.
+ */
+ public Class<?> type(String propName)
+ {
+ Method getter = getter(propName);
+ return (getter == null)
+ ? null
+ : getter.getReturnType();
+ }
+
+
+//----------------------------------------------------------------------------
+// Internals
+//----------------------------------------------------------------------------
+
+ private void introspect(Class<?> klass)
+ {
+ try
+ {
+ for (Method method : klass.getMethods())
+ {
+ if (method.getDeclaringClass() == Object.class)
+ continue;
+
+ String methodName = method.getName();
+ if (methodName.startsWith("get"))
+ {
+ String propName = extractAndSavePropName(methodName, 3);
+ saveGetter(propName, method);
+ }
+ else if (methodName.startsWith("is"))
+ {
+ String propName = extractAndSavePropName(methodName, 2);
+ saveGetter(propName, method);
+ }
+ else if (methodName.startsWith("set"))
+ {
+ String propName = extractAndSavePropName(methodName, 3);
+ saveSetter(propName, method);
+ }
+ }
+ }
+ catch (Exception ee)
+ {
+ throw new ConversionException("unable to introspect", ee);
+ }
+ }
+
+
+ private String extractAndSavePropName(String methodName, int pos)
+ {
+ String propName = methodName.substring(pos);
+ _propNames.add(Introspector.decapitalize(propName));
+ return propName.toLowerCase();
+ }
+
+
+ private void saveGetter(String propName, Method method)
+ {
+ Method existing = _getters.get(propName);
+ if (existing == null)
+ {
+ _getters.put(propName, method);
+ return;
+ }
+
+ Class<?> methodClass = method.getReturnType();
+ Class<?> existingClass = existing.getReturnType();
+ if (existingClass.isAssignableFrom(methodClass))
+ {
+ _getters.put(propName, method);
+ return;
+ }
+ }
+
+
+ private void saveSetter(String propName, Method method)
+ {
+ Method existing = _setters.get(propName);
+ if (existing == null)
+ {
+ _setters.put(propName, method);
+ return;
+ }
+
+ Class<?> methodClass = method.getDeclaringClass();
+ Class<?> existingClass = existing.getDeclaringClass();
+ if (!existingClass.isAssignableFrom(methodClass))
+ return; // existing is subclass, keep it
+
+ if (methodClass != existingClass)
+ {
+ // existing is superclass, take subclass
+ _setters.put(propName, method);
+ return;
+ }
+
+ if (setterRank(method) < setterRank(existing))
+ {
+ _setters.put(propName, method);
+ return;
+ }
+ }
+
+
+ private static int setterRank(Method method)
+ {
+ Class<?> parmClass = method.getParameterTypes()[0];
+ if (parmClass.isPrimitive())
+ return 1;
+ if (Number.class.isAssignableFrom(parmClass))
+ return 2;
+ if (String.class.isAssignableFrom(parmClass))
+ return 3;
+ return 4;
+ }
+}
Added: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/IntrospectionCache.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/IntrospectionCache.java (rev 0)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/IntrospectionCache.java 2009-10-13 18:35:12 UTC (rev 164)
@@ -0,0 +1,65 @@
+// 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.HashMap;
+import java.util.Map;
+
+
+/**
+ * A thread-safe cache of {@link Introspection} objects. May be constructed
+ * using either a local or shared (static) cache.
+ */
+public class IntrospectionCache
+{
+ private static Map<Class<?>,Introspection> _staticCache = new HashMap<Class<?>,Introspection>();
+ private Map<Class<?>,Introspection> _cache;
+
+
+ /**
+ * Creates an instance that uses a local cache.
+ */
+ public IntrospectionCache()
+ {
+ this(false);
+ }
+
+
+ /**
+ * Creates an instance that will either use a local or shared (static) cache.
+ */
+ public IntrospectionCache(boolean shared)
+ {
+ _cache = shared ? _staticCache
+ : new HashMap<Class<?>,Introspection>();
+ }
+
+
+ /**
+ * Returns an {@link Introspection} of the passed class.
+ *
+ * @throws ConversionError if unable to introspect the class.
+ */
+ public synchronized Introspection lookup(Class<?> klass)
+ {
+ Introspection result = _cache.get(klass);
+ if (result == null)
+ {
+ result = new Introspection(klass);
+ _cache.put(klass, result);
+ }
+ return result;
+ }
+}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java 2009-10-10 18:19:28 UTC (rev 163)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java 2009-10-13 18:35:12 UTC (rev 164)
@@ -14,10 +14,6 @@
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;
@@ -53,7 +49,7 @@
{
private EnumSet<Xml2BeanOptions> _options;
private PrimitiveConversionHelper _helper;
- private Map<Class<?>,Map<String,Method>> _introspectedClasses;
+ private IntrospectionCache _introspections;
public Xml2BeanConverter(Xml2BeanOptions... options)
@@ -63,7 +59,7 @@
_options.add(option);
_helper = new PrimitiveConversionHelper(_options.contains(Xml2BeanOptions.EXPECT_XSD_FORMAT));
- _introspectedClasses = new HashMap<Class<?>,Map<String,Method>>();
+ _introspections = new IntrospectionCache(_options.contains(Xml2BeanOptions.INTROSPECTION_CACHE));
}
@@ -298,11 +294,8 @@
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));
+ Method setter = _introspections.lookup(beanKlass)
+ .setter(DomUtil.getLocalName(child));
if ((setter == null) && !_options.contains(Xml2BeanOptions.IGNORE_MISSING_PROPERTIES))
{
throw new ConversionException("can't find property setter", child);
@@ -312,29 +305,6 @@
}
- private Map<String,Method> introspect(Class<?> klass)
- {
- Map<String,Method> methodMap = new HashMap<String,Method>();
- try
- {
- BeanInfo info = Introspector.getBeanInfo(klass, Object.class);
- for (PropertyDescriptor propDesc : info.getPropertyDescriptors())
- {
- Method setter = propDesc.getWriteMethod();
- if (setter != null)
- methodMap.put(propDesc.getName(), setter);
- }
- }
- catch (IntrospectionException ee)
- {
- throw new ConversionException("unable to introspect", ee);
- }
-
- _introspectedClasses.put(klass, methodMap);
- return methodMap;
- }
-
-
/**
* Attempts to create a <code>Collection</code> instance appropriate for
* the passed class, returns <code>null</code> if unable.
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-10-10 18:19:28 UTC (rev 163)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanOptions.java 2009-10-13 18:35:12 UTC (rev 164)
@@ -54,5 +54,14 @@
* uses the <code>xsi:type</code> value to choose between different setter
* methods, but otherwise ignores it.
*/
- REQUIRE_XSI_TYPE
+ REQUIRE_XSI_TYPE,
+
+ /**
+ * Will use a shared static introspection cache for all conversions.
+ * <p>
+ * <strong>Warning</strong>: if you use this option, do not store this
+ * library in a shared app-server classpath. If you do, the cache will
+ * prevent class unloading, and you will run out of permgen space.
+ */
+ INTROSPECTION_CACHE
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/package.html
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/package.html 2009-10-10 18:19:28 UTC (rev 163)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/package.html 2009-10-13 18:35:12 UTC (rev 164)
@@ -120,15 +120,8 @@
</ul>
<tr><td>Bean-structured Objects
<td>The object is introspected, and properties are written in the order
- provided by the <code>Introspector</code>. Note that this means you
- can't validate beans against a schema, as the order of elements may
- change.
- <p>
- <strong>Warning</strong>:
- Bean-to-XML conversion uses <code>java.beans.Introspector</code>, which
- holds a cache of introspected objects. If you use this conversion in an
- app-server you should call <code>Introspector.flushCaches()</code> during
- deploy.
+ provided by the introspector. Note that this means you can't validate
+ beans against a schema, as the order of elements may change.
<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>
Added: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestIntrospection.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestIntrospection.java (rev 0)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestIntrospection.java 2009-10-13 18:35:12 UTC (rev 164)
@@ -0,0 +1,324 @@
+// 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.lang.reflect.Method;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+
+public class TestIntrospection
+extends TestCase
+{
+ public TestIntrospection(String testName)
+ {
+ super(testName);
+ }
+
+
+//----------------------------------------------------------------------------
+// Classes to introspect -- all must be public and static
+//----------------------------------------------------------------------------
+
+ /**
+ * A simple bean class, with both primitive and object properties, and
+ * getters that use both "get" and "is".
+ */
+ public static class SimpleBean
+ {
+ private String _sVal;
+ private int _iVal;
+ private boolean _bVal;
+
+ public String getSVal() { return _sVal; }
+ public void setSVal(String val) { _sVal = val; }
+
+ public int getIVal() { return _iVal; }
+ public void setIVal(int val) { _iVal = val; }
+
+ public boolean isBVal() { return _bVal; }
+ public void setBVal(boolean val) { _bVal = val; }
+ }
+
+
+ /**
+ * A class that violates the bean spec by providing getters and setters
+ * with different types.
+ */
+ public static class MixedPrimitiveAndWrapperBean
+ {
+ private Integer _iVal;
+
+ public Integer getIVal() { return _iVal; }
+ public void setIVal(int val) { _iVal = Integer.valueOf(val); }
+ }
+
+
+ /**
+ * A class that provides a variety of setters for its values.
+ */
+ public static class MultipleSetterBean
+ {
+ private String _propS1;
+ private String _propS2;
+ private Integer _propI1;
+ private Integer _propI2;
+ private Integer _propI3;
+ private Integer _propI4;
+
+ public String getPropS1() { return _propS1; }
+ public void setPropS1(String val) { _propS1 = val; }
+ public void setPropS1(Object val) { _propS1 = String.valueOf(val); }
+
+ public String getPropS2() { return _propS2; }
+ public void setPropS2(Object val) { _propS2 = String.valueOf(val); }
+
+ public Integer getPropI1() { return _propI1; }
+ public void setPropI1(Integer val) { _propI1 = val; }
+ public void setPropI1(int val) { _propI1 = Integer.valueOf(val); }
+
+ public Integer getPropI2() { return _propI2; }
+ public void setPropI2(String val) { _propI2 = Integer.valueOf(val); }
+ public void setPropI2(Integer val) { _propI2 = val; }
+
+ public Integer getPropI3() { return _propI3; }
+ public void setPropI3(String val) { _propI3 = Integer.valueOf(val); }
+ public void setPropI3(Object val) { _propI3 = Integer.valueOf(String.valueOf(val)); }
+
+ public Integer getPropI4() { return _propI4; }
+ public void setPropI4(Object val) { _propI4 = Integer.valueOf(String.valueOf(val)); }
+ }
+
+
+ /**
+ * Base class for override tests.
+ */
+ public static class OverrideBaseBean
+ {
+ protected Integer _iVal;
+
+ public Number getIVal() { return _iVal; }
+ public void setIVal(Integer val) { _iVal = val; }
+ }
+
+
+ /**
+ * Subclass for override tests.
+ */
+ public static class OverrideChildBean
+ extends OverrideBaseBean
+ {
+ @Override
+ public Integer getIVal() { return _iVal; }
+ public void setIVal(String val) { _iVal = Integer.valueOf(val); }
+ }
+
+
+ /**
+ * This class has setters for all fields, but is missing a getter. The
+ * introspector should ignore that field.
+ */
+ public static class MissingGetterBean
+ {
+ private String _propS1;
+ private String _propS2;
+
+ public String getPropS1() { return _propS1; }
+ public void setPropS1(String val) { _propS1 = val; }
+
+ public void setPropS2(String val) { _propS2 = val; }
+ }
+
+
+//----------------------------------------------------------------------------
+// Test Cases
+//----------------------------------------------------------------------------
+
+ public void testSimpleBean() throws Exception
+ {
+ Introspection ispec = new Introspection(SimpleBean.class);
+
+ Set<String> props = ispec.propertyNames();
+ assertEquals(3, props.size());
+ assertTrue(props.contains("SVal"));
+ assertTrue(props.contains("IVal"));
+ assertTrue(props.contains("BVal"));
+
+ assertEquals(String.class, ispec.type("sval"));
+ assertEquals(Integer.TYPE, ispec.type("ival"));
+ assertEquals(Boolean.TYPE, ispec.type("bval"));
+
+ Method getSVal = ispec.getter("sval");
+ assertEquals("getSVal", getSVal.getName());
+ assertEquals(String.class, getSVal.getReturnType());
+
+ Method setSVal = ispec.setter("sval");
+ assertEquals("setSVal", setSVal.getName());
+ assertEquals(String.class, setSVal.getParameterTypes()[0]);
+
+ Method getIVal = ispec.getter("ival");
+ assertEquals("getIVal", getIVal.getName());
+ assertEquals(Integer.TYPE, getIVal.getReturnType());
+
+ Method setIVal = ispec.setter("ival");
+ assertEquals("setIVal", setIVal.getName());
+ assertEquals(Integer.TYPE, setIVal.getParameterTypes()[0]);
+
+ Method getBVal = ispec.getter("bval");
+ assertEquals("isBVal", getBVal.getName());
+ assertEquals(Boolean.TYPE, getBVal.getReturnType());
+
+ Method setBVal = ispec.setter("bval");
+ assertEquals("setBVal", setBVal.getName());
+ assertEquals(Boolean.TYPE, setBVal.getParameterTypes()[0]);
+ }
+
+
+ public void testPropertyNamesIgnoreCase() throws Exception
+ {
+ Introspection ispec = new Introspection(SimpleBean.class);
+
+ Set<String> props = ispec.propertyNames();
+ assertTrue(props.contains("SVal"));
+ assertFalse(props.contains("sval"));
+ assertFalse(props.contains("SVAL"));
+
+ assertEquals(String.class, ispec.type("SVal"));
+ assertEquals(String.class, ispec.type("sval"));
+ assertEquals(String.class, ispec.type("SVAL"));
+
+ Method g1 = ispec.getter("SVal");
+ Method g2 = ispec.getter("sval");
+ Method g3 = ispec.getter("SVAL");
+ assertNotNull(g1);
+ assertSame(g1, g2);
+ assertSame(g1, g3);
+
+ Method s1 = ispec.setter("SVal");
+ Method s2 = ispec.setter("sval");
+ Method s3 = ispec.setter("SVAL");
+ assertNotNull(s1);
+ assertSame(s1, s2);
+ assertSame(s1, s3);
+ }
+
+
+
+ public void testMixingPrimitiveAndWrappers() throws Exception
+ {
+ Introspection ispec = new Introspection(MixedPrimitiveAndWrapperBean.class);
+
+ Set<String> props = ispec.propertyNames();
+ assertEquals(1, props.size());
+ assertTrue(props.contains("IVal"));
+
+ assertEquals(Integer.class, ispec.type("ival"));
+
+ Method getIVal = ispec.getter("ival");
+ assertEquals("getIVal", getIVal.getName());
+ assertEquals(Integer.class, getIVal.getReturnType());
+
+ Method setIVal = ispec.setter("ival");
+ assertEquals("setIVal", setIVal.getName());
+ assertEquals(Integer.TYPE, setIVal.getParameterTypes()[0]);
+ }
+
+
+ public void testSetterParameterRanking() throws Exception
+ {
+ Introspection ispec = new Introspection(MultipleSetterBean.class);
+
+ Set<String> props = ispec.propertyNames();
+ assertEquals(6, props.size());
+ assertTrue(props.contains("propS1"));
+ assertTrue(props.contains("propS2"));
+ assertTrue(props.contains("propI1"));
+ assertTrue(props.contains("propI2"));
+ assertTrue(props.contains("propI3"));
+ assertTrue(props.contains("propI4"));
+
+ Method setPropS1 = ispec.setter("propS1");
+ assertEquals("setPropS1", setPropS1.getName());
+ assertEquals(String.class, setPropS1.getParameterTypes()[0]);
+
+ Method setPropS2 = ispec.setter("propS2");
+ assertEquals("setPropS2", setPropS2.getName());
+ assertEquals(Object.class, setPropS2.getParameterTypes()[0]);
+
+ Method setPropI1 = ispec.setter("propI1");
+ assertEquals("setPropI1", setPropI1.getName());
+ assertEquals(Integer.TYPE, setPropI1.getParameterTypes()[0]);
+
+ Method setPropI2 = ispec.setter("propI2");
+ assertEquals("setPropI2", setPropI2.getName());
+ assertEquals(Integer.class, setPropI2.getParameterTypes()[0]);
+
+ Method setPropI3 = ispec.setter("propI3");
+ assertEquals("setPropI3", setPropI3.getName());
+ assertEquals(String.class, setPropI3.getParameterTypes()[0]);
+
+ Method setPropI4 = ispec.setter("propI4");
+ assertEquals("setPropI4", setPropI4.getName());
+ assertEquals(Object.class, setPropI4.getParameterTypes()[0]);
+ }
+
+
+ public void testSubclassSetterOverride() throws Exception
+ {
+ Introspection ispec = new Introspection(OverrideChildBean.class);
+
+ Set<String> props = ispec.propertyNames();
+ assertEquals(1, props.size());
+ assertTrue(props.contains("IVal"));
+
+ Method setIVal = ispec.setter("ival");
+ assertEquals("setIVal", setIVal.getName());
+ assertEquals(String.class, setIVal.getParameterTypes()[0]);
+ }
+
+
+ public void testSubclassGetterOverride() throws Exception
+ {
+ Introspection ispec = new Introspection(OverrideChildBean.class);
+
+ Set<String> props = ispec.propertyNames();
+ assertEquals(1, props.size());
+ assertTrue(props.contains("IVal"));
+
+ Method getIVal = ispec.getter("ival");
+ assertEquals("getIVal", getIVal.getName());
+ assertEquals(Integer.class, getIVal.getReturnType());
+ }
+
+
+ public void testMissingGetter() throws Exception
+ {
+ Introspection ispec = new Introspection(MissingGetterBean.class);
+
+ Set<String> props = ispec.propertyNames();
+ assertEquals(2, props.size());
+ assertTrue(props.contains("propS1"));
+ assertTrue(props.contains("propS2"));
+
+ assertNotNull(ispec.getter("propS1"));
+ assertNotNull(ispec.setter("propS1"));
+ assertEquals(String.class, ispec.type("propS1"));
+
+ assertNull(ispec.getter("propS2"));
+ assertNotNull(ispec.setter("propS2"));
+ assertNull(ispec.type("propS2"));
+ }
+}
Added: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestIntrospectionCache.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestIntrospectionCache.java (rev 0)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestIntrospectionCache.java 2009-10-13 18:35:12 UTC (rev 164)
@@ -0,0 +1,90 @@
+// 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 junit.framework.TestCase;
+
+public class TestIntrospectionCache
+extends TestCase
+{
+ public TestIntrospectionCache(String testName)
+ {
+ super(testName);
+ }
+
+
+//----------------------------------------------------------------------------
+// Test Objects
+//----------------------------------------------------------------------------
+
+ public static class Bean1
+ {
+ private String _sVal;
+
+ public String getSVal() { return _sVal; }
+ public void setSVal(String val) { _sVal = val; }
+ }
+
+
+ public static class Bean2
+ {
+ private String _sVal;
+
+ public String getSVal() { return _sVal; }
+ public void setSVal(String val) { _sVal = val; }
+ }
+
+//----------------------------------------------------------------------------
+// Test Cases
+//----------------------------------------------------------------------------
+
+ public void testBasicOperation() throws Exception
+ {
+ IntrospectionCache cache = new IntrospectionCache();
+
+ Introspection ispec1 = cache.lookup(Bean1.class);
+ assertNotNull(ispec1);
+
+ Introspection ispec2 = cache.lookup(Bean2.class);
+ assertNotNull(ispec2);
+ assertNotSame(ispec1, ispec2);
+
+ Introspection ispec3 = cache.lookup(Bean1.class);
+ assertNotNull(ispec3);
+ assertSame(ispec1, ispec3);
+ }
+
+
+ // note: this is the only method allowed to test a static cache
+ public void testStaticCache() throws Exception
+ {
+ IntrospectionCache cache1 = new IntrospectionCache(true);
+ IntrospectionCache cache2 = new IntrospectionCache(false);
+ IntrospectionCache cache3 = new IntrospectionCache(true);
+ IntrospectionCache cache4 = new IntrospectionCache(false);
+
+ Introspection ispec1 = cache1.lookup(Bean1.class);
+
+ Introspection ispec2 = cache2.lookup(Bean1.class);
+ assertNotSame(ispec1, ispec2);
+
+ Introspection ispec3 = cache3.lookup(Bean1.class);
+ assertSame(ispec1, ispec3);
+
+ Introspection ispec4 = cache4.lookup(Bean1.class);
+ assertNotSame(ispec1, ispec4);
+ assertNotSame(ispec2, ispec4);
+ }
+}
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-10-10 18:19:40
|
Revision: 163
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=163&view=rev
Author: kdgregory
Date: 2009-10-10 18:19:28 +0000 (Sat, 10 Oct 2009)
Log Message:
-----------
Xml2BeanOptions: rename CONVERT_BLANK_AS_NULL to EMPTY_IS_NULL
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanOptions.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestXml2BeanConverter.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java 2009-10-10 18:15:38 UTC (rev 162)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanConverter.java 2009-10-10 18:19:28 UTC (rev 163)
@@ -225,7 +225,7 @@
{
String text = DomUtil.getText(elem);
if (StringUtils.isBlank(text)
- && _options.contains(Xml2BeanOptions.CONVERT_BLANK_AS_NULL))
+ && _options.contains(Xml2BeanOptions.EMPTY_IS_NULL))
text = null;
return text;
}
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-10-10 18:15:38 UTC (rev 162)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanOptions.java 2009-10-10 18:19:28 UTC (rev 163)
@@ -27,7 +27,7 @@
* 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,
+ EMPTY_IS_NULL,
/**
* Expect data (in particular, dates) to be formatted per XML Schema spec.
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestXml2BeanConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestXml2BeanConverter.java 2009-10-10 18:15:38 UTC (rev 162)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestXml2BeanConverter.java 2009-10-10 18:19:28 UTC (rev 163)
@@ -179,7 +179,7 @@
public void testConvertEmptyStringToNull() throws Exception
{
- Xml2BeanConverter driver = new Xml2BeanConverter(Xml2BeanOptions.CONVERT_BLANK_AS_NULL);
+ Xml2BeanConverter driver = new Xml2BeanConverter(Xml2BeanOptions.EMPTY_IS_NULL);
Element src = createTestData(text(" \n\t "));
assertNull(driver.convert(src, String.class));
@@ -189,7 +189,7 @@
public void testConvertEmptyStringToNullAndRequireXsiNull() throws Exception
{
Xml2BeanConverter driver = new Xml2BeanConverter(
- Xml2BeanOptions.CONVERT_BLANK_AS_NULL,
+ Xml2BeanOptions.EMPTY_IS_NULL,
Xml2BeanOptions.REQUIRE_XSI_NIL);
Element valid = createTestData(text(" \t "), xsiNil(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-10-10 18:15:49
|
Revision: 162
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=162&view=rev
Author: kdgregory
Date: 2009-10-10 18:15:38 +0000 (Sat, 10 Oct 2009)
Log Message:
-----------
Bean2XmlOptions: add NULL_AS_EMPTY, rename XSI_NIL to NULL_AS_XSI_NIL
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java 2009-10-05 21:57:23 UTC (rev 161)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlAppenders.java 2009-10-10 18:15:38 UTC (rev 162)
@@ -88,7 +88,9 @@
protected boolean shouldSkip(Object value)
{
- return (value == null) && !_options.contains(Bean2XmlOptions.XSI_NIL);
+ return (value == null)
+ && !_options.contains(Bean2XmlOptions.NULL_AS_EMPTY)
+ && !_options.contains(Bean2XmlOptions.NULL_AS_XSI_NIL);
}
protected void setType(Element elem, String type)
@@ -101,7 +103,9 @@
{
if (value != null)
DomUtil.setText(elem, value);
- else if (isOptionSet(Bean2XmlOptions.XSI_NIL))
+ else if (isOptionSet(Bean2XmlOptions.NULL_AS_EMPTY))
+ DomUtil.setText(elem, "");
+ else if (isOptionSet(Bean2XmlOptions.NULL_AS_XSI_NIL))
DomUtilToo.setXsiNil(elem, true);
}
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-10-05 21:57:23 UTC (rev 161)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-10-10 18:15:38 UTC (rev 162)
@@ -137,7 +137,7 @@
*/
private void doXsiNamespaceHack(Element root)
{
- if (_options.contains(Bean2XmlOptions.XSI_NIL)
+ if (_options.contains(Bean2XmlOptions.NULL_AS_XSI_NIL)
&& !_options.contains(Bean2XmlOptions.XSI_TYPE))
{
DomUtilToo.setXsiNil(root, false);
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java 2009-10-05 21:57:23 UTC (rev 161)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlOptions.java 2009-10-10 18:15:38 UTC (rev 162)
@@ -28,8 +28,24 @@
*/
INTROSPECT_MAPS,
+ /**
+ * If the value is <code>null</code>, add an element containing a single
+ * text child holding an empty string.
+ * <p>
+ * This may make life easier when processing data from a certain DBMS
+ * designed in the mid-1980s when disk space was too expensive to create
+ * a separate null flag for VARCHAR fields. However, be aware that it
+ * may cause parsing problems.
+ */
+ NULL_AS_EMPTY,
/**
+ * If the value is <code>null</code>, add an element without content, with
+ * the attribute <code>xsi:nil</code> set to "true".
+ */
+ NULL_AS_XSI_NIL,
+
+ /**
* Will create sequences (arrays, lists, and sets) as repeated elements
* rather than a parent-children construct. This option is invalid when
* converting an array as the top-level object, as it would cause the
@@ -64,13 +80,6 @@
XSD_FORMAT,
/**
- * Add null values into the tree, as an element without content, with the
- * attribute <code>xsi:nil</code> set to "true". If not present, null
- * values are ignored, and not added to DOM tree.
- */
- XSI_NIL,
-
- /**
* Will add an <code>xsi:type</code> attribute to each element. For values
* covered by the XML Schema simple types, this attribute's value will be
* "<code>xsd:TYPE</code>", where TYPE is the XSD type name. For complex
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java 2009-10-05 21:57:23 UTC (rev 161)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlAppenders.java 2009-10-10 18:15:38 UTC (rev 162)
@@ -98,7 +98,7 @@
{
Element root = DomUtil.newDocument("root");
- Appender appender = new BasicAppender(root, useOptions(Bean2XmlOptions.XSI_NIL));
+ Appender appender = new BasicAppender(root, useOptions(Bean2XmlOptions.NULL_AS_XSI_NIL));
Element child0 = appender.appendValue("foo", "bar", "baz");
Element child1 = appender.appendValue("argle", "bargle", null);
@@ -180,7 +180,7 @@
{
Element root = DomUtil.newDocument("root");
- Appender appender = new IndexedAppender(root, useOptions(Bean2XmlOptions.XSI_NIL));
+ Appender appender = new IndexedAppender(root, useOptions(Bean2XmlOptions.NULL_AS_XSI_NIL));
Element child0 = appender.appendValue("foo", "bar", "baz");
Element child1 = appender.appendValue("argle", "bargle", "wargle");
Element child2 = appender.appendValue("bing", "bang", null);
@@ -251,7 +251,7 @@
{
Element root = DomUtil.newDocument("root");
- Appender appender = new MapAppender(root, useOptions(Bean2XmlOptions.XSI_NIL));
+ Appender appender = new MapAppender(root, useOptions(Bean2XmlOptions.NULL_AS_XSI_NIL));
Element child0 = appender.appendValue("foo", "bar", "baz");
Element child1 = appender.appendValue("argle", "bargle", "wargle");
Element child2 = appender.appendValue("bing", "bang", null);
@@ -346,7 +346,7 @@
{
Element root = DomUtil.newDocument("root");
- Appender appender = new DirectAppender(root, useOptions(Bean2XmlOptions.XSI_NIL));
+ Appender appender = new DirectAppender(root, useOptions(Bean2XmlOptions.NULL_AS_XSI_NIL));
Element child = appender.appendValue("foo", "bar", null);
assertSame(root, child);
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java 2009-10-05 21:57:23 UTC (rev 161)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBean2XmlConverter.java 2009-10-10 18:15:38 UTC (rev 162)
@@ -23,6 +23,9 @@
import java.util.TreeSet;
import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
import net.sf.practicalxml.DomUtil;
import net.sf.practicalxml.OutputUtil;
@@ -96,9 +99,25 @@
}
+ public void testConvertNullAsEmpty() throws Exception
+ {
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.NULL_AS_EMPTY);
+
+ Element root = driver.convert(null, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ NodeList children = root.getChildNodes();
+ assertEquals(1, children.getLength());
+
+ Node child = children.item(0);
+ assertTrue(child instanceof Text);
+ assertEquals("", child.getNodeValue());
+ }
+
+
public void testConvertNullWithNilOption() throws Exception
{
- Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.XSI_NIL);
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.NULL_AS_XSI_NIL);
Element root = driver.convert(null, "test");
// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
@@ -592,7 +611,7 @@
public void testConvertSimpleBeanXsiNil() throws Exception
{
- Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.XSI_NIL);
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.NULL_AS_XSI_NIL);
SimpleBean bean = new SimpleBean(null, 123, null, true);
Element root = driver.convert(bean, "test");
@@ -608,7 +627,7 @@
public void testConvertSimpleBeanXsiNilAndXsiType() throws Exception
{
- Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.XSI_NIL, Bean2XmlOptions.XSI_TYPE);
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.NULL_AS_XSI_NIL, Bean2XmlOptions.XSI_TYPE);
SimpleBean bean = new SimpleBean(null, 123, null, true);
Element root = driver.convert(bean, "test");
@@ -622,6 +641,22 @@
}
+ public void testConvertSimpleBeanNullAsEmpty() throws Exception
+ {
+ Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.NULL_AS_EMPTY);
+
+ SimpleBean bean = new SimpleBean(null, 123, null, true);
+ Element root = driver.convert(bean, "test");
+// System.out.println(OutputUtil.compactString(root.getOwnerDocument()));
+
+ assertChildCount(root, 4);
+ assertSingleChild(root, "sval", "", "", false);
+ assertSingleChild(root, "ival", "", "123", false);
+ assertSingleChild(root, "dval", "", "", false);
+ assertSingleChild(root, "bval", "", "true", false);
+ }
+
+
public void testConvertBeanArrayWithXsiType() throws Exception
{
Bean2XmlConverter driver = new Bean2XmlConverter(Bean2XmlOptions.XSI_TYPE);
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-10-05 21:57:23 UTC (rev 161)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/bean/TestBeanConverter.java 2009-10-10 18:15:38 UTC (rev 162)
@@ -135,7 +135,7 @@
public void testConvertNullUseAndRequireXsiNil() throws Exception
{
Document dom = BeanConverter.convertToXml(
- null, "test", Bean2XmlOptions.XSI_NIL);
+ null, "test", Bean2XmlOptions.NULL_AS_XSI_NIL);
// System.out.println(OutputUtil.compactString(dom));
Object result = BeanConverter.convertToJava(
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-10-05 21:57:34
|
Revision: 161
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=161&view=rev
Author: kdgregory
Date: 2009-10-05 21:57:23 +0000 (Mon, 05 Oct 2009)
Log Message:
-----------
fix FindBugs warning
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-09-24 19:13:30 UTC (rev 160)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Bean2XmlConverter.java 2009-10-05 21:57:23 UTC (rev 161)
@@ -259,7 +259,7 @@
}
if (value == null)
- tryToConvertAsPrimitiveOrNull(value, type, name, appender);
+ tryToConvertAsPrimitiveOrNull(null, type, name, appender);
else
convert(value, name, appender);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|