Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
Difference between revisions of "EclipseLink/DesignDocs/317962/Phase2.1"
(→xml-read-transformer) |
(→@XmlReadTransformer) |
||
(27 intermediate revisions by the same user not shown) | |||
Line 69: | Line 69: | ||
=== Java Metadata === | === Java Metadata === | ||
− | + | ==== @XmlProperties ==== | |
+ | The following is the proposed source code for the XmlProperties annotation: | ||
+ | <source lang="java"> | ||
+ | @Target({METHOD, FIELD, TYPE}) | ||
+ | @Retention(RUNTIME) | ||
+ | public @interface XmlProperties { | ||
+ | XmlProperty[] value(); | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | ==== @XmlProperty ==== | ||
+ | The following is the proposed source code for the XmlProperty annotation: | ||
+ | <source lang="java"> | ||
+ | @Target({METHOD, FIELD, TYPE}) | ||
+ | @Retention(RUNTIME) | ||
+ | public @interface XmlProperty { | ||
+ | /** | ||
+ | * Property name. | ||
+ | */ | ||
+ | String name(); | ||
+ | |||
+ | /** | ||
+ | * String representation of Property value, | ||
+ | * converted to an instance of valueType. | ||
+ | */ | ||
+ | String value(); | ||
+ | |||
+ | /** | ||
+ | * Property value type. | ||
+ | * The value converted to valueType by ConversionManager. | ||
+ | * If specified must be a simple type that could be handled by ConversionManager: | ||
+ | * numerical, boolean, temporal. | ||
+ | */ | ||
+ | Class valueType() default String.class; | ||
+ | </source> | ||
=== XML Metadata === | === XML Metadata === | ||
+ | ==== xml-properties ==== | ||
+ | The <code>xml-properties</code> metadata tag will be used as a grouping element for one or more <code>xml-property</code> elements. | ||
==== xml-property ==== | ==== xml-property ==== | ||
The <code>xml-property</code> metadata tag will be used to configure a property. | The <code>xml-property</code> metadata tag will be used to configure a property. | ||
Line 111: | Line 147: | ||
<java-type name="org.example.Employee"> | <java-type name="org.example.Employee"> | ||
<xml-properties> | <xml-properties> | ||
− | <xml-property name="identifier" value="101" value-type=" | + | <xml-property name="identifier" value="101" value-type="java.lang.Integer" /> |
− | <xml-property name="isTrue" value="false" value-type=" | + | <xml-property name="isTrue" value="false" value-type="java.lang.Boolean" /> |
</xml-properties> | </xml-properties> | ||
</java-type> | </java-type> | ||
+ | </source> | ||
+ | |||
+ | Setting <code>@XmlProperty</code> on a type via annotations can be accomplished as follows: | ||
+ | ===== org.example.Employee.java ===== | ||
+ | <source lang="java"> | ||
+ | @XmlProperties({@XmlProperty(name="identifier", value="101", valueType=Integer.class), | ||
+ | @XmlProperty(name="isTrue", value="false", valueType=Boolean.class)}) | ||
+ | public class Employee { | ||
+ | ... | ||
+ | } | ||
</source> | </source> | ||
Line 126: | Line 172: | ||
<xml-element java-attribute="myelement"> | <xml-element java-attribute="myelement"> | ||
<xml-properties> | <xml-properties> | ||
− | <xml-property name="isAttribute" value="false" value-type=" | + | <xml-property name="isAttribute" value="false" value-type="java.lang.Boolean" /> |
<xml-property name="comment" value="this is an element" /> | <xml-property name="comment" value="this is an element" /> | ||
</xml-properties> | </xml-properties> | ||
Line 132: | Line 178: | ||
</java-attributes> | </java-attributes> | ||
</java-type> | </java-type> | ||
+ | </source> | ||
+ | |||
+ | Setting <code>@XmlProperty</code> on a property via annotations can be accomplished as follows: | ||
+ | ===== org.example.Employee.java ===== | ||
+ | <source lang="java"> | ||
+ | |||
+ | public class Employee { | ||
+ | |||
+ | @XmlProperties({@XmlProperty(name="isAttribute", value="false", valueType=Boolean.class), | ||
+ | @XmlProperty(name="comment", value="this is an element")} | ||
+ | public String myelement; | ||
+ | } | ||
</source> | </source> | ||
Line 139: | Line 197: | ||
=== Java Metadata === | === Java Metadata === | ||
− | + | ==== @XmlTransformation ==== | |
+ | Here is the proposed source code for the XmlTransformation annotation: | ||
+ | |||
+ | <source lang="java"> | ||
+ | @Target({METHOD, FIELD}) | ||
+ | @Retention(RUNTIME) | ||
+ | public @interface XmlTransformation { | ||
+ | /** | ||
+ | * (Optional) The optional element is a hint as to whether the value | ||
+ | * of the field or property may be null. It is disregarded | ||
+ | * for primitive types, which are considered non-optional. | ||
+ | */ | ||
+ | boolean optional() default true; | ||
+ | </source> | ||
+ | |||
+ | ==== @XmlReadTransformer ==== | ||
+ | Here is the proposed source code for the XmlReadTransformer annotation: | ||
+ | <source lang="java"> | ||
+ | @Target({METHOD, FIELD}) | ||
+ | @Retention(RUNTIME) | ||
+ | public @interface XmlReadTransformer { | ||
+ | |||
+ | /** | ||
+ | * User-defined class that must implement the | ||
+ | * org.eclipse.persistence.mappings.transformers.AttributeTransformer | ||
+ | * interface. The class will be instantiated, its buildAttributeValue will | ||
+ | * be used to create the value to be assigned to the attribute. | ||
+ | * Either transformerClass or method must be specified, but not both. | ||
+ | */ | ||
+ | Class<? extends AttributeTransformer> transformerClass() default AttributeTransformer.class; | ||
+ | |||
+ | /** | ||
+ | * The mapped class must have a method with this name which returns a value | ||
+ | * to be assigned to the attribute (not assigns the value to the attribute). | ||
+ | * Either transformerClass or method must be specified, but not both. | ||
+ | */ | ||
+ | String method() default ""; | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | ==== @XmlWriteTransformer ==== | ||
+ | Here is the proposed source code for the XmlWriteTransformer annotation: | ||
+ | <source lang="java"> | ||
+ | @Target({METHOD, FIELD}) | ||
+ | @Retention(RUNTIME) | ||
+ | public @interface XmlWriteTransformer { | ||
+ | |||
+ | /** | ||
+ | * User-defined class that must implement the | ||
+ | * org.eclipse.persistence.mappings.transformers.FieldTransformer interface. | ||
+ | * The class will be instantiated, its buildFieldValue will be used to | ||
+ | * create the value to be written into XML document. | ||
+ | * Either transformerClass or method must be specified, but not both. | ||
+ | */ | ||
+ | Class<? extends FieldTransformer> transformerClass() default FieldTransformer.class; | ||
+ | |||
+ | /** | ||
+ | * The mapped class must have a method with this name which returns a value | ||
+ | * to be written into the XML document. | ||
+ | * The method may require an XmlTransient annotation to avoid being mapped as | ||
+ | * an XmlElement by default. | ||
+ | * Either transformerClass or method must be specified, but not both. | ||
+ | */ | ||
+ | String method() default ""; | ||
+ | |||
+ | /** | ||
+ | * Specify here the XPath into which the value should be written. | ||
+ | * The only case when this could be skipped is if a single WriteTransformer | ||
+ | * annotates an attribute - the attribute's name will be | ||
+ | * used as an element name. | ||
+ | */ | ||
+ | String xmlPath(); | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | ==== @XmlWriteTransformers ==== | ||
+ | Here is the proposed source code for the XmlWriteTransformers annotation: | ||
+ | |||
+ | <source lang="java"> | ||
+ | @Target({METHOD, FIELD}) | ||
+ | @Retention(RUNTIME) | ||
+ | public @interface XmlWriteTransformers { | ||
+ | |||
+ | XmlWriteTransformer[] value() default {}; | ||
+ | } | ||
+ | </source> | ||
=== XML Metadata === | === XML Metadata === | ||
Line 147: | Line 290: | ||
==== xml-read-transformer ==== | ==== xml-read-transformer ==== | ||
Defines transformation of node(s) value(s) into an attribute value. This corresponds to an attribute transformer on the <code>XmlTransformationMapping</code>. | Defines transformation of node(s) value(s) into an attribute value. This corresponds to an attribute transformer on the <code>XmlTransformationMapping</code>. | ||
− | |||
*<code>method</code> | *<code>method</code> | ||
**The mapped class must have a method with this name which returns a value to be assigned to the attribute. | **The mapped class must have a method with this name which returns a value to be assigned to the attribute. | ||
+ | **The method should have one of the following signatures: | ||
+ | ***myMethod(Record) | ||
+ | ***myMethod(Record, AbstractSession) | ||
+ | ***myMethod(Record, Session) | ||
*<code>transformer-class</code> | *<code>transformer-class</code> | ||
**This is a user-defined class that must implement the <code>org.eclipse.persistence.mappings.transformers.AttributeTransformer</code> interface. The class will be instantiated, and its <code>buildAttributeValue(Record, Object, Session)</code> method will be used to create the value to be assigned to the attribute. | **This is a user-defined class that must implement the <code>org.eclipse.persistence.mappings.transformers.AttributeTransformer</code> interface. The class will be instantiated, and its <code>buildAttributeValue(Record, Object, Session)</code> method will be used to create the value to be assigned to the attribute. | ||
− | Note that either a <code>method</code> or <code>transformer-class</code> should be set, but not both. In the event that both are set | + | Note that either a <code>method</code> or <code>transformer-class</code> should be set, but not both. In the event that both/neither are set an exception will be thrown. |
==== xml-write-transformer ==== | ==== xml-write-transformer ==== | ||
Defines transformation of the attribute value to a single node value. This corresponds to a field transformer on the <code>XmlTransformationMapping</code>. | Defines transformation of the attribute value to a single node value. This corresponds to a field transformer on the <code>XmlTransformationMapping</code>. | ||
+ | *<code>method</code> | ||
+ | **The mapped class must have a method with this name which returns a value to be assigned to the attribute. | ||
+ | **The method should have one of the following signatures: | ||
+ | ***myMethod() | ||
+ | ***myMethod(AbstractSession) | ||
+ | ***myMethod(Session) | ||
+ | *<code>transformer-class</code> | ||
+ | **This is a user-defined class that must implement the <code>org.eclipse.persistence.mappings.transformers.FieldTransformer</code> interface. The class will be instantiated, and its <code>buildFieldValue(Object, String, Session)</code> will be used to create the value to be written into the node. | ||
+ | *<code>xml-path</code> | ||
+ | **Identifies the node into which the value should be written. This should be set in all cases. | ||
+ | |||
+ | Note that either a <code>method</code> or <code>transformer-class</code> should be set, but not both. In the event that both/neither are set an exception will be thrown. | ||
==== XML Schema ==== | ==== XML Schema ==== | ||
Line 196: | Line 354: | ||
<java-type name="org.example.Employee"> | <java-type name="org.example.Employee"> | ||
<java-attributes> | <java-attributes> | ||
− | <xml-transformation java-attribute=" | + | <xml-transformation java-attribute="normalHours" optional="true"> |
+ | <xml-access-methods get-method="getNormalHours" set-method="setNormalHours" /> | ||
<xml-read-transformer transformer-class="org.example.NormalHoursTransformer" /> | <xml-read-transformer transformer-class="org.example.NormalHoursTransformer" /> | ||
<xml-write-transformer xml-path="normal-hours/start-time/text()" transformer-class="org.example.StartTimeTransformer"/> | <xml-write-transformer xml-path="normal-hours/start-time/text()" transformer-class="org.example.StartTimeTransformer"/> | ||
<xml-write-transformer xml-path="normal-hours/end-time/text()" transformer-class="org.example.EndTimeTransformer"/> | <xml-write-transformer xml-path="normal-hours/end-time/text()" transformer-class="org.example.EndTimeTransformer"/> | ||
− | |||
</xml-transformation> | </xml-transformation> | ||
</java-attributes> | </java-attributes> | ||
</java-type> | </java-type> | ||
+ | </source> | ||
+ | |||
+ | Setting the <code>@XmlTransformation</code> via annotations can be accomplished as follows: | ||
+ | ===== org.example.Employee.java ===== | ||
+ | <source lang="java"> | ||
+ | @XmlRootElement(name="employee") | ||
+ | public class Employee { | ||
+ | public String name; | ||
+ | |||
+ | @XmlTransformation | ||
+ | @XmlReadTransformer(transformerClass = NormalHoursTransformer.class) | ||
+ | @XmlWriteTransformers({ | ||
+ | @XmlWriteTransformer(transformerClass = StartTimeTransformer.class, xpath= "normal-hours/start-time/text()"), | ||
+ | @XmlWriteTransformer(transformerClass = EndTimeTransformer.class, xpath="normal-hours/end-time/text()") | ||
+ | }) | ||
+ | public String[] normalHours; | ||
</source> | </source> | ||
Line 226: | Line 400: | ||
=== XML Metadata === | === XML Metadata === | ||
+ | ==== xml-class-extractor ==== | ||
+ | The class extractor can be set via XML metadata via the <code>xml-class-extractor</code> tag. | ||
==== XML Schema ==== | ==== XML Schema ==== | ||
Following is the proposed schema structure for <code>xml-class-extractor</code> - a global element/complex type pair will be added, and a ref will be added to <code>java-type</code>: | Following is the proposed schema structure for <code>xml-class-extractor</code> - a global element/complex type pair will be added, and a ref will be added to <code>java-type</code>: | ||
Line 271: | Line 447: | ||
* returned would be based on the given Record. | * returned would be based on the given Record. | ||
*/ | */ | ||
− | public | + | public Class extractClassFromRow(Record databaseRow, Session session) { |
return Employee.class; | return Employee.class; | ||
} | } | ||
Line 292: | Line 468: | ||
|- | |- | ||
| xml-transformation | | xml-transformation | ||
− | | <code>org.eclipse.persistence.testing.jaxb.externalizedmetadata. | + | | <code>org.eclipse.persistence.testing.jaxb.externalizedmetadata.xmltransformation</code> |
|- | |- | ||
| xml-class-extractor | | xml-class-extractor | ||
| <code>org.eclipse.persistence.testing.jaxb.externalizedmetadata.xmlclassextractor</code> | | <code>org.eclipse.persistence.testing.jaxb.externalizedmetadata.xmlclassextractor</code> | ||
|} | |} | ||
+ | |||
=== Annotations === | === Annotations === | ||
{|{{BMTableStyle}} | {|{{BMTableStyle}} | ||
Line 304: | Line 481: | ||
|- | |- | ||
| XmlProperties | | XmlProperties | ||
− | | | + | | <code>org.eclipse.persistence.testing.jaxb.annotations.xmlproperties</code> |
|- | |- | ||
| XmlProperty | | XmlProperty | ||
− | | | + | | <code>org.eclipse.persstence.testing.jaxb.annotations.xmlproperties</code> |
|- | |- | ||
| XmlTransformation | | XmlTransformation | ||
− | | | + | | <code>org.eclipse.persistence.testing.jaxb.annotations.xmltransformation</code> |
|- | |- | ||
| XmlClassExtractor | | XmlClassExtractor | ||
− | | | + | | <code>org.eclipse.persistence.testing.jaxb.annotations.xmlclassextractor</code> |
+ | |} | ||
+ | |||
+ | == Open Issues == | ||
+ | |||
+ | This section lists open issues. | ||
+ | |||
+ | {|{{BMTableStyle}} | ||
+ | |-{{BMTHStyle}} | ||
+ | ! Issue# | ||
+ | ! Description/Notes | ||
+ | |- | ||
+ | | 1 | ||
+ | | Should the xml-path attribute be required on xml-write-transformer? The only case where one isn't required is in the case of a single xml-write-transfomer; in this case we could use the schemaName that is set on the associated Property. | ||
|} | |} | ||
Line 322: | Line 512: | ||
{|{{BMTableStyle}} | {|{{BMTableStyle}} | ||
|-{{BMTHStyle}} | |-{{BMTHStyle}} | ||
− | ! | + | ! Decision# |
! Description/Notes | ! Description/Notes | ||
! Decision | ! Decision |
Latest revision as of 14:21, 17 November 2010
Contents
- 1 Phase 2 - Additional MOXy annotation/xml metadata support
- 1.1 Annotations/XML Metadata
- 1.2 XmlProperties
- 1.3 XmlProperty
- 1.4 XmlTransformation
- 1.5 XmlClassExtractor
- 1.6 Testing
- 1.7 Open Issues
- 1.8 Decisions
Phase 2 - Additional MOXy annotation/xml metadata support
This phase of development involves providing additional MOXy annotations and XML metadata support that will allow configuration similar to that of deployment XML
Annotations/XML Metadata
The following MOXy annotations/XML metadata will be targeted in this phase:
MOXy Annotation | XML Metadata Tag | Package | Type | Field | Method |
---|---|---|---|---|---|
XmlProperties | xml-properties | X | X | X | |
XmlProperty | xml-property | X | X | X | |
XmlTransformation | xml-transformation | X | X | ||
XmlReadTransformer | xml-read-transformer | X | X | ||
XmlWriteTransformer | xml-write-transformer | X | X | ||
XmlClassExtractor | xml-class-extractor | X |
XmlProperties
Purpose
Descriptors and mappings can contain a Map of properties. @XmlProperties
and xml-properties
will be used as a wrapper for one or more property entries. See below for additional information and examples of use.
XmlProperty
Purpose
Provides a means to set a property on a mapping or descriptor. Any annotations set on a property will be completely replaced by XML. Any annotations set on a type will be merged with XML, with XML taking precedence in the case of a conflict.
Java Metadata
@XmlProperties
The following is the proposed source code for the XmlProperties annotation:
@Target({METHOD, FIELD, TYPE}) @Retention(RUNTIME) public @interface XmlProperties { XmlProperty[] value(); }
@XmlProperty
The following is the proposed source code for the XmlProperty annotation:
@Target({METHOD, FIELD, TYPE}) @Retention(RUNTIME) public @interface XmlProperty { /** * Property name. */ String name(); /** * String representation of Property value, * converted to an instance of valueType. */ String value(); /** * Property value type. * The value converted to valueType by ConversionManager. * If specified must be a simple type that could be handled by ConversionManager: * numerical, boolean, temporal. */ Class valueType() default String.class;
XML Metadata
xml-properties
The xml-properties
metadata tag will be used as a grouping element for one or more xml-property
elements.
xml-property
The xml-property
metadata tag will be used to configure a property.
XML Schema
Since there can be multiple properties on a mapping or descriptor, and <xs:all> doesn't allow maxOccurs="unbounded", we will wrap xml-property
in xml-properties
. Following are the proposed schema changes:
<xs:element name="xml-properties" type="xml-properties" /> <xs:complexType name="xml-properties"> <xs:sequence> <xs:element name="xml-property" minOccurs="0" maxOccurs="unbounded" > <xs:complexType> <xs:attribute name="name" type="xs:string" use="required" /> <xs:attribute name="value" type="xs:string" use="required" /> <xs:attribute name="value-type" type="xs:string" default="java.lang.String" /> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType>
An element ref to the new global xml-properties
element will be added to the following:
- java-type
- xml-any-attribute
- xml-attribute
- xml-any-element
- xml-element
- xml-elements
- xml-element-ref
- xml-element-refs
- xml-inverse-reference
- xml-value
- xml-transformation
Example: type-level property
The following example will demonstrate how a type-level property can be applied.
Setting xml-property
on a type via EclipseLink XML metadata can be accomplished as follows:
<java-type name="org.example.Employee"> <xml-properties> <xml-property name="identifier" value="101" value-type="java.lang.Integer" /> <xml-property name="isTrue" value="false" value-type="java.lang.Boolean" /> </xml-properties> </java-type>
Setting @XmlProperty
on a type via annotations can be accomplished as follows:
org.example.Employee.java
@XmlProperties({@XmlProperty(name="identifier", value="101", valueType=Integer.class), @XmlProperty(name="isTrue", value="false", valueType=Boolean.class)}) public class Employee { ... }
Example: property-level property
The following example will demonstrate how a property-level property can be applied.
Setting xml-property
on a property via EclipseLink XML metadata can be accomplished as follows:
<java-type name="org.example.Employee"> <java-attributes> <xml-element java-attribute="myelement"> <xml-properties> <xml-property name="isAttribute" value="false" value-type="java.lang.Boolean" /> <xml-property name="comment" value="this is an element" /> </xml-properties> </xml-element> </java-attributes> </java-type>
Setting @XmlProperty
on a property via annotations can be accomplished as follows:
org.example.Employee.java
public class Employee { @XmlProperties({@XmlProperty(name="isAttribute", value="false", valueType=Boolean.class), @XmlProperty(name="comment", value="this is an element")} public String myelement; }
XmlTransformation
Purpose
Provides a means to configure an org.eclipse.persistence.oxm.mappings.XMLTransformationMapping
. Transformation mappings are used to create a custom mapping where one or more XML nodes can be used to create the object to be stored in a Java class's attribute.
Java Metadata
@XmlTransformation
Here is the proposed source code for the XmlTransformation annotation:
@Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface XmlTransformation { /** * (Optional) The optional element is a hint as to whether the value * of the field or property may be null. It is disregarded * for primitive types, which are considered non-optional. */ boolean optional() default true;
@XmlReadTransformer
Here is the proposed source code for the XmlReadTransformer annotation:
@Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface XmlReadTransformer { /** * User-defined class that must implement the * org.eclipse.persistence.mappings.transformers.AttributeTransformer * interface. The class will be instantiated, its buildAttributeValue will * be used to create the value to be assigned to the attribute. * Either transformerClass or method must be specified, but not both. */ Class<? extends AttributeTransformer> transformerClass() default AttributeTransformer.class; /** * The mapped class must have a method with this name which returns a value * to be assigned to the attribute (not assigns the value to the attribute). * Either transformerClass or method must be specified, but not both. */ String method() default ""; }
@XmlWriteTransformer
Here is the proposed source code for the XmlWriteTransformer annotation:
@Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface XmlWriteTransformer { /** * User-defined class that must implement the * org.eclipse.persistence.mappings.transformers.FieldTransformer interface. * The class will be instantiated, its buildFieldValue will be used to * create the value to be written into XML document. * Either transformerClass or method must be specified, but not both. */ Class<? extends FieldTransformer> transformerClass() default FieldTransformer.class; /** * The mapped class must have a method with this name which returns a value * to be written into the XML document. * The method may require an XmlTransient annotation to avoid being mapped as * an XmlElement by default. * Either transformerClass or method must be specified, but not both. */ String method() default ""; /** * Specify here the XPath into which the value should be written. * The only case when this could be skipped is if a single WriteTransformer * annotates an attribute - the attribute's name will be * used as an element name. */ String xmlPath(); }
@XmlWriteTransformers
Here is the proposed source code for the XmlWriteTransformers annotation:
@Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface XmlWriteTransformers { XmlWriteTransformer[] value() default {}; }
XML Metadata
xml-transformation
The xml-transformation
metadata tag will be used to configure a transformation.
xml-read-transformer
Defines transformation of node(s) value(s) into an attribute value. This corresponds to an attribute transformer on the XmlTransformationMapping
.
method
- The mapped class must have a method with this name which returns a value to be assigned to the attribute.
- The method should have one of the following signatures:
- myMethod(Record)
- myMethod(Record, AbstractSession)
- myMethod(Record, Session)
transformer-class
- This is a user-defined class that must implement the
org.eclipse.persistence.mappings.transformers.AttributeTransformer
interface. The class will be instantiated, and itsbuildAttributeValue(Record, Object, Session)
method will be used to create the value to be assigned to the attribute.
- This is a user-defined class that must implement the
Note that either a method
or transformer-class
should be set, but not both. In the event that both/neither are set an exception will be thrown.
xml-write-transformer
Defines transformation of the attribute value to a single node value. This corresponds to a field transformer on the XmlTransformationMapping
.
method
- The mapped class must have a method with this name which returns a value to be assigned to the attribute.
- The method should have one of the following signatures:
- myMethod()
- myMethod(AbstractSession)
- myMethod(Session)
transformer-class
- This is a user-defined class that must implement the
org.eclipse.persistence.mappings.transformers.FieldTransformer
interface. The class will be instantiated, and itsbuildFieldValue(Object, String, Session)
will be used to create the value to be written into the node.
- This is a user-defined class that must implement the
xml-path
- Identifies the node into which the value should be written. This should be set in all cases.
Note that either a method
or transformer-class
should be set, but not both. In the event that both/neither are set an exception will be thrown.
XML Schema
Following is the proposed schema structure for xml-transformation
:
<xs:element name="xml-transformation" substitutionGroup="java-attribute"> <xs:complexType> <xs:complexContent> <xs:extension base="java-attribute"> <xs:sequence> <xs:element name="xml-access-methods" type="xml-access-methods" minOccurs="0"/> <xs:element ref="xml-properties" minOccurs="0"/> <xs:element name="xml-read-transformer"> <xs:complexType> <xs:attribute name="method" type="xs:string" /> <xs:attribute name="transformer-class" type="xs:string" /> </xs:complexType> </xs:element> <xs:element name="xml-write-transformer" minOccurs="0" maxOccurs="unbounded"> <xs:complexType> <xs:attribute name="method" type="xs:string" /> <xs:attribute name="xml-path" type="xs:string" /> <xs:attribute name="transformer-class" type="xs:string" /> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="optional" type="xs:boolean" default="false"/> </xs:extension> </xs:complexContent> </xs:complexType> </xs:element>
Example
The following example will demonstrate how a transformation can be applied.
Setting xml-transformation
via EclipseLink XML metadata can be accomplished as follows:
<java-type name="org.example.Employee"> <java-attributes> <xml-transformation java-attribute="normalHours" optional="true"> <xml-access-methods get-method="getNormalHours" set-method="setNormalHours" /> <xml-read-transformer transformer-class="org.example.NormalHoursTransformer" /> <xml-write-transformer xml-path="normal-hours/start-time/text()" transformer-class="org.example.StartTimeTransformer"/> <xml-write-transformer xml-path="normal-hours/end-time/text()" transformer-class="org.example.EndTimeTransformer"/> </xml-transformation> </java-attributes> </java-type>
Setting the @XmlTransformation
via annotations can be accomplished as follows:
org.example.Employee.java
@XmlRootElement(name="employee") public class Employee { public String name; @XmlTransformation @XmlReadTransformer(transformerClass = NormalHoursTransformer.class) @XmlWriteTransformers({ @XmlWriteTransformer(transformerClass = StartTimeTransformer.class, xpath= "normal-hours/start-time/text()"), @XmlWriteTransformer(transformerClass = EndTimeTransformer.class, xpath="normal-hours/end-time/text()") }) public String[] normalHours;
XmlClassExtractor
Purpose
A class extractor provides a means for complex inheritance support. A ClassExtractor instance is registered with the descriptor to override the default inheritance mechanism. This allows for a user defined class indicator in place of providing an explicit class indicator field. The instance registered must extend the org.eclipse.persistence.descriptors.ClassExtractor
class and implement the extractClassFromRow(Record, Session)
method; this method is used to determine which class to instantiate when unmarshalling.
Java Metadata
@XmlClassExtractor
The following is the proposed source code for the XmlClassExtractor annotation:
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface XmlClassExtractor { /** * (Required) Defines the name of the class extractor that should be * applied to this entity's descriptor. */ Class value(); }
XML Metadata
xml-class-extractor
The class extractor can be set via XML metadata via the xml-class-extractor
tag.
XML Schema
Following is the proposed schema structure for xml-class-extractor
- a global element/complex type pair will be added, and a ref will be added to java-type
:
<xs:element name="xml-class-extractor" type="xml-class-extractor" /> <xs:complexType name="xml-class-extractor"> <xs:attribute name="class" type="xs:string" use="required"/> </xs:complexType>
Example
The following example will demonstrate how a class extractor can be applied.
Setting xml-class-extractor
via EclipseLink XML metadata can be accomplished as follows:
<java-type name="org.example.Person"> <xml-class-extractor class="org.example.MyClassExtractor" /> </java-type>
Setting the Class Extractor via Annotations would be accomplished as follows: org.example.Person.java
package org.example; @XmlClassExtractor(MyClassExtactor.class) class Person { String name; }
org.example.Employee.java
package org.example; class Employee extends Person { String id; }
org.example.MyClassExtractor.java
package org.example; class MyClassExtractor extends org.eclipse.persistence.descriptors.ClassExtractor { /** * This method simply returns Employee.class. Typically, the class to be * returned would be based on the given Record. */ public Class extractClassFromRow(Record databaseRow, Session session) { return Employee.class; } }
Testing
This section identifies the test package(s) for each feature outlined on this page.
XML Metadata
XML Metadata | Package |
---|---|
xml-properties | org.eclipse.persistence.testing.jaxb.externalizedmetadata.mappings.direct
|
xml-property | org.eclipse.persistence.testing.jaxb.externalizedmetadata.mappings.direct
|
xml-transformation | org.eclipse.persistence.testing.jaxb.externalizedmetadata.xmltransformation
|
xml-class-extractor | org.eclipse.persistence.testing.jaxb.externalizedmetadata.xmlclassextractor
|
Annotations
Annotation | Package |
---|---|
XmlProperties | org.eclipse.persistence.testing.jaxb.annotations.xmlproperties
|
XmlProperty | org.eclipse.persstence.testing.jaxb.annotations.xmlproperties
|
XmlTransformation | org.eclipse.persistence.testing.jaxb.annotations.xmltransformation
|
XmlClassExtractor | org.eclipse.persistence.testing.jaxb.annotations.xmlclassextractor
|
Open Issues
This section lists open issues.
Issue# | Description/Notes |
---|---|
1 | Should the xml-path attribute be required on xml-write-transformer? The only case where one isn't required is in the case of a single xml-write-transfomer; in this case we could use the schemaName that is set on the associated Property. |
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 | xml-class-extraction-method | We will not provide support for setting a class extraction method name on the InheritancePolicy. Please refer to this bug for additional information. | |
2 | xml-transformation | It was decided not to support several properties from the jpa version of transformation as they don't apply to xml-transformation. The following properties were removed: name, mutable, access-type and attribute-type |