Difference between revisions of "EclipseLink/DesignDocs/317962/Phase3"

From Eclipsepedia

Jump to: navigation, search
(XmlJoinNode)
(Example)
Line 145: Line 145:
 
import javax.xml.bind.annotation.XmlRootElement;
 
import javax.xml.bind.annotation.XmlRootElement;
  
@XmlRootElement("vehicle-data")
+
@XmlRootElement(name="vehicle-data")
 
@XmlDiscriminatorNode("@vtype")
 
@XmlDiscriminatorNode("@vtype")
 
@XmlDiscriminatorValue("vehicle")
 
@XmlDiscriminatorValue("vehicle")
Line 163: Line 163:
 
import javax.xml.bind.annotation.XmlRootElement;
 
import javax.xml.bind.annotation.XmlRootElement;
  
@XmlRootElement("car-data")
+
@XmlRootElement(name="car-data")
 
@XmlDiscriminatorValue("car")
 
@XmlDiscriminatorValue("car")
 
class Car {
 
class Car {

Revision as of 10:38, 24 August 2010

Contents

Phase 3 - MOXy Equivalents of Relevant JPA Annotations

This phase of development involves providing additional MOXy annotations and XML metadata support equivalent to that of any relevant JPA annotations.

Annotations/XML Metadata

The following MOXy annotations/XML metadata will be targeted in this phase:

JPA Annotation MOXy Annotation XML Metadata Tag Package Type Field Method
DiscriminatorColumn XmlDiscriminatorNode xml-discriminator-node X
DiscriminatorValue XmlDiscriminatorValue xml-discriminator-value X
JoinColumn XmlJoinNode xml-join-node X X
JoinColumns XmlJoinNodes xml-join-nodes X X
XmlKey xml-key X X

Inheritance Support

XmlDiscriminatorNode

Purpose

Provide a means to set the class indicator field name when using inheritance.

Java Metadata

package org.eclipse.persistence.oxm.annotations;
 
@Target({TYPE}) 
@Retention(RUNTIME)
public @interface XmlDiscriminatorNode {
    String value();
}

XML Metadata

xml-discriminator-node

The xml-discriminator-node metadata tag will be used to set the class indicator field name when using inheritance. The value will be in the form of an XPath to an attribute, i.e. @xsi:type.

eclipselink-oxm.xml snippet

<java-type name="org.example.Vehicle" xml-discriminator-node="@vtype">

XmlDiscriminatorValue

Purpose

Provide a means to set a class indicator when using inheritance.

Java Metadata

package org.eclipse.persistence.oxm.annotations;
 
@Target({TYPE}) 
@Retention(RUNTIME)
public @interface XmlDiscriminatorValue {
    String value();
}

XML Metadata

xml-discriminator-value

The xml-discriminator-value metadata tag will be used to set a class indicator when using inheritance.

eclipselink-oxm.xml snippet

<java-type name="org.example.Car" xml-discriminator-value="car">

XML Schema

Following is the proposed XSD change necessary to provide support for inheritance. The following attributes will be added to java-type:

<xs:attribute name="xml-discriminator-node" type="xs:string" />
<xs:attribute name="xml-discriminator-value" type="xs:string" />

Example

The following example will demonstrate how inheritance can be configured.

Using the xml-discriminator-node and xml-discriminator-value EclipseLink XML metadata tags to set the class indicator field name and class indicator(s) can be accomplished as follows:

<java-types>
    <java-type name="org.example.Vehicle" xml-discriminator-node="@vtype" xml-discriminator-value="vehicle">
        <xml-root-element name="vehicle-data" />
        <java-attributes>
            <xml-element java-attribute="topSpeed" name="top-speed" />
        </java-attributes>
    </java-type>
    <java-type name="org.example.Car" xml-discriminator-value="car">
        <xml-root-element name="car-data" /> 
        <java-attributes>
            <xml-element java-attribute="numberOfDoors" name="number-of-doors" />
            <xml-element java-attribute="milesPerGallon" name="miles-per-gallon" />
        </java-attributes>
    </java-type>
</java-types>

Setting the class indicator field name and class indicator(s) via Annotations would be accomplished as follows:

org.example.Vehicle.java

package org.example;
 
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorNode;
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
 
@XmlRootElement(name="vehicle-data")
@XmlDiscriminatorNode("@vtype")
@XmlDiscriminatorValue("vehicle")
class Vehicle {
    public String model;
    public String manufacturer;
    @XmlElement(name="top-speed")
    public int topSpeed;
}

org.example.Car.java

package org.example;
 
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
 
@XmlRootElement(name="car-data")
@XmlDiscriminatorValue("car")
class Car {
    @XmlElement(name="number-of-doors")
    public int numberOfDoors;
    @XmlElement(name="miles-per-gallon")
    public int milesPerGallon;
}

Sample XML Instance Document

<vehicle-data vtype="car">
    <model>Mustang GT</model>
    <manufacturer>Ford</manufacturer>
    <top-speed>354</top-speed>
    <number-of-doors>2</number-of-doors>
    <miles-per-gallon>26</miles-per-gallon>
</vehicle-data>

Relationship Mapping Support

We currently support relationship mappings through @ID/@IDREF annotations, and xml-id/xml-idref metadata tags. There are a number of limitations when using these:

