001: /*
002: * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
003: * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
004: */
005:
006: package javax.xml.bind.annotation.adapters;
007:
008: /**
009: * Adapts a Java type for custom marshaling.
010: *
011: * <p> <b> Usage: </b> </p>
012: *
013: * <p>
014: * Some Java types do not map naturally to a XML representation, for
015: * example <tt>HashMap</tt> or other non JavaBean classes. Conversely,
016: * a XML repsentation may map to a Java type but an application may
017: * choose to accesss the XML representation using another Java
018: * type. For example, the schema to Java binding rules bind
019: * xs:DateTime by default to XmlGregorianCalendar. But an application
020: * may desire to bind xs:DateTime to a custom type,
021: * MyXmlGregorianCalendar, for example. In both cases, there is a
022: * mismatch between <i> bound type </i>, used by an application to
023: * access XML content and the <i> value type</i>, that is mapped to an
024: * XML representation.
025: *
026: * <p>
027: * This abstract class defines methods for adapting a bound type to a value
028: * type or vice versa. The methods are invoked by the JAXB binding
029: * framework during marshaling and unmarshalling:
030: *
031: * <ul>
032: * <li> <b> XmlAdapter.marshal(...): </b> During marshalling, JAXB
033: * binding framework invokes XmlAdapter.marshal(..) to adapt a
034: * bound type to value type, which is then marshaled to XML
035: * representation. </li>
036: *
037: * <li> <b> XmlAdapter.unmarshal(...): </b> During unmarshalling,
038: * JAXB binding framework first unmarshals XML representation
039: * to a value type and then invokes XmlAdapter.unmarshal(..) to
040: * adapt the value type to a bound type. </li>
041: * </ul>
042: *
043: * Writing an adapter therefore involves the following steps:
044: *
045: * <ul>
046: * <li> Write an adapter that implements this abstract class. </li>
047: * <li> Install the adapter using the annotation {@link
048: * XmlJavaTypeAdapter} </li>
049: * </ul>
050: *
051: * <p><b>Example:</b> Customized mapping of </tt>HashMap</tt></p>
052: * <p> The following example illustrates the use of
053: * <tt>@XmlAdapter</tt> and <tt>@XmlJavaTypeAdapter</tt> to
054: * customize the mapping of a <tt>HashMap</tt>.
055: *
056: * <p> <b> Step 1: </b> Determine the desired XML representation for HashMap.
057: *
058: * <pre>
059: * <hashmap>
060: * <entry key="id123">this is a value</entry>
061: * <entry key="id312">this is another value</entry>
062: * ...
063: * </hashmap>
064: * </pre>
065: *
066: * <p> <b> Step 2: </b> Determine the schema definition that the
067: * desired XML representation shown above should follow.
068: *
069: * <pre>
070: *
071: * <xs:complexType name="myHashMapType">
072: * <xs:sequence>
073: * <xs:element name="entry" type="myHashMapEntryType"
074: * minOccurs = "0" maxOccurs="unbounded"/>
075: * </xs:sequence>
076: * </xs:complexType>
077: *
078: * <xs:complexType name="myHashMapEntryType">
079: * <xs:simpleContent>
080: * <xs:extension base="xs:string">
081: * <xs:attribute name="key" type="xs:int"/>
082: * </xs:extension>
083: * </xs:simpleContent>
084: * </xs:complexType>
085: *
086: * </pre>
087: *
088: * <p> <b> Step 3: </b> Write value types that can generate the above
089: * schema definition.
090: *
091: * <pre>
092: * public class MyHashMapType {
093: * List<MyHashMapEntryType> entry;
094: * }
095: *
096: * public class MyHashMapEntryType {
097: * @XmlAttribute
098: * public Integer key;
099: *
100: * @XmlValue
101: * public String value;
102: * }
103: * </pre>
104: *
105: * <p> <b> Step 4: </b> Write the adapter that adapts the value type,
106: * MyHashMapType to a bound type, HashMap, used by the application.
107: *
108: * <pre>
109: * public final class MyHashMapAdapter extends
110: * XmlAdapter<MyHashMapType,HashMap> { ... }
111: *
112: * </pre>
113: *
114: * <p> <b> Step 5: </b> Use the adapter.
115: *
116: * <pre>
117: * public class Foo {
118: * @XmlJavaTypeAdapter(MyHashMapAdapter.class)
119: * HashMap hashmap;
120: * ...
121: * }
122: * </pre>
123: *
124: * The above code fragment will map to the following schema:
125: *
126: * <pre>
127: * <xs:complexType name="Foo">
128: * <xs:sequence>
129: * <xs:element name="hashmap" type="myHashMapType"
130: * </xs:sequence>
131: * </xs:complexType>
132: * </pre>
133: *
134: * @param <BoundType>
135: * The type that JAXB doesn't know how to handle. An adapter is written
136: * to allow this type to be used as an in-memory representation through
137: * the <tt>ValueType</tt>.
138: * @param <ValueType>
139: * The type that JAXB knows how to handle out of the box.
140: *
141: * @author <ul><li>Sekhar Vajjhala, Sun Microsystems Inc.</li> <li> Kohsuke Kawaguchi, Sun Microsystems Inc.</li></ul>
142: * @see XmlJavaTypeAdapter
143: * @since JAXB 2.0
144: */
145: public abstract class XmlAdapter<ValueType, BoundType> {
146:
147: /**
148: * Do-nothing constructor for the derived classes.
149: */
150: protected XmlAdapter() {
151: }
152:
153: /**
154: * Convert a value type to a bound type.
155: *
156: * @param v
157: * The value to be converted. Can be null.
158: * @throws Exception
159: * if there's an error during the conversion. The caller is responsible for
160: * reporting the error to the user through {@link javax.xml.bind.ValidationEventHandler}.
161: */
162: public abstract BoundType unmarshal(ValueType v) throws Exception;
163:
164: /**
165: * Convert a bound type to a value type.
166: *
167: * @param v
168: * The value to be convereted. Can be null.
169: * @throws Exception
170: * if there's an error during the conversion. The caller is responsible for
171: * reporting the error to the user through {@link javax.xml.bind.ValidationEventHandler}.
172: */
173: public abstract ValueType marshal(BoundType v) throws Exception;
174: }
|