|
|
(One intermediate revision by the same user not shown) |
Line 1: |
Line 1: |
− | {{EclipseLink_UserGuide
| + | Please see http://www.eclipse.org/eclipselink/documentation/2.4/moxy/special_schema_types002.htm |
− | |info=y
| + | |
− | |toc=y
| + | |
− | |eclipselink=y
| + | |
− | |eclipselinktype=MOXy
| + | |
− | }}
| + | |
− | | + | |
− | =Mapping to a Union Field=
| + | |
− | | + | |
− | The following XML schema and class diagram show a typical use of an XML Schema Union:
| + | |
− | | + | |
− | <source lang="xml">
| + | |
− | <?xml version="1.0" encoding="UTF-8"?>
| + | |
− | <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
| + | |
− | <xsd:element name="customer" type="customer-type" />
| + | |
− | <xsd:complexType name="customer-type">
| + | |
− | <xsd:sequence>
| + | |
− | <xsd:element name="shoe-size" type="size-type" />
| + | |
− | </xsd:sequence>
| + | |
− | </xsd:complexType>
| + | |
− | <xsd:simpleType name="size-type">
| + | |
− | <xsd:union memberTypes="xsd:decimal xsd:string" />
| + | |
− | </xsd:simpleType>
| + | |
− | </xsd:schema>
| + | |
− | </source>
| + | |
− | | + | |
− | [[Image:dxmuc.gif]]<br><br>
| + | |
− | | + | |
− | The figure below illustrates a mapping to a union field in an XML document that conforms to the example schema. When EclipseLink unmarshalls the XML document, it tries each of the union types until it can make a successful conversion. The first schema type in the union is '''xsd:decimal'''. Because "10.5" is a valid decimal, EclipseLink converts the value to the appropriate type.
| + | |
− | | + | |
− | [[Image:dxmuv.gif]]<br><br>
| + | |
− | | + | |
− | In a second example document, the value "M" is not a valid '''xsd:decimal''' type, so the next union type is tried, '''xsd:string'''.
| + | |
− | | + | |
− | [[Image:dxmuvs.gif]]<br><br>
| + | |
− | | + | |
− | == Example ==
| + | |
− | | + | |
− | Currently, EclipseLink does not support the mapping of Unions using Annotations or OXM Metadata. However, an EclipseLink XML Customizer can be used to create the mapping.
| + | |
− | | + | |
− | First, we annotate the '''shoeSize''' attribute with '''@XmlTransient''', to avoid automatically generating a mapping for it. We also include an '''@XmlCustomizer''' annotation; the '''CustomerCustomizer''' class will create the Union mapping in code.
| + | |
− | | + | |
− | <source lang="java">
| + | |
− | package example;
| + | |
− | | + | |
− | import javax.xml.bind.annotation.*;
| + | |
− | import org.eclipse.persistence.oxm.annotations.*;
| + | |
− | | + | |
− | @XmlRootElement
| + | |
− | @XmlAccessorType(XmlAccessType.FIELD)
| + | |
− | @XmlCustomizer(CustomerCustomizer.class)
| + | |
− | public class Customer {
| + | |
− | @XmlTransient
| + | |
− | private Object shoeSize;
| + | |
− | | + | |
− | ...
| + | |
− | }
| + | |
− | </source>
| + | |
− | | + | |
− | | + | |
− | The '''CustomerCustomizer''' class can be used to manually add a mapping to the '''shoeSize''' attribute. Here, an '''XMLUnionField''' is configured on the mapping, and the possible Union member types are added by calling '''addSchemaType()''':
| + | |
− | | + | |
− | <source lang="java">
| + | |
− | package example;
| + | |
− | | + | |
− | import org.eclipse.persistence.config.DescriptorCustomizer;
| + | |
− | import org.eclipse.persistence.descriptors.ClassDescriptor;
| + | |
− | import org.eclipse.persistence.oxm.*;
| + | |
− | | + | |
− | public class CustomerCustomizer implements DescriptorCustomizer {
| + | |
− | | + | |
− | @Override
| + | |
− | public void customize(ClassDescriptor descriptor) throws Exception {
| + | |
− | XMLDirectMapping shoeSizeMapping = new XMLDirectMapping();
| + | |
− | shoeSizeMapping.setAttributeName("shoeSize");
| + | |
− | | + | |
− | XMLUnionField shoeSizeField = new XMLUnionField();
| + | |
− | shoeSizeField.setXPath("shoe-size/text()");
| + | |
− | shoeSizeField.addSchemaType(XMLConstants.DECIMAL_QNAME);
| + | |
− | shoeSizeField.addSchemaType(XMLConstants.STRING_QNAME);
| + | |
− | | + | |
− | shoeSizeMapping.setField(shoeSizeField);
| + | |
− |
| + | |
− | descriptor.addMapping(shoeSizeMapping);
| + | |
− | }
| + | |
− | | + | |
− | }
| + | |
− | </source>
| + | |
− | | + | |
− | | + | |
− | == Conversion Order ==
| + | |
− | | + | |
− | The order of the calls to '''addSchemaType()''' is important; when converting an XML value into Java, EclipseLink will attempt the conversions in the order that they were added to the field, and return as soon as a successful conversion is made. For example, when unmarshalling a '''shoeSize''' of "10.5":
| + | |
− | | + | |
− | <source lang="java">
| + | |
− | ...
| + | |
− | shoeSizeField.addSchemaType(XMLConstants.DECIMAL_QNAME);
| + | |
− | shoeSizeField.addSchemaType(XMLConstants.STRING_QNAME);
| + | |
− | ...
| + | |
− | </source>
| + | |
− | | + | |
− | A '''BigDecimal''' will be created to store the value. If, however, your '''XMLUnionField''' was set up like this:
| + | |
− | | + | |
− | <source lang="java">
| + | |
− | ...
| + | |
− | shoeSizeField.addSchemaType(XMLConstants.STRING_QNAME);
| + | |
− | shoeSizeField.addSchemaType(XMLConstants.DECIMAL_QNAME);
| + | |
− | ...
| + | |
− | </source>
| + | |
− | | + | |
− | The '''shoeSize''' value will be a String ("10.5").
| + | |
− | | + | |
− | | + | |
− | == Customizing Conversion Classes ==
| + | |
− | | + | |
− | EclipseLink uses a set of default conversions to create a value for the Java attribute (in this case, '''xsd:decimal''' will be converted into a '''BigDecimal'''). You can override this behavior in Java code using the '''XMLUnionField''' method '''addConversion'''. For example, if you want your Java object to store '''shoeSize''' as a '''Float''':
| + | |
− | | + | |
− | <source lang="java">
| + | |
− | shoeSizeField.addConversion(XMLConstants.DECIMAL_QNAME, Float.class);
| + | |
− | </source>
| + | |