  • ID property must be of type String
  • Target class of an IDREF must have an ID property
  • JAXB expects that a given class can have at most one ID property, so composite keys cannot be configured w/o violating the JAXB spec.

Use of XmlJoinNode(s) will allow one or more properties in the target class to be used as the key for a relationship mapping.

XmlKey

Purpose

One or more XmlKey annotations can be used to declare the primary keys in a given class. For a single key, either XmlID or XmlKey can be used. For composite primary keys, multiple XmlKey annotations can be used, or a single XmlID can be combined with one or more XmlKey annotations.

Java Metadata

package org.eclipse.persistence.oxm.annotations;
 
@Target({METHOD, FIELD}) 
@Retention(RUNTIME)
public @interface XmlKey {}

XML Metadata

xml-key

xml-key will be used to identify one or more primary keys on a given type. Any XmlKey annotations will be combined with those set via xml metadata. To unset a property annotated with XmlKey, the property must be present in XML without xml-key="true".

eclipselink-oxm.xml snippet (org.example.Address type)

<xml-element java-attribute="empId" xml-key="true" />
<xml-element java-attribute="type" xml-key="true" />

XML Schema

Following is the proposed XSD change necessary to provide additional relationship mapping support. The following attribute will be added to xml-attribute and xml-element:

<xs:attribute name="xml-key" type="xs:boolean" default="false" />

XmlJoinNodes

Purpose

XmlJoinNodes is used to group one or more XmlJoinNode entries. Please see XmlJoinNode below for examples of use.

Java Metadata

package org.eclipse.persistence.oxm.annotations;
 
@Target({METHOD, FIELD}) 
@Retention(RUNTIME)
public @interface XmlJoinNodes {
    XmlJoinNode[] value();
}

XML Metadata

xml-join-nodes

xml-join-nodes will be used to group one or more xml-join-node entries. Please see xml-join-node below for additional information and examples of use.

XmlJoinNode

Purpose

XmlJoinNode is used to identify a source to target primary key field association. For composite keys, XmlJoinNodes can be used. To unset a property annotated with XmlJoinNodes, the property must be present in XML without an xml-join-nodes element.

Java Metadata

package org.eclipse.persistence.oxm.annotations;
 
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface XmlJoinNode {
    String xmlPath();
    String referencedXmlPath();
}

XML Metadata

xml-join-node

xml-join-node is used to identify a source to target primary key field association. For composite keys, xml-join-nodes can be used. To unset a property annotated with XmlJoinNode, the property must be present in XML without any xml-join-node elements.

eclipselink-oxm.xml snippet (org.example.Employee type)

<xml-element java-attribute="address">
    <xml-join-nodes>
        <xml-join-node xml-path="address/@emp-id" referenced-xml-path="empId" />
        <xml-join-node xml-path="address/@type" referenced-xml-path="type" />
    </xml-join-nodes>
</xml-element>

XML Schema

Following is the proposed XSD change necessary to provide additional relationship mapping support:

<xs:element name="xml-join-nodes" type="xml-join-nodes" />
<xs:complexType name="xml-join-nodes">
    <xs:sequence>
        <xs:element name="xml-join-node" minOccurs="0" maxOccurs="unbounded" >
            <xs:complexType>
                <xs:attribute name="xml-path" type="xs:string" use="required" />
                <xs:attribute name="referenced-xml-path" type="xs:string" use="required" />
            </xs:complexType>
        </xs:element>
    </xs:sequence>
</xs:complexType>

Example

The following example will demonstrate how a relationship mapping with composite keys can be configured.

Using the xml-join-nodes and xml-join-node EclipseLink XML metadata tags to configure a relationship mapping can be accomplished as follows:

<java-types>
    <java-type name="org.example.Employee">
        <xml-root-element name="employee-data" />
        <java-attributes>
            <xml-attribute java-attribute="id" />
            <xml-element java-attribute="address">
                <xml-join-nodes>
                    <xml-join-node xml-path="address/@emp-id" referenced-xml-path="empId" />
                    <xml-join-node xml-path="address/@type" referenced-xml-path="type" />
                </xml-join-nodes>
            </xml-element>
        </java-attributes>
    </java-type>
    <java-type name="org.example.Address">
        <xml-root-element name="address-data" /> 
        <java-attributes>
            <xml-element java-attribute="empId" xml-key="true" />
            <xml-element java-attribute="type" xml-key="true" />
        </java-attributes>
    </java-type>
</java-types>

Setting up a relationship mapping via Annotations would be accomplished as follows:

org.example.Employee.java

package org.example;
 
import org.eclipse.persistence.oxm.annotations.XmlJoinNode;
import org.eclipse.persistence.oxm.annotations.XmlJoinNodes;
 
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
 
@XmlRootElement("employee-data")
class Employee {
    @XmlAttribute
    public String id;
 
