| /* | |
| * Copyright (c) 2004, 2021 Oracle and/or its affiliates. All rights reserved. | |
| * | |
| * This program and the accompanying materials are made available under the | |
| * terms of the Eclipse Distribution License v. 1.0, which is available at | |
| * http://www.eclipse.org/org/documents/edl-v10.php. | |
| * | |
| * SPDX-License-Identifier: BSD-3-Clause | |
| */ | |
| package jakarta.xml.bind.annotation.adapters; | |
| /** | |
| * Adapts a Java type for custom marshaling. | |
| * | |
| * <p> <b> Usage: </b> </p> | |
| * | |
| * <p> | |
| * Some Java types do not map naturally to an XML representation, for | |
| * example {@code HashMap} or other non JavaBean classes. Conversely, | |
| * an XML representation may map to a Java type but an application may | |
| * choose to access the XML representation using another Java | |
| * type. For example, the schema to Java binding rules bind | |
| * xs:DateTime by default to XmlGregorianCalendar. But an application | |
| * may desire to bind xs:DateTime to a custom type, | |
| * MyXmlGregorianCalendar, for example. In both cases, there is a | |
| * mismatch between <i> bound type </i>, used by an application to | |
| * access XML content and the <i> value type</i>, that is mapped to an | |
| * XML representation. | |
| * | |
| * <p> | |
| * This abstract class defines methods for adapting a bound type to a value | |
| * type or vice versa. The methods are invoked by the Jakarta XML Binding binding | |
| * framework during marshaling and unmarshalling: | |
| * | |
| * <ul> | |
| * <li> <b> XmlAdapter.marshal(...): </b> During marshalling, Jakarta XML Binding | |
| * binding framework invokes XmlAdapter.marshal(..) to adapt a | |
| * bound type to value type, which is then marshaled to XML | |
| * representation. </li> | |
| * | |
| * <li> <b> XmlAdapter.unmarshal(...): </b> During unmarshalling, | |
| * Jakarta XML Binding binding framework first unmarshals XML representation | |
| * to a value type and then invokes XmlAdapter.unmarshal(..) to | |
| * adapt the value type to a bound type. </li> | |
| * </ul> | |
| * | |
| * Writing an adapter therefore involves the following steps: | |
| * | |
| * <ul> | |
| * <li> Write an adapter that implements this abstract class. </li> | |
| * <li> Install the adapter using the annotation {@link | |
| * XmlJavaTypeAdapter} </li> | |
| * </ul> | |
| * | |
| * <p><b>Example:</b> Customized mapping of {@code HashMap}</p> | |
| * <p> The following example illustrates the use of | |
| * {@code @XmlAdapter} and {@code @XmlJavaTypeAdapter} to | |
| * customize the mapping of a {@code HashMap}. | |
| * | |
| * <p> <b> Step 1: </b> Determine the desired XML representation for HashMap. | |
| * | |
| * <pre>{@code | |
| * <hashmap> | |
| * <entry key="id123">this is a value</entry> | |
| * <entry key="id312">this is another value</entry> | |
| * ... | |
| * </hashmap> | |
| * }</pre> | |
| * | |
| * <p> <b> Step 2: </b> Determine the schema definition that the | |
| * desired XML representation shown above should follow. | |
| * | |
| * <pre>{@code | |
| * | |
| * <xs:complexType name="myHashMapType"> | |
| * <xs:sequence> | |
| * <xs:element name="entry" type="myHashMapEntryType" | |
| * minOccurs = "0" maxOccurs="unbounded"/> | |
| * </xs:sequence> | |
| * </xs:complexType> | |
| * | |
| * <xs:complexType name="myHashMapEntryType"> | |
| * <xs:simpleContent> | |
| * <xs:extension base="xs:string"> | |
| * <xs:attribute name="key" type="xs:int"/> | |
| * </xs:extension> | |
| * </xs:simpleContent> | |
| * </xs:complexType> | |
| * | |
| * }</pre> | |
| * | |
| * <p> <b> Step 3: </b> Write value types that can generate the above | |
| * schema definition. | |
| * | |
| * <pre> | |
| * public class MyHashMapType { | |
| * List<MyHashMapEntryType> entry; | |
| * } | |
| * | |
| * public class MyHashMapEntryType { | |
| * @XmlAttribute | |
| * public Integer key; | |
| * | |
| * @XmlValue | |
| * public String value; | |
| * } | |
| * </pre> | |
| * | |
| * <p> <b> Step 4: </b> Write the adapter that adapts the value type, | |
| * MyHashMapType to a bound type, HashMap, used by the application. | |
| * | |
| * <pre>{@code | |
| * public final class MyHashMapAdapter extends | |
| * XmlAdapter<MyHashMapType,HashMap> { ... } | |
| * | |
| * }</pre> | |
| * | |
| * <p> <b> Step 5: </b> Use the adapter. | |
| * | |
| * <pre> | |
| * public class Foo { | |
| * @XmlJavaTypeAdapter(MyHashMapAdapter.class) | |
| * HashMap hashmap; | |
| * ... | |
| * } | |
| * </pre> | |
| * | |
| * The above code fragment will map to the following schema: | |
| * | |
| * <pre>{@code | |
| * <xs:complexType name="Foo"> | |
| * <xs:sequence> | |
| * <xs:element name="hashmap" type="myHashMapType"> | |
| * </xs:sequence> | |
| * </xs:complexType> | |
| * }</pre> | |
| * | |
| * @param <BoundType> | |
| * The type that Jakarta XML Binding doesn't know how to handle. An adapter is written | |
| * to allow this type to be used as an in-memory representation through | |
| * the {@code ValueType}. | |
| * @param <ValueType> | |
| * The type that Jakarta XML Binding knows how to handle out of the box. | |
| * | |
| * @author <ul><li>Sekhar Vajjhala, Sun Microsystems Inc.</li> <li> Kohsuke Kawaguchi, Sun Microsystems Inc.</li></ul> | |
| * @see XmlJavaTypeAdapter | |
| * @since 1.6, JAXB 2.0 | |
| */ | |
| public abstract class XmlAdapter<ValueType,BoundType> { | |
| /** | |
| * Do-nothing constructor for the derived classes. | |
| */ | |
| protected XmlAdapter() {} | |
| /** | |
| * Convert a value type to a bound type. | |
| * | |
| * @param v | |
| * The value to be converted. Can be null. | |
| * @throws Exception | |
| * if there's an error during the conversion. The caller is responsible for | |
| * reporting the error to the user through {@link jakarta.xml.bind.ValidationEventHandler}. | |
| */ | |
| public abstract BoundType unmarshal(ValueType v) throws Exception; | |
| /** | |
| * Convert a bound type to a value type. | |
| * | |
| * @param v | |
| * The value to be convereted. Can be null. | |
| * @throws Exception | |
| * if there's an error during the conversion. The caller is responsible for | |
| * reporting the error to the user through {@link jakarta.xml.bind.ValidationEventHandler}. | |
| */ | |
| public abstract ValueType marshal(BoundType v) throws Exception; | |
| } |