|
|
(8 intermediate revisions by 2 users not shown) |
Line 1: |
Line 1: |
− | {{EclipseLink_UserGuide
| + | Please see http://www.eclipse.org/eclipselink/documentation/2.4/moxy/type_level003.htm |
− | |info=y
| + | |
− | |toc=y
| + | |
− | |eclipselink=y
| + | |
− | |eclipselinktype=MOXy
| + | |
− | }}
| + | |
− | = Handling Inheritance =
| + | |
− | | + | |
− | EclipseLink MOXy provides several ways to represent your inheritance hierarchy in XML.
| + | |
− | | + | |
− | | + | |
− | == Using xsi:type ==
| + | |
− | | + | |
− | By default, EclipseLink will use the '''xsi:type''' attribute to represent inheritance in XML.
| + | |
− | | + | |
− | In this example an abstract super class ('''ContactInfo''') contains all types of contact information. '''Address''' and '''PhoneNumber''' are the concrete implementations of '''ContactInfo'''.
| + | |
− | | + | |
− | <source lang="java">
| + | |
− | public abstract class ContactInfo {
| + | |
− | }
| + | |
− | | + | |
− | public class Address extends ContactInfo {
| + | |
− |
| + | |
− | private String street;
| + | |
− | ...
| + | |
− |
| + | |
− | }
| + | |
− | | + | |
− | public class PhoneNumber extends ContactInfo {
| + | |
− | | + | |
− | private String number;
| + | |
− | ...
| + | |
− |
| + | |
− | }
| + | |
− | </source>
| + | |
− | | + | |
− | | + | |
− | Because the '''Customer''' object can have different types of contact information, its property refers to the superclass.
| + | |
− | | + | |
− | <source lang="java">
| + | |
− | @XmlRootElement
| + | |
− | public class Customer {
| + | |
− |
| + | |
− | private ContactInfo contactInfo;
| + | |
− | ...
| + | |
− |
| + | |
− | }
| + | |
− | </source>
| + | |
− | | + | |
− | | + | |
− | Marshalling an example '''Customer''' would produce the following XML:
| + | |
− | | + | |
− | <source lang="xml">
| + | |
− | <customer>
| + | |
− | <contactInfo
| + | |
− | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
| + | |
− | xsi:type="address">
| + | |
− | <street>323 Main Street</street>
| + | |
− | </contactInfo>
| + | |
− | </customer>
| + | |
− | </source>
| + | |
− | | + | |
− | Note the '''xsi:type''' attribute on the '''contactInfo''' element.
| + | |
− | | + | |
− | | + | |
− | == Using Substitution Groups ==
| + | |
− | | + | |
− | Another way to model inheritance in XML is through XML Schema's ''substitution groups'' functionality. Using this approach, the element name itself determines which subclass to use.
| + | |
− | | + | |
− | Taking the same example from above, we will add '''@XmlRootElement''' annotations to each of the subclasses, which will act as the inheritance indicator.
| + | |
− | | + | |
− | <source lang="java">
| + | |
− | public abstract class ContactInfo {
| + | |
− | }
| + | |
− | | + | |
− | @XmlRootElement
| + | |
− | public class Address extends ContactInfo {
| + | |
− |
| + | |
− | private String street;
| + | |
− | ...
| + | |
− |
| + | |
− | }
| + | |
− | | + | |
− | @XmlRootElement
| + | |
− | public class PhoneNumber extends ContactInfo {
| + | |
− | | + | |
− | private String number;
| + | |
− | ...
| + | |
− |
| + | |
− | }
| + | |
− | </source>
| + | |
− | | + | |
− | | + | |
− | Using this approach, marshalling an example '''Customer''' would produce the following XML:
| + | |
− | | + | |
− | <source lang="xml">
| + | |
− | <customer>
| + | |
− | <address>
| + | |
− | <street>323 Main Street</street>
| + | |
− | </address>
| + | |
− | </customer>
| + | |
− | </source>
| + | |
− | | + | |
− | Note that the '''Address''' object is marshalled to the '''address''' element.
| + | |
− | | + | |
− | | + | |
− | == Using @XmlDescriminatorNode / @XmlDescrimintatorValue ==
| + | |
− | | + | |
− | You can also use the MOXY-specific '''@XmlDescriminatorNode''' and '''@XmlDescrimintatorValue''' annotations available in EclipseLink 2.2 to represent inheritance. With this approach, you can select the attribute to represent the subtype.
| + | |
− | | + | |
− | In this example an abstract super class ('''ContactInfo'') contains all types of contact information. The '''ContactInfo''' uses the '''@XmlDescriminatorNode''' annotation to specify the XML attribute ('''classifier''') to indicate the subtype.
| + | |
− | | + | |
− | '''Address''' and '''PhoneNumber''' are the concrete implementations of '''ContactInfo'''. The '''@XmlDescriminatorValue''' is used to override the default type name.
| + | |
− | | + | |
− | <source lang="java">
| + | |
− | package blog.inheritance;
| + | |
− |
| + | |
− | import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorNode;
| + | |
− | import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
| + | |
− | | + | |
− | @XmlDiscriminatorNode("@classifier")
| + | |
− | public abstract class ContactInfo {
| + | |
− |
| + | |
− | }
| + | |
− | | + | |
− | @XmlDiscriminatorValue("address-classifier")
| + | |
− | public class Address extends ContactInfo {
| + | |
− |
| + | |
− | private String street;
| + | |
− |
| + | |
− | public String getStreet() {
| + | |
− | return street;
| + | |
− | }
| + | |
− |
| + | |
− | public void setStreet(String street) {
| + | |
− | this.street = street;
| + | |
− | }
| + | |
− |
| + | |
− | }
| + | |
− | | + | |
− | @XmlDiscriminatorValue("phone-number-classifier")
| + | |
− | public class PhoneNumber extends ContactInfo {
| + | |
− |
| + | |
− | }
| + | |
− | | + | |
− | </source>
| + | |
− |
| + | |
− | | + | |
− | The''' Customer''' object can have different types of contact info set on it, so the property will refer to the super class.
| + | |
− | ===jaxb.properties===
| + | |
− | To use the MOXy JAXB implementation, use a '''jaxb.properties''' file with the '''Address''' class that contains the following:
| + | |
− | <code>
| + | |
− | javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
| + | |
− | </code>
| + | |
− | | + | |
− | In the following example, the descriminator represents inheritance.
| + | |
− | <source lang="java">
| + | |
− |
| + | |
− | package blog.inheritance;
| + | |
− |
| + | |
− | import javax.xml.bind.JAXBContext;
| + | |
− | import javax.xml.bind.Marshaller;
| + | |
− |
| + | |
− | public class Demo {
| + | |
− |
| + | |
− | public static void main(String[] args) throws Exception {
| + | |
− | Customer customer = new Customer();
| + | |
− | Address address = new Address();
| + | |
− | address.setStreet("1 A Street");
| + | |
− | customer.setContactInfo(address);
| + | |
− |
| + | |
− | JAXBContext jc = JAXBContext.newInstance(Customer.class, Address.class, PhoneNumber.class);
| + | |
− |
| + | |
− | Marshaller marshaller = jc.createMarshaller();
| + | |
− | marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
| + | |
− | marshaller.marshal(customer, System.out);
| + | |
− | }
| + | |
− |
| + | |
− | }
| + | |
− | </source>
| + | |
− | | + | |
− | The above sample produces the following XML.
| + | |
− | | + | |
− | <source lang="xml">
| + | |
− | | + | |
− | <customer>
| + | |
− | <contactInfo classifier="address-classifier">
| + | |
− | <street>1 A Street</street>
| + | |
− | </contactInfo>
| + | |
− | </customer>
| + | |
− | | + | |
− | </source>
| + | |
− | | + | |
− | Notice that '''Address''''is marshalled to the '''contactInfo''' element. Its '''classifier''' attribute contains the discriminator node value '''address-classifier'''.
| + | |
− | | + | |
− | | + | |
− | | + | |
− | {{EclipseLink_MOXy
| + | |
− | |next= [[/EclipseLink/UserGuide/MOXy/Simple_Values|Simple Values]]
| + | |
− | |previous= n
| + | |
− | |up= [[EclipseLink/UserGuide/MOXy|MOXy User Guide]]
| + | |
− | |version=2.2.0 DRAFT}}
| + | |