    @XmlJoinNodes({
        @XmlJoinNode(xmlPath="address/@emp-id" referencedXmlPath="empId"),
        @XmlJoinNode(xmlPath="address/@type" referencedXmlPath="type")
    })
    public Address address;
}

org.example.Address.java

package org.example;
 
import org.eclipse.persistence.oxm.annotations.XmlKey;
 
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
 
@XmlRootElement("address-data")
class Address {
    @XmlElement
    @XmlKey
    public String empId;
 
    @XmlElement
    @XmlKey
    public String type;
 
    public String street;
    public String city;
    public String postal;
}

Sample XML Instance Document

<root>
    <employee-data id="100">
        <address emp-id="100" type="HOME" />
    </employee-data>
    <address-data>
        <empId>100</empId>
        <type>HOME</type>
        <street>99 Some St.</street>
        <city>Kanata</city>
        <postal>K0A3m0</postal>
    </address-data>
    <address-data>
        <empId>100</empId>
        <type>WORK</type>
        <street>45 O'Connor St., Suite 400</street>
        <city>Ottawa</city>
        <postal>K1P1A4</postal>
    </address-data>
    <address-data>
        <empId>200</empId>
        <type>HOME</type>
        <street>1 Anystreet Rd.</street>
        <city>Ottawa</city>
        <postal>K4P1A2</postal>
    </address-data>
</root>

Testing

This section identifies the test package(s) for each feature outlined on this page.

XML Metadata

XML Metadata Package
xml-discriminator-node org.eclipse.persistence.testing.jaxb.externalizedmetadata.inheritance
xml-discriminator-value org.eclipse.persistence.testing.jaxb.externalizedmetadata.inheritance

Annotations

Annotation Package

Planning

This section lists feature delivery estimates.

Name Estimate (days) Estimate Complete Actual Complete
xml-discriminator-node            2    
xml-discriminator-value            1    
XmlDiscriminatorNode            1    
XmlDiscriminatorValue            1    
xml-key            2    
xml-join-node(s)            3    
XmlKey            2    
XmlJoinNode            2    
XmlJoinNodes            1    

Open Issues

This section lists open issues.

Issue# Description/Notes
1

Decisions

This section lists decisions made. These are intended to document the resolution of open issues or constraints added to the project that are important.

Decision# Description/Notes Decision
1