[Practicalxml-commits] SF.net SVN: practicalxml:[109] branches/dev-1.1/src
Brought to you by:
kdgregory
|
From: Auto-Generated S. C. M. <pra...@li...> - 2009-08-17 17:13:45
|
Revision: 109
http://practicalxml.svn.sourceforge.net/practicalxml/?rev=109&view=rev
Author: kdgregory
Date: 2009-08-17 17:13:36 +0000 (Mon, 17 Aug 2009)
Log Message:
-----------
implement XML->Bean conversions
Modified Paths:
--------------
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/ConversionHelper.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/xml2bean/Xml2BeanDriver.java
branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/xml2bean/Xml2BeanOptions.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractBeanConverterTestCase.java
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestConversionHelper.java
Added Paths:
-----------
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanDriver.java
Removed Paths:
-------------
branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanHandler.java
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/ConversionHelper.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/ConversionHelper.java 2009-08-15 18:57:35 UTC (rev 108)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/ConversionHelper.java 2009-08-17 17:13:36 UTC (rev 109)
@@ -32,6 +32,21 @@
*/
public class ConversionHelper
{
+ private static Map<String,Class<?>> XSD_TYPE_TO_JAVA_CLASS
+ = new HashMap<String,Class<?>>();
+ static
+ {
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:string", String.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:boolean", Boolean.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:byte", Byte.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:short", Short.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:int", Integer.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:long", Long.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:decimal", BigDecimal.class);
+ XSD_TYPE_TO_JAVA_CLASS.put("xsd:dateTime", Date.class);
+ }
+
+
// this is not static because the helpers are inner classes
private Map<Class<?>,ConversionHandler<?>> _helpers
= new HashMap<Class<?>,ConversionHandler<?>>();
@@ -48,6 +63,14 @@
_helpers.put(BigInteger.class, new BigIntegerConversionHandler());
_helpers.put(BigDecimal.class, new BigDecimalConversionHandler());
_helpers.put(Date.class, new DateConversionHandler());
+
+ _helpers.put(Boolean.TYPE, new BooleanConversionHandler());
+ _helpers.put(Byte.TYPE, new ByteConversionHandler());
+ _helpers.put(Short.TYPE, new ShortConversionHandler());
+ _helpers.put(Integer.TYPE, new IntegerConversionHandler());
+ _helpers.put(Long.TYPE, new LongConversionHandler());
+ _helpers.put(Float.TYPE, new FloatConversionHandler());
+ _helpers.put(Double.TYPE, new DoubleConversionHandler());
}
private boolean _useXsdFormatting;
@@ -85,6 +108,16 @@
ConversionHandler<?> helper = _helpers.get(klass);
return (helper == null) ? null : helper.getXsiType();
}
+
+
+ /**
+ * Returns the Java type that best matches the given Schema type name,
+ * <code>null</code> if we do not have an appropriate mapping.
+ */
+ public Class<?> getJavaType(String xsdTypename)
+ {
+ return XSD_TYPE_TO_JAVA_CLASS.get(xsdTypename);
+ }
/**
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/xml2bean/Xml2BeanDriver.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/xml2bean/Xml2BeanDriver.java 2009-08-15 18:57:35 UTC (rev 108)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/xml2bean/Xml2BeanDriver.java 2009-08-17 17:13:36 UTC (rev 109)
@@ -14,22 +14,434 @@
package net.sf.practicalxml.converter.xml2bean;
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import javax.xml.XMLConstants;
+
+import net.sf.practicalxml.DomUtil;
+import net.sf.practicalxml.converter.ConversionException;
+import net.sf.practicalxml.converter.ConversionHelper;
+import net.sf.practicalxml.internal.StringUtils;
+
import org.w3c.dom.Element;
+import org.w3c.dom.Node;
/**
- * Driver class for converting an XML DOM into a Java bean, using a {@link
- * Xml2BeanHandler} to manage data conversion.
+ * Driver class for converting an XML DOM into a Java bean. Normal usage is
+ * to create a single instance of this class with desired options, then use
+ * it for multiple conversions. This class is thread-safe.
+ * <p>
+ * This class assumes that the source XML will be in the form produced by
+ * {@link Bean2XmlDriver}: each element either contains child elements, or
+ * a text node containing the element's value. However, conversion is
+ * driven by the parameters passed to {@link #convert}, not by the content
+ * of the XML document; this can lead to some unexpected behavior:
+ * <ul>
+ * <li> Bean classes are introspected, and recursively processed base on
+ * the property descriptors. If the bean has multiple setter methods
+ * for a property, the method selected is arbitrarily chosen by the
+ * JavaBeans introspector. You can pass an option that looks for a
+ * setters using <code>String</code>, but this is not recommended
+ * from a performance perspective.
+ * <li> JDK collection types do not carry type information, so the only
+ * way to properly convert them is using an <code>xsi:type</code>
+ * attribute on the child elements. If this attribute is missing
+ * or cannot be interpreted, the element will be processed as if
+ * it is a <code>String</code>.
+ * <li> The converter will to pick an appropriate implementation class
+ * if given one of the JDK collections interfaces: <code>
+ * ArrayList</code> for <code>List</code> or <code>Collection</code>,
+ * <code>TreeSet</code> for <code>SortedSet</code>, <code>HashSet</code>
+ * for any other <code>Set</code>, and likewise <code>TreeMap</code> and
+ * <code>HashMap</code> for <code>SortedMap</code> and <code>Map</code>.
+ * </ul>
*/
public class Xml2BeanDriver
{
+ private EnumSet<Xml2BeanOptions> _options;
+ private ConversionHelper _helper;
+ private Map<Class<?>,Map<String,Method>> _introspectedClasses;
+
+
+ public Xml2BeanDriver(Xml2BeanOptions... options)
+ {
+ _options = EnumSet.noneOf(Xml2BeanOptions.class);
+ for (Xml2BeanOptions option : options)
+ _options.add(option);
+
+ _helper = new ConversionHelper(_options.contains(Xml2BeanOptions.EXPECT_XSD_FORMAT));
+ _introspectedClasses = new HashMap<Class<?>,Map<String,Method>>();
+ }
+
+
+//----------------------------------------------------------------------------
+// Public Methods
+//----------------------------------------------------------------------------
+
/**
- * Fills a bean-style object from an XML element. For each child of the
- * passed element, tries to find a property with the same name, invokes
- * the appropriate conversion handler method, and sets the property from
- * the result.
+ * Attempts to convert the passed DOM subtree into an object of the
+ * specified class.
*/
- public void dispatch(Element elem, Object bean)
+ public <T> T convert(Element elem, Class<T> klass)
{
+ return klass.cast(convertWithoutCast(elem, klass));
}
+
+
+//----------------------------------------------------------------------------
+// Internal Conversion Methods
+//----------------------------------------------------------------------------
+
+
+
+ /**
+ * Attempts to convert the passed DOM subtree into an object of the
+ * specified class. Note that this version does not use generics,
+ * and does not try to cast the result, whereas the public version
+ * does. Internally, we want to treat <code>Integer.TYPE</code> the
+ * same as <code>Integer.class</code>, and the cast prevents that.
+ */
+ public Object convertWithoutCast(Element elem, Class<?> klass)
+ {
+ validateXsiType(elem, klass);
+ if (isAllowableNull(elem))
+ return null;
+
+ Object obj = tryConvertAsPrimitive(elem, klass);
+ if (obj == null)
+ obj = tryConvertAsArray(elem, klass);
+ if (obj == null)
+ obj = tryConvertAsSimpleCollection(elem, klass);
+ if (obj == null)
+ obj = tryConvertAsMap(elem, klass);
+ if (obj == null)
+ obj = tryConvertAsBean(elem, klass);
+ return obj;
+ }
+
+
+ private boolean isAllowableNull(Element elem)
+ {
+ String text = getText(elem);
+ if ((text != null) || hasElementChildren(elem))
+ return false;
+
+ if (_options.contains(Xml2BeanOptions.REQUIRE_XSI_NIL))
+ {
+ String attr = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil");
+ if (!attr.equals("true"))
+ throw new ConversionException(
+ "missing xsi:nil: " + DomUtil.getAbsolutePath(elem));
+ }
+
+ return true;
+ }
+
+
+ private Object tryConvertAsPrimitive(Element elem, Class<?> klass)
+ {
+ if (_helper.getXsdType(klass) == null)
+ return null;
+
+ if (hasElementChildren(elem))
+ throw new ConversionException(
+ "expecting primitive; has children: " + DomUtil.getAbsolutePath(elem));
+
+ return _helper.parse(getText(elem), klass);
+ }
+
+
+ private Object tryConvertAsArray(Element elem, Class<?> klass)
+ {
+ Class<?> childKlass = klass.getComponentType();
+ if (childKlass == null)
+ return null;
+
+ List<Element> children = DomUtil.getChildren(elem);
+ Object result = Array.newInstance(childKlass, children.size());
+ int idx = 0;
+ for (Element child : children)
+ {
+ Array.set(result, idx++, convertWithoutCast(child, childKlass));
+ }
+ return result;
+ }
+
+
+ private Object tryConvertAsSimpleCollection(Element elem, Class<?> klass)
+ {
+ Collection<Object> result = instantiateCollection(klass);
+ if (result == null)
+ return null;
+
+ List<Element> children = DomUtil.getChildren(elem);
+ for (Element child : children)
+ {
+ Class<?> childClass = getClassFromXsiType(child);
+ if (childClass == null)
+ childClass = String.class;
+ result.add(convertWithoutCast(child, childClass));
+ }
+ return result;
+ }
+
+
+ private Object tryConvertAsMap(Element elem, Class<?> klass)
+ {
+ Map<Object,Object> result = instantiateMap(klass);
+ if (result == null)
+ return null;
+
+ List<Element> children = DomUtil.getChildren(elem);
+ for (Element child : children)
+ {
+ String key = child.getAttribute("key");
+ if (StringUtils.isEmpty(key))
+ key = DomUtil.getLocalName(child);
+ Class<?> childClass = getClassFromXsiType(child);
+ if (childClass == null)
+ childClass = String.class;
+ result.put(key, convertWithoutCast(child, childClass));
+ }
+ return result;
+ }
+
+
+ private Object tryConvertAsBean(Element elem, Class<?> klass)
+ {
+ Object bean = instantiateBean(elem, klass);
+
+ List<Element> children = DomUtil.getChildren(elem);
+ for (Element child : children)
+ {
+ Method setter = getSetterMethod(klass, child);
+ if (setter == null)
+ continue;
+
+ Class<?> childClass = setter.getParameterTypes()[0];
+ Object childValue = convertWithoutCast(child, childClass);
+ invokeSetter(elem, bean, setter, childValue);
+ }
+ return bean;
+ }
+
+
+//----------------------------------------------------------------------------
+// Other Internals
+//----------------------------------------------------------------------------
+
+ /**
+ * Returns the text content of an element, applying appropriate options.
+ */
+ private String getText(Element elem)
+ {
+ String text = DomUtil.getText(elem);
+ if (StringUtils.isBlank(text)
+ && _options.contains(Xml2BeanOptions.CONVERT_BLANK_AS_NULL))
+ text = null;
+ return text;
+ }
+
+
+ /**
+ * Returns the <code>xsi:type</code> attribute value, <code>null</code> if
+ * it's not set.
+ */
+ private String getXsiType(Element elem)
+ {
+ String xsiType = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
+ return StringUtils.isEmpty(xsiType)
+ ? null
+ : xsiType;
+ }
+
+
+ /**
+ * Examines an element's <code>xsi:type</code> attribute, if any, and
+ * returns the Java class corresponding to it. Used when converting
+ * collection types, which don't have type information that can be
+ * introspected, and also to validate non-XSD types.
+ */
+ private Class<?> getClassFromXsiType(Element elem)
+ {
+ String xsiType = getXsiType(elem);
+ if (xsiType == null)
+ return null;
+
+ if (xsiType.startsWith("java:"))
+ {
+ String javaType = xsiType.substring(5);
+ try
+ {
+ return Class.forName(javaType);
+ }
+ catch (ClassNotFoundException ee)
+ {
+ throw new ConversionException(
+ "invalid Java type specification (" + javaType + "): "
+ + DomUtil.getAbsolutePath(elem),
+ ee);
+ }
+ }
+ return _helper.getJavaType(xsiType);
+ }
+
+
+ private void validateXsiType(Element elem, Class<?> klass)
+ {
+ if (!_options.contains(Xml2BeanOptions.REQUIRE_XSI_TYPE))
+ return;
+
+ String xsiType = elem.getAttributeNS(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type");
+ if (StringUtils.isEmpty(xsiType))
+ throw new ConversionException(
+ "missing xsi:type: " + DomUtil.getAbsolutePath(elem));
+
+ if (xsiType.equals(_helper.getXsdType(klass)))
+ return;
+
+ Class<?> xsiKlass = getClassFromXsiType(elem);
+ if (klass.isAssignableFrom(xsiKlass))
+ return;
+
+ throw new ConversionException(
+ "invalid xsi:type (\"" + xsiType + "\" for " + klass.getName() + "): "
+ + DomUtil.getAbsolutePath(elem));
+ }
+
+
+ private boolean hasElementChildren(Element elem)
+ {
+ Node child = elem.getFirstChild();
+ while (child != null)
+ {
+ if (child instanceof Element)
+ return true;
+ child = child.getNextSibling();
+ }
+ return false;
+ }
+
+
+ private Method getSetterMethod(Class<?> beanKlass, Element child)
+ {
+ Map<String,Method> methodMap = _introspectedClasses.get(beanKlass);
+ if (methodMap == null)
+ methodMap = introspect(beanKlass);
+
+ Method setter = methodMap.get(DomUtil.getLocalName(child));
+ if ((setter == null) && !_options.contains(Xml2BeanOptions.IGNORE_MISSING_PROPERTIES))
+ {
+ throw new ConversionException(
+ "can't find property setter in " + beanKlass.getName() + ": "
+ + DomUtil.getAbsolutePath(child));
+ }
+
+ return setter;
+ }
+
+
+ private Map<String,Method> introspect(Class<?> klass)
+ {
+ Map<String,Method> methodMap = new HashMap<String,Method>();
+ try
+ {
+ BeanInfo info = Introspector.getBeanInfo(klass, Object.class);
+ for (PropertyDescriptor propDesc : info.getPropertyDescriptors())
+ {
+ Method setter = propDesc.getWriteMethod();
+ if (setter != null)
+ methodMap.put(propDesc.getName(), setter);
+ }
+ }
+ catch (IntrospectionException e)
+ {
+ throw new ConversionException("unable to introspect", e);
+ }
+
+ _introspectedClasses.put(klass, methodMap);
+ return methodMap;
+ }
+
+
+ /**
+ * Attempts to create a <code>Collection</code> instance appropriate for
+ * the passed class, returns <code>null</code> if unable.
+ */
+ private Collection<Object> instantiateCollection(Class<?> klass)
+ {
+ if (SortedSet.class.isAssignableFrom(klass))
+ return new TreeSet<Object>();
+ else if (Set.class.isAssignableFrom(klass))
+ return new HashSet<Object>();
+ else if (List.class.isAssignableFrom(klass))
+ return new ArrayList<Object>();
+ else if (Collection.class.isAssignableFrom(klass))
+ return new ArrayList<Object>();
+ else
+ return null;
+ }
+
+
+ /**
+ * Attempts to create a <code>Map</code> instance appropriate for the
+ * passed class, returns <code>null</code> if unable.
+ */
+ private Map<Object,Object> instantiateMap(Class<?> klass)
+ {
+ if (SortedMap.class.isAssignableFrom(klass))
+ return new TreeMap<Object,Object>();
+ else if (Map.class.isAssignableFrom(klass))
+ return new HashMap<Object,Object>();
+ else
+ return null;
+ }
+
+
+ private Object instantiateBean(Element elem, Class<?> klass)
+ {
+ try
+ {
+ return klass.newInstance();
+ }
+ catch (Exception ee)
+ {
+ throw new ConversionException(
+ "unable to instantiate bean: " + DomUtil.getAbsolutePath(elem),
+ ee);
+ }
+ }
+
+
+ private void invokeSetter(Element elem, Object bean, Method setter, Object value)
+ {
+ try
+ {
+ setter.invoke(bean, value);
+ }
+ catch (Exception ee)
+ {
+ throw new ConversionException(
+ "unable to set property: " + DomUtil.getAbsolutePath(elem),
+ ee);
+ }
+ }
}
Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/xml2bean/Xml2BeanOptions.java
===================================================================
--- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/xml2bean/Xml2BeanOptions.java 2009-08-15 18:57:35 UTC (rev 108)
+++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/xml2bean/Xml2BeanOptions.java 2009-08-17 17:13:36 UTC (rev 109)
@@ -30,25 +30,22 @@
/**
- * If present, the converter ignores elements that don't correspond to
- * settable properties of the bean.
+ * Expect data (in particular, dates) to be formatted per XML Schema spec.
*/
- IGNORE_MISSING_PROPERTIES,
+ EXPECT_XSD_FORMAT,
/**
- * If present, the converter will ignore any objects that cannot be
- * converted (many of the JDK-provided classes fall into this category,
- * because they're not bean-structured).
+ * If present, the converter ignores elements that don't correspond to
+ * settable properties of the bean.
*/
- IGNORE_UNCONVERTIBLE_OBJECTS,
+ IGNORE_MISSING_PROPERTIES,
/**
- * If present, the converter will use a setter method taking a String, in
- * preference to any other type. Default behavior is to pick the method
- * with the most restrictive type (and considering numeric types as more
- * restrictive than <code>String</code>).
+ * If present, the converter will look for a setter method taking a
+ * <code>String</code>, in preference to a non-string method returned
+ * from the bean introspector.
*/
PREFER_STRING_SETTER,
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractBeanConverterTestCase.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractBeanConverterTestCase.java 2009-08-15 18:57:35 UTC (rev 108)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/AbstractBeanConverterTestCase.java 2009-08-17 17:13:36 UTC (rev 109)
@@ -81,7 +81,7 @@
new PrimitiveValue(Double.valueOf(1234567890.5), "xsd:decimal", "1234567890.5"),
new PrimitiveValue(new BigInteger("123456789012345"), "xsd:decimal", "123456789012345"),
new PrimitiveValue(new BigDecimal("123456789012345.123456789012345"), "xsd:decimal", "123456789012345.123456789012345"),
- new PrimitiveValue(new Date(1247551703704L), "xsd:dateTime", "2009-07-14T06:08:23")
+ new PrimitiveValue(new Date(1247551703000L), "xsd:dateTime", "2009-07-14T06:08:23")
};
@@ -170,23 +170,23 @@
assertXsiType(message, elem, expectedType);
assertXsiNil(message, elem, isNil);
}
-
+
protected void assertNameTypeValue(
- Element elem,
+ Element elem,
String expectedName, String expectedType, String expectedValue)
{
assertNameTypeValue("", elem, expectedName, expectedType, expectedValue);
}
-
-
+
+
protected void assertNameTypeValue(
- String message, Element elem,
+ String message, Element elem,
String expectedName, String expectedType, String expectedValue)
{
if (message.length() > 0)
message += " ";
-
+
assertName(message + "name", elem, expectedName);
assertXsiType(message + "xsi:type", elem, expectedType);
assertValue(message + "value", elem, expectedValue);
Modified: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestConversionHelper.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestConversionHelper.java 2009-08-15 18:57:35 UTC (rev 108)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestConversionHelper.java 2009-08-17 17:13:36 UTC (rev 109)
@@ -54,6 +54,20 @@
// Test Cases
//----------------------------------------------------------------------------
+ public void testClassToXsdType() throws Exception
+ {
+ ConversionHelper helper = new ConversionHelper();
+
+ assertEquals("xsd:string", helper.getXsdType(String.class));
+ assertEquals("xsd:string", helper.getXsdType(Character.class));
+ assertEquals(String.class, helper.getJavaType("xsd:string"));
+
+ assertEquals("xsd:boolean", helper.getXsdType(Boolean.class));
+ assertEquals(Boolean.class, helper.getJavaType("xsd:boolean"));
+
+ }
+
+
public void testUnknownClass() throws Exception
{
ConversionHelper helper = new ConversionHelper();
Added: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanDriver.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanDriver.java (rev 0)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanDriver.java 2009-08-17 17:13:36 UTC (rev 109)
@@ -0,0 +1,708 @@
+// Copyright 2008-2009 severally by the contributors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package net.sf.practicalxml.converter;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+
+import javax.xml.XMLConstants;
+import org.w3c.dom.Element;
+
+import net.sf.practicalxml.converter.xml2bean.Xml2BeanDriver;
+import net.sf.practicalxml.converter.xml2bean.Xml2BeanOptions;
+
+
+import static net.sf.practicalxml.builder.XmlBuilder.*;
+
+
+public class TestXml2BeanDriver
+extends AbstractBeanConverterTestCase
+{
+ public TestXml2BeanDriver(String name)
+ {
+ super(name);
+ }
+
+
+//----------------------------------------------------------------------------
+// Support Code
+//----------------------------------------------------------------------------
+
+ private static Element createTestData(net.sf.practicalxml.builder.Node... childNodes)
+ {
+ return element("root", childNodes)
+ .toDOM().getDocumentElement();
+ }
+
+
+ private static net.sf.practicalxml.builder.Node xsiType(String typeName)
+ {
+ return attribute(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI,
+ "type",
+ typeName);
+ }
+
+
+ private static net.sf.practicalxml.builder.Node xsiNil(boolean isNil)
+ {
+ return attribute(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI,
+ "nil",
+ isNil ? "true" : "false");
+ }
+
+
+ private static void assertConversionError(
+ String message, Xml2BeanDriver driver, Element elem, Class<?> klass)
+ {
+ try
+ {
+ driver.convert(elem, klass);
+ fail(message);
+ }
+ catch (ConversionException ee)
+ { /* success */ }
+ }
+
+
+//----------------------------------------------------------------------------
+// Test Classes
+//----------------------------------------------------------------------------
+
+ public static class ReadOnlyBean
+ {
+ private String _sval;
+ public String getSval() { return _sval; }
+ }
+
+
+//----------------------------------------------------------------------------
+// Test Cases
+//----------------------------------------------------------------------------
+
+ public void testConvertPrimitivesDefault() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ for (PrimitiveValue value : PRIMITIVE_VALUES)
+ {
+ Element src = createTestData(text(value.getDefaultText()));
+ Object dst = driver.convert(src, value.getKlass());
+ assertEquals(value.getKlass().getName(), value.getValue(), dst);
+ }
+ }
+
+
+ public void testConvertPrimitivesXsdFormat() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver(Xml2BeanOptions.EXPECT_XSD_FORMAT);
+
+ for (PrimitiveValue value : PRIMITIVE_VALUES)
+ {
+ Element src = createTestData(text(value.getXsdText()));
+ Object dst = driver.convert(src, value.getKlass());
+ assertEquals(value.getKlass().getName(), value.getValue(), dst);
+ }
+ }
+
+
+ public void testConvertPrimitivesRequireXsiType() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver(Xml2BeanOptions.REQUIRE_XSI_TYPE);
+
+ Element valid = createTestData(text("foo"), xsiType("xsd:string"));
+ Object dst = driver.convert(valid, String.class);
+ assertEquals("foo", dst);
+
+ Element invalid = createTestData(text("foo"));
+ assertConversionError("converted element missing xsi:type",
+ driver, invalid, String.class);
+ }
+
+
+ public void testConvertPrimitiveWithWrongXsiType() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver(Xml2BeanOptions.REQUIRE_XSI_TYPE);
+
+ Element invalid = createTestData(text("foo"), xsiType("xsd:int"));
+ assertConversionError("converted element with incorrect xsi:type",
+ driver, invalid, String.class);
+ }
+
+
+ public void testConvertPrimitiveWithChildElement() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ Element invalid = createTestData(text("foo"), element("bar"));
+ assertConversionError("converted primitive with element content",
+ driver, invalid, String.class);
+ }
+
+
+ public void testConvertNullDefault() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ Element src = createTestData();
+ assertNull(driver.convert(src, String.class));
+ }
+
+
+ public void testConvertNullRequireXsiNull() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver(Xml2BeanOptions.REQUIRE_XSI_NIL);
+
+ Element valid = createTestData(xsiNil(true));
+ assertNull(driver.convert(valid, String.class));
+
+ Element invalid = createTestData();
+ assertConversionError("able to convert null data with REQUIRE_XSI_NIL set",
+ driver, invalid, String.class);
+ }
+
+
+ public void testConvertEmptyStringDefault() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ String str = " \n \t ";
+ Element src = createTestData(text(str));
+ Object dst = driver.convert(src, String.class);
+ assertEquals(str, dst);
+ }
+
+
+ public void testConvertEmptyStringToNull() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver(Xml2BeanOptions.CONVERT_BLANK_AS_NULL);
+
+ Element src = createTestData(text(" \n\t "));
+ assertNull(driver.convert(src, String.class));
+ }
+
+
+ public void testConvertEmptyStringToNullAndRequireXsiNull() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver(
+ Xml2BeanOptions.CONVERT_BLANK_AS_NULL,
+ Xml2BeanOptions.REQUIRE_XSI_NIL);
+
+ Element valid = createTestData(text(" \t "), xsiNil(true));
+ assertNull(driver.convert(valid, String.class));
+
+ Element invalid = createTestData(text(" \t "));
+ assertConversionError("able to convert blank data with CONVERT_BLANK_AS_NULL and REQUIRE_XSI_NIL set",
+ driver, invalid, String.class);
+ }
+
+
+ public void testConvertPrimitiveArray() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ // note that the child element names shouldn't matter ... doesn't
+ // have to be the "data" of Bean2Xml
+ Element data = createTestData(
+ element("foo", text("12")),
+ element("bar", text("78")),
+ element("baz", text("-17")));
+
+ int[] result = driver.convert(data, int[].class);
+ assertEquals(3, result.length);
+ assertEquals(12, result[0]);
+ assertEquals(78, result[1]);
+ assertEquals(-17, result[2]);
+ }
+
+
+ public void testConvertPrimitiveArrayRequireXsiType() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver(Xml2BeanOptions.REQUIRE_XSI_TYPE);
+
+ Element valid = createTestData(
+ xsiType("java:" + int[].class.getName()),
+ element("foo", text("12"), xsiType("xsd:int")));
+
+ int[] result = driver.convert(valid, int[].class);
+ assertEquals(1, result.length);
+ assertEquals(12, result[0]);
+
+ Element invalid = createTestData(
+ element("foo", text("12"), xsiType("xsd:int")));
+
+ assertConversionError("able to convert with REQUIRE_XSI_TYPE set",
+ driver, invalid, int[].class);
+ }
+
+
+ public void testConvertListAssumingString() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ // note that the child element names shouldn't matter ... doesn't
+ // have to be the "data" of Bean2Xml
+ Element data = createTestData(
+ element("a", text("foo")),
+ element("b", text("bar")),
+ element("b", text("baz")),
+ element("c", text("bar")));
+
+ List<?> result = driver.convert(data, List.class);
+ assertEquals(4, result.size());
+
+ Iterator<?> itx = result.iterator();
+ assertEquals("foo", itx.next());
+ assertEquals("bar", itx.next());
+ assertEquals("baz", itx.next());
+ assertEquals("bar", itx.next());
+ }
+
+
+ public void testConvertListWithXsiType() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ Element data = createTestData(
+ element("a", text("foo"), xsiType("xsd:string")),
+ element("b", text("123"), xsiType("xsd:int")),
+ element("b", text("123.0"), xsiType("xsd:decimal")),
+ element("c", text("456"), xsiType("xsd:string")));
+
+ List<?> result = driver.convert(data, List.class);
+ assertEquals(4, result.size());
+
+ Iterator<?> itx = result.iterator();
+ assertEquals("foo", itx.next());
+ assertEquals(Integer.valueOf(123), itx.next());
+ assertEquals(new BigDecimal("123.0"), itx.next());
+ assertEquals("456", itx.next());
+ }
+
+ public void testConvertListWithJavaType() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ Element data = createTestData(
+ element("a", text("1234"),
+ xsiType("java:java.math.BigInteger")));
+
+ List<?> result = driver.convert(data, List.class);
+ assertEquals(1, result.size());
+ assertEquals(new BigInteger("1234"), result.iterator().next());
+
+ }
+
+
+ public void testConvertListWithBogusJavaType() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ Element data = createTestData(
+ element("a", text("foo"), xsiType("java:foo")));
+
+ assertConversionError("converted unknown type",
+ driver, data, List.class);
+ }
+
+
+ public void testConvertSortedSetAssumingString() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ Element data = createTestData(
+ element("a", text("foo")),
+ element("b", text("bar")),
+ element("b", text("baz")),
+ element("c", text("bar")));
+
+ SortedSet<?> result = driver.convert(data, SortedSet.class);
+ assertEquals(3, result.size());
+
+ Iterator<?> itx = result.iterator();
+ assertEquals("bar", itx.next());
+ assertEquals("baz", itx.next());
+ assertEquals("foo", itx.next());
+ }
+
+
+ public void testConvertSetAssumingString() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ Element data = createTestData(
+ element("a", text("foo")),
+ element("b", text("bar")),
+ element("b", text("baz")),
+ element("c", text("bar")));
+
+ Set<?> result = driver.convert(data, Set.class);
+ assertEquals(3, result.size());
+ assertTrue(result.contains("bar"));
+ assertTrue(result.contains("baz"));
+ assertTrue(result.contains("foo"));
+ }
+
+
+ public void testConvertCollectionAssumingString() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ Element data = createTestData(
+ element("a", text("foo")),
+ element("b", text("bar")),
+ element("b", text("baz")),
+ element("c", text("bar")));
+
+ Collection<?> result = driver.convert(data, Collection.class);
+ assertEquals(4, result.size());
+
+ Iterator<?> itx = result.iterator();
+ assertEquals("foo", itx.next());
+ assertEquals("bar", itx.next());
+ assertEquals("baz", itx.next());
+ assertEquals("bar", itx.next());
+ }
+
+
+ // this handles the case where we're processing a bean that uses interfaces
+ // but the source document has a concrete type
+ public void testConvertCollectionRequireXsiTypeWithConcreteType() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver(Xml2BeanOptions.REQUIRE_XSI_TYPE);
+
+ Element data = createTestData(
+ xsiType("java:java.util.ArrayList"),
+ element("a", text("foo"), xsiType("xsd:string")),
+ element("b", text("123"), xsiType("xsd:int")));
+
+ Collection<?> result = driver.convert(data, Collection.class);
+ assertEquals(2, result.size());
+
+ Iterator<?> itx = result.iterator();
+ assertEquals("foo", itx.next());
+ assertEquals(Integer.valueOf(123), itx.next());
+ }
+
+
+
+ public void testConvertMapDefaultKeyAssumingString() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ // we want distinct child names -- and overlapping ones -- because
+ // the converter should ignore them -- also note duplicate key
+ Element data = createTestData(
+ element("a", text("foo"), attribute("key", "argle")),
+ element("b", text("bar"), attribute("key", "bargle")),
+ element("b", text("baz"), attribute("key", "argle")),
+ element("c", text("bar"), attribute("key", "wargle")));
+
+ Map<?,?> result = driver.convert(data, Map.class);
+ assertEquals(3, result.size());
+ assertEquals("baz", result.get("argle"));
+ assertEquals("bar", result.get("bargle"));
+ assertEquals("bar", result.get("wargle"));
+ }
+
+
+ public void testConvertSortedMapDefaultKeyAssumingString() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ Element data = createTestData(
+ element("a", text("foo"), attribute("key", "argle")),
+ element("b", text("bar"), attribute("key", "bargle")),
+ element("c", text("arb"), attribute("key", "wargle")),
+ element("b", text("baz"), attribute("key", "argle")));
+
+ SortedMap<?,?> result = driver.convert(data, SortedMap.class);
+ assertEquals(3, result.size());
+
+ Iterator<?> itx = result.keySet().iterator();
+ assertEquals("argle", itx.next());
+ assertEquals("bargle", itx.next());
+ assertEquals("wargle", itx.next());
+
+ assertEquals("baz", result.get("argle"));
+ assertEquals("bar", result.get("bargle"));
+ assertEquals("arb", result.get("wargle"));
+ }
+
+
+ public void testConvertMapNameAsKeyAssumingString() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ // no attributes this time, but note the duplicate element name
+ Element data = createTestData(
+ element("a", text("foo")),
+ element("b", text("bar")),
+ element("b", text("baz")),
+ element("c", text("bar")));
+
+ Map<?,?> result = driver.convert(data, Map.class);
+ assertEquals(3, result.size());
+ assertEquals("foo", result.get("a"));
+ assertEquals("baz", result.get("b"));
+ assertEquals("bar", result.get("c"));
+ }
+
+
+ public void testConvertMapNameAsKeyUsingXsiType() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ // this time we have unique element names
+ Element data = createTestData(
+ element("a", text("foo"), xsiType("xsd:string")),
+ element("b", text("123"), xsiType("xsd:int")),
+ element("c", text("123.0"), xsiType("xsd:decimal")),
+ element("d", text("456"), xsiType("xsd:string")));
+
+ Map<?,?> result = driver.convert(data, Map.class);
+ assertEquals(4, result.size());
+ assertEquals("foo", result.get("a"));
+ assertEquals(Integer.valueOf(123), result.get("b"));
+ assertEquals(new BigDecimal("123.0"), result.get("c"));
+ assertEquals("456", result.get("d"));
+ }
+
+
+ public void testConvertMapNameAsKeyUsingJavaType() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ // this time we have unique element names
+ Element data = createTestData(
+ element("b", text("123"), xsiType("java:java.lang.Integer")));
+
+ Map<?,?> result = driver.convert(data, Map.class);
+ assertEquals(1, result.size());
+ assertEquals(Integer.valueOf(123), result.get("b"));
+ }
+
+
+ public void testSimpleBeanDefault() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ Element data = createTestData(
+ element("sval", text("foo")),
+ element("ival", text("123")),
+ element("dval", text("123.456")),
+ element("bval", text("true")));
+
+ SimpleBean result = driver.convert(data, SimpleBean.class);
+ assertEquals("foo", result.getSval());
+ assertEquals(123, result.getIval());
+ assertEquals(new BigDecimal("123.456"), result.getDval());
+ assertEquals(true, result.isBval());
+ }
+
+
+ public void testSimpleBeanWithMissingValues() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ Element data = createTestData(
+ element("sval", text("foo")),
+ element("ival", text("123")));
+
+ SimpleBean result = driver.convert(data, SimpleBean.class);
+ assertEquals("foo", result.getSval());
+ assertEquals(123, result.getIval());
+ assertNull(result.getDval());
+ assertEquals(false, result.isBval());
+ }
+
+
+ public void testSimpleBeanRequireXsiType() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver(Xml2BeanOptions.REQUIRE_XSI_TYPE);
+
+ Element valid = createTestData(
+ xsiType("java:" + SimpleBean.class.getName()),
+ element("sval", text("foo"), xsiType("xsd:string")),
+ element("ival", text("123"), xsiType("xsd:int")),
+ element("dval", text("123.456"),xsiType("xsd:decimal")),
+ element("bval", text("true"), xsiType("xsd:boolean")));
+
+ SimpleBean result = driver.convert(valid, SimpleBean.class);
+ assertEquals("foo", result.getSval());
+ assertEquals(123, result.getIval());
+ assertEquals(new BigDecimal("123.456"), result.getDval());
+ assertEquals(true, result.isBval());
+
+ Element invalid1 = createTestData(
+ element("sval", text("foo"), xsiType("xsd:string")),
+ element("ival", text("123"), xsiType("xsd:int")),
+ element("dval", text("123.456"),xsiType("xsd:decimal")),
+ element("bval", text("true"), xsiType("xsd:boolean")));
+ assertConversionError("didn't throw when missing xsi:type on top level",
+ driver, invalid1, SimpleBean.class);
+
+ Element invalid2 = createTestData(
+ xsiType("java:" + SimpleBean.class.getName()),
+ element("sval", text("foo")),
+ element("ival", text("123")),
+ element("dval", text("123.456")),
+ element("bval", text("true")));
+ assertConversionError("didn't throw when missing xsi:type on component level",
+ driver, invalid2, SimpleBean.class);
+ }
+
+
+ public void testSimpleBeanWithExtraValues() throws Exception
+ {
+ Element data = createTestData(
+ element("sval", text("foo")),
+ element("ival", text("123")),
+ element("zippy", text("pinhead")));
+
+ Xml2BeanDriver driver1 = new Xml2BeanDriver();
+
+ assertConversionError("converted bean when extra fields present in XML",
+ driver1, data, SimpleBean.class);
+
+ Xml2BeanDriver driver2 = new Xml2BeanDriver(Xml2BeanOptions.IGNORE_MISSING_PROPERTIES);
+
+ SimpleBean result = driver2.convert(data, SimpleBean.class);
+ assertEquals("foo", result.getSval());
+ assertEquals(123, result.getIval());
+ assertNull(result.getDval());
+ assertEquals(false, result.isBval());
+ }
+
+
+ public void testBeanArray() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ Element data = createTestData(
+ element("idx0",
+ element("sval", text("foo")),
+ element("ival", text("123")),
+ element("dval", text("123.456")),
+ element("bval", text("true"))),
+ element("idx1",
+ element("sval", text("bar")),
+ element("ival", text("456")),
+ element("dval", text("456.789")),
+ element("bval", text("false"))));
+
+ SimpleBean[] result = driver.convert(data, SimpleBean[].class);
+ assertEquals(2, result.length);
+
+ assertEquals("foo", result[0].getSval());
+ assertEquals(123, result[0].getIval());
+ assertEquals(new BigDecimal("123.456"), result[0].getDval());
+ assertEquals(true, result[0].isBval());
+
+ assertEquals("bar", result[1].getSval());
+ assertEquals(456, result[1].getIval());
+ assertEquals(new BigDecimal("456.789"), result[1].getDval());
+ assertEquals(false, result[1].isBval());
+ }
+
+
+ public void testConvertCompoundBean() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+
+ Element data = createTestData(
+ element("simple",
+ element("sval", text("foo")),
+ element("ival", text("123")),
+ element("dval", text("456")),
+ element("bval", text("true"))),
+ element("primArray",
+ element("idx1", text("1")),
+ element("idx2", text("2")),
+ element("idx3", text("3"))),
+ element("stringList",
+ element("idx1", text("foo")),
+ element("idx2", text("bar")),
+ element("idx3", text("baz"))));
+
+ CompoundBean result = driver.convert(data, CompoundBean.class);
+
+ assertEquals("foo", result.getSimple().getSval());
+ assertEquals(123, result.getSimple().getIval());
+ assertEquals(456, result.getSimple().getDval().intValue()); // laziness prevails
+ assertEquals(true, result.getSimple().isBval());
+ assertEquals(1, result.getPrimArray()[0]);
+ assertEquals(2, result.getPrimArray()[1]);
+ assertEquals(3, result.getPrimArray()[2]);
+ assertEquals("foo", result.getStringList().get(0));
+ assertEquals("bar", result.getStringList().get(1));
+ assertEquals("baz", result.getStringList().get(2));
+ }
+
+
+ public void testConvertCompoundBeanRequireXsiType() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver(Xml2BeanOptions.REQUIRE_XSI_TYPE);
+
+ Element data = createTestData(
+ xsiType("java:" + CompoundBean.class.getName()),
+ element("simple",
+ xsiType("java:" + SimpleBean.class.getName()),
+ element("sval", text("foo"), xsiType("xsd:string")),
+ element("ival", text("123"), xsiType("xsd:int")),
+ element("dval", text("456"), xsiType("xsd:decimal")),
+ element("bval", text("true"), xsiType("xsd:boolean"))),
+ element("primArray",
+ xsiType("java:" + int[].class.getName()),
+ element("idx1", text("1"), xsiType("xsd:int")),
+ element("idx2", text("2"), xsiType("xsd:int")),
+ element("idx3", text("3"), xsiType("xsd:int"))),
+ element("stringList",
+ xsiType("java:" + List.class.getName()),
+ element("idx1", text("foo"), xsiType("xsd:string")),
+ element("idx2", text("bar"), xsiType("xsd:string")),
+ element("idx3", text("baz"), xsiType("xsd:string"))));
+
+ CompoundBean result = driver.convert(data, CompoundBean.class);
+
+ assertEquals("foo", result.getSimple().getSval());
+ assertEquals(123, result.getSimple().getIval());
+ assertEquals(456, result.getSimple().getDval().intValue());
+ assertEquals(true, result.getSimple().isBval());
+ assertEquals(1, result.getPrimArray()[0]);
+ assertEquals(2, result.getPrimArray()[1]);
+ assertEquals(3, result.getPrimArray()[2]);
+ assertEquals("foo", result.getStringList().get(0));
+ assertEquals("bar", result.getStringList().get(1));
+ assertEquals("baz", result.getStringList().get(2));
+ }
+
+
+ public void testReadOnlyBean() throws Exception
+ {
+ Xml2BeanDriver driver = new Xml2BeanDriver();
+ Element data = createTestData(
+ element("sval", text("foo")));
+
+ assertConversionError("converted bean without setter",
+ driver, data, ReadOnlyBean.class);
+ }
+}
Property changes on: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanDriver.java
___________________________________________________________________
Added: svn:executable
+ *
Deleted: branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanHandler.java
===================================================================
--- branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanHandler.java 2009-08-15 18:57:35 UTC (rev 108)
+++ branches/dev-1.1/src/test/java/net/sf/practicalxml/converter/TestXml2BeanHandler.java 2009-08-17 17:13:36 UTC (rev 109)
@@ -1,409 +0,0 @@
-// Copyright 2008-2009 severally by the contributors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package net.sf.practicalxml.converter;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import javax.xml.XMLConstants;
-import org.w3c.dom.Element;
-
-import net.sf.practicalxml.DomUtil;
-import net.sf.practicalxml.builder.XmlBuilder;
-import net.sf.practicalxml.converter.xml2bean.Xml2BeanHandler;
-import net.sf.practicalxml.converter.xml2bean.Xml2BeanOptions;
-
-
-public class TestXml2BeanHandler
-extends AbstractBeanConverterTestCase
-{
- public TestXml2BeanHandler(String name)
- {
- super(name);
- }
-
-
-//----------------------------------------------------------------------------
-// Support Code
-//----------------------------------------------------------------------------
-
- /**
- * Builds a DOM tree with a single element, containing the specified
- * text as a child of the root. We don't care about the element's name;
- * it's the text that's important.
- */
- private Element createElement(String data)
- {
- Element elem = XmlBuilder.element("data").toDOM().getDocumentElement();
- if (data != null)
- DomUtil.appendText(elem, data);
- return elem;
- }
-
-
- /**
- * Reflectively executes the named method, and asserts that it throws
- * a conversion exception. This method exists to keep clutter out of
- * the test methods.
- */
- private void assertConversionFailure(
- Xml2BeanHandler handler, String methodName,
- Element elem, String failureText)
- throws Exception
- {
- Method method = handler.getClass().getMethod(methodName, Element.class);
- try
- {
- method.invoke(handler, elem);
- fail(methodName + ": " + failureText);
- }
- catch (InvocationTargetException ee)
- {
- if (ee.getCause().getClass() != ConversionException.class)
- fail(methodName + "threw unexpected exception: " + ee.getCause());
- // otherwise, we're successful
- }
- }
-
-
-//----------------------------------------------------------------------------
-// Test Cases
-//----------------------------------------------------------------------------
-
- public void testConvertString() throws Exception
- {
- Xml2BeanHandler handler = new Xml2BeanHandler();
-
- Element data1 = createElement("foo");
- assertEquals("foo", handler.convertString(data1));
-
- Element data2 = createElement("");
- assertEquals("", handler.convertString(data2));
- }
-
-
- public void testConvertCharacter() throws Exception
- {
- Xml2BeanHandler handler = new Xml2BeanHandler();
-
- Element data1 = createElement("A");
- assertEquals(Character.valueOf('A'), handler.convertCharacter(data1));
-
- Element data2 = createElement("\uFB01");
- assertEquals(Character.valueOf('\uFB01'), handler.convertCharacter(data2));
-
- Element data3 = createElement("");
- assertEquals(Character.valueOf('\0'), handler.convertCharacter(data3));
-
- Element data4 = createElement("ix");
- assertConversionFailure(handler, "convertCharacter", data4, "converted invalid value");
- }
-
-
- public void testConvertBoolean() throws Exception
- {
- Xml2BeanHandler handler = new Xml2BeanHandler();
-
- Element data1 = createElement("true");
- assertEquals(Boolean.TRUE, handler.convertBoolean(data1));
-
- Element data2 = createElement("1");
- assertEquals(Boolean.TRUE, handler.convertBoolean(data2));
-
- Element data3 = createElement("false");
- assertEquals(Boolean.FALSE, handler.convertBoolean(data3));
-
- Element data4 = createElement("0");
- assertEquals(Boolean.FALSE, handler.convertBoolean(data4));
-
- Element data5 = createElement("ix");
- assertConversionFailure(handler, "convertBoolean", data5, "converted invalid value");
-
- Element data6 = createElement("");
- assertConversionFailure(handler, "convertBoolean", data6, "converted empty value");
- }
-
-
- public void testConvertByte() throws Exception
- {
- Xml2BeanHandler handler = new Xml2BeanHandler();
-
- Element data1 = createElement("123");
- assertEquals(Byte.valueOf((byte)123), handler.convertByte(data1));
-
- Element data2 = createElement("-123");
- assertEquals(Byte.valueOf((byte)-123), handler.convertByte(data2));
-
- Element data3 = createElement("ix");
- assertConversionFailure(handler, "convertByte", data3, "converted invalid value");
-
- Element data4 = createElement("1234567");
- assertConversionFailure(handler, "convertByte", data4, "converted too-large value");
-
- Element data5 = createElement("");
- assertConversionFailure(handler, "convertByte", data5, "converted empty value");
- }
-
-
- public void testConvertShort() throws Exception
- {
- Xml2BeanHandler handler = new Xml2BeanHandler();
-
- Element data1 = createElement("12345");
- assertEquals(Short.valueOf((short)12345), handler.convertShort(data1));
-
- Element data2 = createElement("-12345");
- assertEquals(Short.valueOf((short)-12345), handler.convertShort(data2));
-
- Element data3 = createElement("ix");
- assertConversionFailure(handler, "convertShort", data3, "converted non-numeric value");
-
- Element data4 = createElement("1234567");
- assertConversionFailure(handler, "convertShort", data4, "converted too-large value");
-
- Element data5 = createElement("123.45");
- assertConversionFailure(handler, "convertShort", data5, "converted non-integer value");
-
- Element data6 = createElement("");
- assertConversionFailure(handler, "convertShort", data6, "converted empty value");
- }
-
-
- public void testConvertInteger() throws Exception
- {
- Xml2BeanHandler handler = new Xml2BeanHandler();
-
- Element data1 = createElement("123456789");
- assertEquals(Integer.valueOf(123456789), handler.convertInteger(data1));
-
- Element data2 = createElement("-123456789");
- assertEquals(Integer.valueOf(-123456789), handler.convertInteger(data2));
-
- Element data3 = createElement("ix");
- assertConversionFailure(handler, "convertInteger", data3, "converted non-numeric value");
-
- Element data4 = createElement("123456789012345");
- assertConversionFailure(handler, "convertInteger", data4, "converted too-large value");
-
- Element data5 = createElement("123.45");
- assertConversionFailure(handler, "convertInteger", data5, "converted non-integer value");
-
- Element data6 = createElement("");
- assertConversionFailure(handler, "convertInteger", data6, "converted empty value");
- }
-
-
- public void testConvertLong() throws Exception
- {
- Xml2BeanHandler handler = new Xml2BeanHandler();
-
- Element data1 = createElement("1234567890123456");
- assertE...
[truncated message content] |