Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
EclipseLink/DesignDocs/317962/Phase3
Contents
- 1 Phase 3 - MOXy Equivalents of Relevant JPA Annotations
- 1.1 Annotations/XML Metadata
- 1.2 Inheritance Support
- 1.3 Relationship Mapping Support
- 1.4 Event Handling Support
- 1.5 Testing
- 1.6 Open Issues
- 1.7 Decisions
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 | ||
N/A | XmlAfterUnmarshal | xml-after-unmarshal | X (XML) | X (@) | ||
N/A | XmlBeforeUnmarshal | xml-before-unmarshal | X (XML) | X (@) | ||
N/A | XmlAfterMarshal | xml-after-marshal | X (XML) | X (@) | ||
N/A | XmlBeforeMarshal | xml-before-marshal | X (XML) | 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("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("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 { String value(); }
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
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>
Event Handling Support
We will provide event handling support, based loosely on the JPA pre/post event concept, in the form of before/after marshal/unmarshal events.
XmlBeforeMarshal
Purpose
Presence of this annotation indicates the method that is to be called prior to a marshal operation.
Java Metadata
package org.eclipse.persistence.oxm.annotations; @Target({METHOD}) @Retention(RUNTIME) public @interface XmlBeforeMarshal {}
XML Metadata
xml-before-marshal
will be used to indicate the method that is to be called prior to a marshal operation.
XmlAfterMarshal
Purpose
Presence of this annotation indicates the method that is to be called subsequent to a marshal operation.
Java Metadata
package org.eclipse.persistence.oxm.annotations; @Target({METHOD}) @Retention(RUNTIME) public @interface XmlAfterMarshal {}
XML Metadata
xml-after-marshal
will be used to indicate the method that is to be called subsequent to a marshal operation.
XmlBeforeUnmarshal
Purpose
Presence of this annotation indicates the method that is to be called prior to an unmarshal operation.
Java Metadata
package org.eclipse.persistence.oxm.annotations; @Target({METHOD}) @Retention(RUNTIME) public @interface XmlBeforeUnmarshal {}
XML Metadata
xml-before-unmarshal
will be used to indicate the method that is to be called prior to an unmarshal operation in.
XmlAfterUnmarshal
Purpose
Presence of this annotation indicates the method that is to be called subsequent to an unmarshal operation.
Java Metadata
package org.eclipse.persistence.oxm.annotations; @Target({METHOD}) @Retention(RUNTIME) public @interface XmlAfterUnmarshal {}
XML Metadata
xml-after-unmarshal
will be used to indicate the method that is to be called subsequent to an unmarshal operation.
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 |
---|---|
|
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 |