1 /* 2 * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.xml.bind.annotation.adapters; 27 28 /** 29 * Adapts a Java type for custom marshaling. 30 * 31 * <p> <b> Usage: </b> </p> 32 * 33 * <p> 34 * Some Java types do not map naturally to a XML representation, for 35 * example <tt>HashMap</tt> or other non JavaBean classes. Conversely, 36 * a XML repsentation may map to a Java type but an application may 37 * choose to accesss the XML representation using another Java 38 * type. For example, the schema to Java binding rules bind 39 * xs:DateTime by default to XmlGregorianCalendar. But an application 40 * may desire to bind xs:DateTime to a custom type, 41 * MyXmlGregorianCalendar, for example. In both cases, there is a 42 * mismatch between <i> bound type </i>, used by an application to 43 * access XML content and the <i> value type</i>, that is mapped to an 44 * XML representation. 45 * 46 * <p> 47 * This abstract class defines methods for adapting a bound type to a value 48 * type or vice versa. The methods are invoked by the JAXB binding 49 * framework during marshaling and unmarshalling: 50 * 51 * <ul> 52 * <li> <b> XmlAdapter.marshal(...): </b> During marshalling, JAXB 53 * binding framework invokes XmlAdapter.marshal(..) to adapt a 54 * bound type to value type, which is then marshaled to XML 55 * representation. </li> 56 * 57 * <li> <b> XmlAdapter.unmarshal(...): </b> During unmarshalling, 58 * JAXB binding framework first unmarshals XML representation 59 * to a value type and then invokes XmlAdapter.unmarshal(..) to 60 * adapt the value type to a bound type. </li> 61 * </ul> 62 * 63 * Writing an adapter therefore involves the following steps: 64 * 65 * <ul> 66 * <li> Write an adapter that implements this abstract class. </li> 67 * <li> Install the adapter using the annotation {@link 68 * XmlJavaTypeAdapter} </li> 69 * </ul> 70 * 71 * <p><b>Example:</b> Customized mapping of <tt>HashMap</tt></p> 72 * <p> The following example illustrates the use of 73 * <tt>@XmlAdapter</tt> and <tt>@XmlJavaTypeAdapter</tt> to 74 * customize the mapping of a <tt>HashMap</tt>. 75 * 76 * <p> <b> Step 1: </b> Determine the desired XML representation for HashMap. 77 * 78 * <pre> 79 * <hashmap> 80 * <entry key="id123">this is a value</entry> 81 * <entry key="id312">this is another value</entry> 82 * ... 83 * </hashmap> 84 * </pre> 85 * 86 * <p> <b> Step 2: </b> Determine the schema definition that the 87 * desired XML representation shown above should follow. 88 * 89 * <pre> 90 * 91 * <xs:complexType name="myHashMapType"> 92 * <xs:sequence> 93 * <xs:element name="entry" type="myHashMapEntryType" 94 * minOccurs = "0" maxOccurs="unbounded"/> 95 * </xs:sequence> 96 * </xs:complexType> 97 * 98 * <xs:complexType name="myHashMapEntryType"> 99 * <xs:simpleContent> 100 * <xs:extension base="xs:string"> 101 * <xs:attribute name="key" type="xs:int"/> 102 * </xs:extension> 103 * </xs:simpleContent> 104 * </xs:complexType> 105 * 106 * </pre> 107 * 108 * <p> <b> Step 3: </b> Write value types that can generate the above 109 * schema definition. 110 * 111 * <pre> 112 * public class MyHashMapType { 113 * List<MyHashMapEntryType> entry; 114 * } 115 * 116 * public class MyHashMapEntryType { 117 * @XmlAttribute 118 * public Integer key; 119 * 120 * @XmlValue 121 * public String value; 122 * } 123 * </pre> 124 * 125 * <p> <b> Step 4: </b> Write the adapter that adapts the value type, 126 * MyHashMapType to a bound type, HashMap, used by the application. 127 * 128 * <pre> 129 * public final class MyHashMapAdapter extends 130 * XmlAdapter<MyHashMapType,HashMap> { ... } 131 * 132 * </pre> 133 * 134 * <p> <b> Step 5: </b> Use the adapter. 135 * 136 * <pre> 137 * public class Foo { 138 * @XmlJavaTypeAdapter(MyHashMapAdapter.class) 139 * HashMap hashmap; 140 * ... 141 * } 142 * </pre> 143 * 144 * The above code fragment will map to the following schema: 145 * 146 * <pre> 147 * <xs:complexType name="Foo"> 148 * <xs:sequence> 149 * <xs:element name="hashmap" type="myHashMapType" 150 * </xs:sequence> 151 * </xs:complexType> 152 * </pre> 153 * 154 * @param <BoundType> 155 * The type that JAXB doesn't know how to handle. An adapter is written 156 * to allow this type to be used as an in-memory representation through 157 * the <tt>ValueType</tt>. 158 * @param <ValueType> 159 * The type that JAXB knows how to handle out of the box. 160 * 161 * @author <ul><li>Sekhar Vajjhala, Sun Microsystems Inc.</li> <li> Kohsuke Kawaguchi, Sun Microsystems Inc.</li></ul> 162 * @see XmlJavaTypeAdapter 163 * @since 1.6, JAXB 2.0 164 */ 165 public abstract class XmlAdapter<ValueType,BoundType> { 166 167 /** 168 * Do-nothing constructor for the derived classes. 169 */ 170 protected XmlAdapter() {} 171 172 /** 173 * Convert a value type to a bound type. 174 * 175 * @param v 176 * The value to be converted. Can be null. 177 * @throws Exception 178 * if there's an error during the conversion. The caller is responsible for 179 * reporting the error to the user through {@link javax.xml.bind.ValidationEventHandler}. 180 */ 181 public abstract BoundType unmarshal(ValueType v) throws Exception; 182 183 /** 184 * Convert a bound type to a value type. 185 * 186 * @param v 187 * The value to be convereted. Can be null. 188 * @throws Exception 189 * if there's an error during the conversion. The caller is responsible for 190 * reporting the error to the user through {@link javax.xml.bind.ValidationEventHandler}. 191 */ 192 public abstract ValueType marshal(BoundType v) throws Exception; 193 }