Skip to main content

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.

Jump to: navigation, search

EclipseLink/Development/339381

Design Specification: XML Flex Extensions

ER 339381

Currently, EclipseLink MOXy supports the mapping of Java fields and properties to XML. Said another way; in order to map data to XML, the user must have an existing Java field or property to map.

To support multi-tenancy, we will be allowing the user to add additional mappings at runtime. Because these new mappings would not have existing fields / properties on the Java class to map to, we will introduce the concept of "flex extensions", where we can instead map the elements of a Java Map to the desired XML.

Requirements

  1. Users must be able to annotate a field on their Java objects to hold flex extensions
    1. The Java field must be of type Map<String, Object>
  2. Users must be able to specify a field in EclipseLink OXM to hold flex extensions
  3. Users must be able to add new mappings at runtime through EclipseLink OXM
  4. Users should be able to add any type of MOXy mapping as a flex extension

Configuration

Annotations

The user can specify a field on their Java object to hold flex extensions by using the @XmlFlexExtensions annotation.

@Target({METHOD, FIELD}) 
@Retention(RUNTIME)
public @interface XmlFlexExtensions {}

OXM Metadata

To indicate a flex extensions field in EclipseLink OXM, the user can specify an xml-flex-extensions element in their metadata file:

eclipselink_oxm_2_3.xsd:

...
<xs:element name="xml-flex-extensions" substitutionGroup="java-attribute">
   <xs:complexType>
      <xs:complexContent>
         <xs:extension base="java-attribute">
      </xs:complexContent>
   </xs:complexType>
</xs:element>
...

Example

The following domain class specifies an @XmlFlexExtensions attribute to hold additional mappings:

@XmlRootElement
public class Customer {
 
   @XmlAttribute
   private String name;
 
   @XmlFlexExtensions
   private Map<String, Object> extensions;
 
   // getters and setters...
 
}

The class above can be expressed in EclipseLink OXM metadata as follows:

...
<java-types>
   <java-type name="Customer">
      <java-attributes>
         <xml-attribute java-attribute="name" type="java.lang.String" />
         <xml-flex-extensions java-attribute="extensions" />
      </java-attributes>
   </java-type>
...

In an secondary metadata file, we will define additional mappings that we would like to add to Customer:

...
<java-types>
    <java-type name="Customer">
        <java-attributes>
            <xml-element java-attribute="discountCode" name="discount-code"
                type="java.lang.String" />
        </java-attributes>
    </java-type>
</java-types>
...

(Note that there is no special configuration needed for additional mappings; they are specified in the same way as "normal" mappings.)

To set the values for these additional mappings, we will add elements into the extensions Map:

InputStream oxm = classLoader.getResourceAsStream("eclipselink-oxm.xml");
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, oxm);
 
Class[] classes = new Class[] { Customer.class };
JAXBContext ctx = JAXBContext.newInstance(classes, properties);
 
Customer c = new Customer();
c.setName("Dan Swano");
c.getExtensions().put("discountCode", "SIUB372JS7G2IUDS7");
 
ctx.createMarshaller().marshal(e, System.out);

This will produce the following XML:

<customer>
   <name>Dan Swano</name>
   <discount-code>SIUB372JS7G2IUDS7</discount-code>
</customer>

Document History

Date Author Version Description & Notes
110323 Rick Barkhouse 1.00
110329 Rick Barkhouse 1.01 : Input from Doug, added Action Items
110331 Rick Barkhouse 1.02 : Moved open items to Discussion page
110404 Rick Barkhouse 1.03 : Changed to "XML Flex Extensions", modified OXM configuration

Back to the top