Jump to: navigation, search

Difference between revisions of "EclipseLink/UserGuide/MOXy/Simple Values/Special Schema Types/Unions"

Line 34: Line 34:
  
 
[[Image:dxmuvs.gif]]<br><br>
 
[[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.
 
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:
 +
 +
<source lang="java">
 +
package example;
 +
 +
import javax.xml.bind.annotation.*;
 +
import org.eclipse.persistence.oxm.annotations.*;
 +
 +
@XmlRootElement
 +
@XmlAccessorType(XmlAccessType.FIELD)
 +
@XmlCustomizer(EmployeeCustomizer.class)
 +
public class Employee {
 +
  @XmlAttribute
 +
  private Integer id;
 +
 +
  @XmlAttribute
 +
  private String name;
 +
 +
  @XmlInverseReference(mappedBy="employee")
 +
  private PhoneNumber phone;
 +
 +
  @XmlTransient
 +
  private Object shoeSize;
 +
 +
  ...
 +
}
 +
</source>
  
 
<source lang="java">
 
<source lang="java">

Revision as of 09:41, 26 April 2011

EclipseLink MOXy

link="http://wiki.eclipse.org/EclipseLink"
EclipseLink
Website
Download
Community
Mailing ListForumsIRC
Bugzilla
Open
Help Wanted
Bug Day
Contribute
Browse Source

Mapping to a Union Field

The following XML schema and class diagram show a typical use of an XML Schema Union:

<?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>

Dxmuc.gif

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. If the Object attribute is specific enough to trigger an appropriate value, EclipseLink will use that type instead. Otherwise, EclipseLink uses a default (in this case BigDecimal). You can override this behavior in Java code.

Dxmuv.gif

In a second example document, the value "M" is not a valid xsd:decimal type, so the next union type is tried, xsd:string.

Dxmuvs.gif

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:

package example;
 
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.*;
 
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlCustomizer(EmployeeCustomizer.class)
public class Employee {
   @XmlAttribute
   private Integer id;
 
   @XmlAttribute
   private String name;
 
   @XmlInverseReference(mappedBy="employee")
   private PhoneNumber phone;
 
   @XmlTransient
   private Object shoeSize;
 
   ...
}
package example;
 
import org.eclipse.persistence.config.DescriptorCustomizer;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.oxm.*;
 
public class EmployeeCustomizer implements DescriptorCustomizer {
 
   @Override
   public void customize(ClassDescriptor descriptor) throws Exception {
      XMLDirectMapping shoeSizeMapping = new XMLDirectMapping();
      shoeSizeMapping.setAttributeName("shoeSize");
 
      XMLUnionField shoeSizeField = new XMLUnionField();
      shoeSizeField.setXPath("shoeSize/text()");
      shoeSizeField.addSchemaType(XMLConstants.DECIMAL_QNAME);
      shoeSizeField.addSchemaType(XMLConstants.STRING_QNAME);
 
      shoeSizeMapping.setField(shoeSizeField);
 
      descriptor.addMapping(shoeSizeMapping);
   }
 
}


To override the default conversion, use the XMLUnionField method addConversion:

shoeSizeField.addConversion(XMLConstants.DECIMAL_QNAME, Float.class);

Mapping to a Union of Lists

Given the XML schema in Schema for XML Direct Mapping to Union of Lists, the XML Direct Mapping to Union of Lists figure illustrates an XML direct mapping to a union of lists in a corresponding XML document. The Java for XML Direct Mapping to Union of Lists example shows how to configure this mapping in Java.


Schema for XML Direct Mapping to Union of Lists

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <xsd:element name="vacation" type="unionOfLists"/>
    <xsd:simpleType name="unionOfLists">
        <xsd:union memberTypes="xsd:double">
            <xsd:simpleType>
                <xsd:list itemType="xsd:date"/>
            </xsd:simpleType>

            <xsd:simpleType>
                <xsd:list itemType="xsd:integer"/>
            </xsd:simpleType>
        </xsd:union>
    </xsd:simpleType>
</xsd:schema>


XML Direct Mapping to Union of Lists

Dxuofl.gif

Note that in this example, valid XML documents contain either all xsd:double, all xsd:date, or all xsd:integer values.


Java for XML Direct Mapping to Union of Lists

XMLDirectMapping mapping = new XMLDirectMapping();
mapping.setAttributeName("vacation");
mapping.setXPath("UnionOfLists/text()");

Mapping to a Union of Unions

Given the XML schema in the Schema for XML Direct Mapping to a Union of Unions example, the Java Class for XML Direct Mapping to a Union of Unions figure illustrates a Java class that can be mapped to a corresponding XML document. The Java for XML Direct Mapping to a Union of Unions example shows how to configure this mapping in Java.


Schema for XML Direct Mapping to a Union of Unions

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="vacation" type="unionOfUnions"/>
    <xsd:simpleType name="unionOfUnions">
        <xsd:union>

            <xsd:simpleType>
                <xsd:union>
                    <xsd:simpleType>
                        <xsd:list itemType="xsd:date"/>
                    </xsd:simpleType>
                    <xsd:simpleType>

                        <xsd:list itemType="xsd:integer"/>
                    </xsd:simpleType>
                </xsd:union>
            </xsd:simpleType>
            <xsd:simpleType>
                <xsd:union>

                    <xsd:simpleType>
                        <xsd:list itemType="xsd:string"/>
                    </xsd:simpleType>
                    <xsd:simpleType>
                        <xsd:list itemType="xsd:float"/>
                    </xsd:simpleType>

                </xsd:union>
            </xsd:simpleType>
        </xsd:union>
    </xsd:simpleType>
</xsd:schema>


Java Class for XML Direct Mapping to a Union of Unions

Dxuofu.gif


Java for XML Direct Mapping to a Union of Unions

XMLDirectMapping vacationMapping = new XMLDirectMapping();
vacationMapping.setAttributeName("vacation");
XMLUnionField vacationField = new XMLUnionField();
vacationField.setXPath("vacation/text()");
vacationField.addSchemaType(XMLConstants.DATE_QNAME);
vacationField.addSchemaType(XMLConstants.INTEGER_QNAME);
vacationField.addSchemaType(XMLConstants.STRING_QNAME);
vacationField.addSchemaType(XMLConstants.FLOAT_QNAME);
vacationMapping.setField(vacationField);


Eclipselink-logo.gif
Version: 2.2.0 Draft
Other versions...