[Practicalxml-commits] SF.net SVN: practicalxml:[111] branches/dev-1.1/src/main/java/net/sf/ practi
Brought to you by:
kdgregory
From: Auto-Generated S. C. M. <pra...@li...> - 2009-08-17 20:24:31
|
Revision: 111 http://practicalxml.svn.sourceforge.net/practicalxml/?rev=111&view=rev Author: kdgregory Date: 2009-08-17 20:24:04 +0000 (Mon, 17 Aug 2009) Log Message: ----------- update comments Modified Paths: -------------- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/BeanConverter.java branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanDriver.java branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/package.html Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/BeanConverter.java =================================================================== --- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/BeanConverter.java 2009-08-17 17:26:40 UTC (rev 110) +++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/BeanConverter.java 2009-08-17 20:24:04 UTC (rev 111) @@ -15,60 +15,162 @@ package net.sf.practicalxml.converter; import org.w3c.dom.Document; +import org.w3c.dom.Element; import net.sf.practicalxml.converter.bean.Bean2XmlDriver; import net.sf.practicalxml.converter.bean.Bean2XmlOptions; /** - * Converts Java objects (not just beans) to and from an XML representation. - * This was originally developed to support RESTful web services, without the - * class-generation hassle of JAXB. + * Converts Java objects (not just beans) to or from an XML representation. + * Originally developed to support simple web services, without the overhead + * (schema definitions and/or annotations) required by JAXB. * <p> - * The XML generated/consumed by this class obeys the following rules, with - * options controlled by {@link Bean2XmlOptions}: - * <ul> - * <li> All elements inherit their parent's namespace and namespace prefix. - * <li> Elements of sets are output using the element name "data". - * <li> Elements of lists and arrays are output using the element name "data", - * with an attribute "index" that contains the numeric index. - * <li> Elements of maps are by default output using the name "data", with an - * attribute "name" containing the actual map key. The output option - * <code>INTROSPECT_MAPS</code> will change this behavior, but will throw - * if the map keys are not valid XML element names. - * <li> Values are output using <code>toString()</code>, except as overridden - * by options. - * <li> Null values do not generate output, unless the <code>XSI_NIL</code> - * option is in effect. - * </ul> + * A single instance handles conversions in one direction only. This is a + * consequence of specifying options as varargs, but fits well with "normal" + * application design, in which input and output are distinct operations. + * Note that, depending on options settings, output generated by one converter + * may not be valid input for another. + * <p> + * The basic structure of XML produced/consumed by this class is that the + * root element represents the object being converted, and its child nodes + * represent the elements/properties of the object. Nodes representing complex + * objects have child elements, those representing simple (primitive) objects + * have a single text child. Objects are processed recursively, and cycles are + * <em>not</em> detected (although this may change). + * <p> + * A namespace and qualified name may be provided to {@link #convertToXml}, + * and all elements will inherit the namespace and prefix. Namespaces are + * ignored on input; all property matches uses the element's local name. + * <p> + * Each element may have an <code>xsi:type</code> attribute (where <code>xsi + * </code> references to the XML Schema instance namespace). This attribute + * is optional for both output and input; if used for output, it is merely + * informational, but for input will be examined to validate that the XML is + * appropriate for the desired object type. For primitive types, wrappers, + * and strings, it takes the form "<code>xsd:TYPE</code>", where <code>TYPE + * </code> is one of the simple types defined by XML schema. For other Java + * types, it takes the form "<code>java:TYPE</code>", where <code>TYPE</code> + * is the fully qualified Java classname. + * <p> + * On input, the desired type is specified by the caller or by introspection + * (except in the case of collection elements; see below). The <code>xsi:type + * </code> value, if any, is ignored except for validation. + * <p> + * Additional conversion rules are as follows: + * + * <table border="1"> + * <tr><th>Java Object Type + * <th>{@link #convertToXml} + * <th>{@link #convertToJava} + * <tr><td>Primitives, Wrapper objects, and String + * <td> + * <td> + * <tr><td>Arrays + * <td>Elements of the array are written in sequence to the DOM, using the + * element name "<code>data</code>". Elements are given an attribute + * named "<code>index</code>", which contains the element's position + * within the array. + * <td>Elements of the array are processed in sequence, ignoring both + * element name and "index" attribute. + * <tr><td>Lists and Sets + * <td>The collection is iterated, and elements are written in sequence to + * the DOM, using the element name "<code>data</code>". Elements are + * given an attribute named "<code>index</code>", which contains the + * element's position within the iteration (meaningful only for lists). + * <td>Elements of the are processed in sequence, ignoring both element + * name and "index" attribute. + * <p> + * If an <code>xsi:type</code> attribute is present, it will be used + * to drive conversion of the element. Otherwise, the element will be + * converted as a <code>String</code> (which will fail for complex + * types, because string conversion assumes a single text node). + * <p> + * Where the caller specifies an interface as the conversion class, the + * converter will choose an appropriate implementation class: + * <ul> + * <li> <code>ArrayList</code> for <code>List</code> or <code>Collection</code> + * <li> <code>TreeSet</code> for <code>SortedSet</code> + * <li> <code>HashSet</code> for <code>Set</code> + * </ul> + * <tr><td>Maps + * <td>The collection is iterated, and elements are written in sequence to + * the DOM. Depending on the output options, either the entry key will + * be used as the element name, or the name will be "<code>data</code>" + * and the key stored in an attribute named "<code>key</code>". The + * former option is only permitted if all keys in the map are valid + * XML element names; otherwise the converter will throw. + * <td>Elements are processed in sequence. The converter first looks for + * a "<code>key</code>" attribute, and will use it as the entry key + * if found. Otherwise, it will use the element name. If your maps + * are being reduced to a single entry, look for a missing attribute. + * <p> + * If an <code>xsi:type</code> attribute is present, it will be used + * to drive conversion of the element. Otherwise, the element will be + * converted as a <code>String</code> (which will fail for complex + * types, because string conversion assumes a single text node). + * <p> + * Where the caller specifies an interface as the conversion class, + * the converter will choose an appropriate implementation class: + * <code>TreeMap</code> for <code>SortedMap</code>, and <code>HashMap + * </code> for <code>Map</code>. + * <tr><td>Bean-structured Objects + * <td>The object is introspected, and properties are written in the order + * provided by the <code>Introspector</code>. + * <td>The bean class must provide a no-argument constructor (otherwise it + * doesn't follow the bean spec, and we can't use it). + * <p> + * The converter relies on <code>java.beans.Introspector</code> to find + * property setter methods for an object. If the object provides + * multiple methods for the property, the converter will use whichever + * one the introspector provides. + * <p> + * Elements are processed in order, and the element's localname is used + * to find the associated object property. If the XML does not contain + * an element corresponding to a bean property, that property is left + * with its default value (ie, we don't try to find an element based + * on property name). + * <p> + * If the XML contains an element that does not correspond to any bean + * property, the converter will either throw or ignore the element, + * depending on options settings. + * <tr><td>Other Objects + * <td>not supported + * <td>not supported + * </table> + * + * <strong>Warning</strong>: + * this class makes use of <code>java.beans.Introspector</code>, which holds + * a cache of introspected objects. If you use this converter in an app-server + * you should call <code>Introspector.flushCaches()</code> during deploy. */ public class BeanConverter { /** * Creates a new DOM document from the passed bean, in which all elements * are members of the specified namespace. - * + * * @param bean The source object. This can be any Java object: * bean, collection, or simple type. * @param nsUri The namespace of the root element. This will be * inherited by all child elements. - * @param rootName The qualified name given to the root element of the + * @param rootName The qualified name given to the root element of the * generated document. If a qualified name, all child * elements will inherit its prefix. * @param options Options controlling output. . */ - public static Document generateXml(Object bean, String nsUri, String rootName, + public static Document generateXml(Object bean, String nsUri, String rootName, Bean2XmlOptions... options) { Bean2XmlDriver driver = new Bean2XmlDriver(options); return driver.convert(bean, nsUri, rootName).getOwnerDocument(); } - - + + /** * Creates a new DOM document from the passed bean, without namespace. - * + * * @param bean The source object. This can be any Java object: * bean, collection, or simple type. * @param rootName The name given to the root element of the produced @@ -76,7 +178,7 @@ * @param options Options controlling output. . */ - public static Document generateXml(Object bean, String rootName, + public static Document generateXml(Object bean, String rootName, Bean2XmlOptions... options) { Bean2XmlDriver driver = new Bean2XmlDriver(options); Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanDriver.java =================================================================== --- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanDriver.java 2009-08-17 17:26:40 UTC (rev 110) +++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/bean/Xml2BeanDriver.java 2009-08-17 20:24:04 UTC (rev 111) @@ -48,31 +48,6 @@ * Driver class for converting an XML DOM into a Java bean. Normal usage is * to create a single instance of this class with desired options, then use * it for multiple conversions. This class is thread-safe. - * <p> - * This class assumes that the source XML will be in the form produced by - * {@link Bean2XmlDriver}: each element either contains child elements, or - * a text node containing the element's value. However, conversion is - * driven by the parameters passed to {@link #convert}, not by the content - * of the XML document; this can lead to some unexpected behavior: - * <ul> - * <li> Bean classes are introspected, and recursively processed base on - * the property descriptors. If the bean has multiple setter methods - * for a property, the method selected is arbitrarily chosen by the - * JavaBeans introspector. You can pass an option that looks for a - * setters using <code>String</code>, but this is not recommended - * from a performance perspective. - * <li> JDK collection types do not carry type information, so the only - * way to properly convert them is using an <code>xsi:type</code> - * attribute on the child elements. If this attribute is missing - * or cannot be interpreted, the element will be processed as if - * it is a <code>String</code>. - * <li> The converter will to pick an appropriate implementation class - * if given one of the JDK collections interfaces: <code> - * ArrayList</code> for <code>List</code> or <code>Collection</code>, - * <code>TreeSet</code> for <code>SortedSet</code>, <code>HashSet</code> - * for any other <code>Set</code>, and likewise <code>TreeMap</code> and - * <code>HashMap</code> for <code>SortedMap</code> and <code>Map</code>. - * </ul> */ public class Xml2BeanDriver { Modified: branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/package.html =================================================================== --- branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/package.html 2009-08-17 17:26:40 UTC (rev 110) +++ branches/dev-1.1/src/main/java/net/sf/practicalxml/converter/package.html 2009-08-17 20:24:04 UTC (rev 111) @@ -1,6 +1,15 @@ <html> <body> This package contains classes to convert between XML and a variety of - other formats. + other formats. Each conversion has a top-level convenience class in + this package, which handles common conversion scenarios and provides + overall documentation on the conversion. Sub-packages contain the + actual conversion classes; you may need to use those classes directly + for "unusual" conversions. + <p> + Any problems during conversion (in either direction) are reported via + {@link ConversionException}, which is a runtime exception and will + wrap any actual exception. If appropriate, this exception will also + contain the XPath to the node failing conversion. </body> </html> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |