Skip to main content

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.

Jump to: navigation, search

EclipseLink/Release/2.4.0/JAXB RI Extensions/XML Location

Design Documentation: @XmlLocation

ER 355766

In the current JAXB RI, developed by Sun, there are a series of "proprietary" JAXB extensions that are available to provide advanced JAXB functionality outside of the JAXB spec (these extension classes reside in the com.sun.xml.bind package).

The @XmlLocation annotation is one of these extensions - it allows the user to specify a property on the JAXB object that will be updated (upon unmarshalling) with that object's XML location information (i.e. the line number, column number, and system ID that points to this object's location in the XML input).

This document will outline the design for an EclipseLink equivalent to this extension.


Requirements

  • Deliver an @XmlLocation annotation in the EclipseLink library that will provide the same functionality as the Sun extension.
    • Line number
    • Column number
    • System ID, if applicable
  • Have zero impact on memory/performance if the user is not using @XmlLocation.


Behaviour

  • If an object containing an @XmlLocation property is unmarshalled, a Locator object will be created and set on the property, containing the XML location info.
  • If an object with a populated Locator is marshalled to XML, the Locator information will appear in the resultant XML.
  • If XML is unmarshalled that contains actual Locator information (e.g. the example above), that information is not read in like a normal mapping; upon unmarshalling the Locator property will be set to reflect the current XML location.
  • If an @XmlLocation property is also marked as @XmlTransient, then Locator information will NOT appear in marshalled XML.


Configuration

In order to use @XmlLocation, the user must first have a property on their Java object (either a field or get/set pair) of type org.xml.sax.Locator. The user can then specify that this property should be used to track XML location by using either EclipseLink Annotations or XML Bindings.


Annotations

package org.eclipse.persistence.oxm.annotations;
 
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
 
@Target({METHOD, FIELD}) 
@Retention(RUNTIME)
public @interface XmlLocation {}


XML Bindings

eclipselink_oxm_2_4.xsd:

...
    <xs:element name="xml-transient" substitutionGroup="java-attribute">
        <xs:complexType>
            <xs:complexContent>
                <xs:extension base="java-attribute">
                    <xs:attribute name="xml-location" type="xs:boolean" default="false" />
                </xs:extension>
            </xs:complexContent>
        </xs:complexType>
    </xs:element>
...
    <xs:element name="xml-element" substitutionGroup="java-attribute">
        <xs:complexType>
            <xs:complexContent>
                <xs:extension base="java-attribute">
                    ...
                    <xs:attribute name="xml-location" type="xs:boolean" default="false" />
                </xs:extension>
            </xs:complexContent>
        </xs:complexType>
    </xs:element>
...


Config Options

The @XmlLocation feature does not expose any configuration options, it is merely a tagging annotation that indicates the property to be used for tracking XML location information.


Example

Annotations:

import javax.xml.bind.annotation.*;
 
import org.eclipse.persistence.oxm.annotations.XmlLocation;
 
import org.xml.sax.Locator;
 
@XmlRootElement
public class Customer {
 
   public int id;
 
   public String name;
 
   @XmlLocation
   public Locator locator;
 
    @Override
    public String toString() {
        String loc = " noLoc";
        if (locator != null) {
            loc = " L" + locator.getLineNumber() + 
                  " C" + locator.getColumnNumber() +
                  " " + locator.getSystemId();
        }
 
        return "Customer(" + name + ")" + loc;
    }
 
}

Equivalent XML Bindings:

...
    <java-types>
        <java-type name="Customer">
            <xml-root-element />
            <java-attributes>
                <xml-element java-attribute="id" />
                <xml-element java-attribute="name" />
                <xml-element java-attribute="locator" xml-location="true" />
            </java-attributes>
        </java-type>
    </java-types>
...

Example XML Instance Document:

<?xml version="1.0" encoding="UTF-8"?>
<customer>
   <id>1872874</id>
   <name>Bob Smith</name>
</customer>

Unmarshalling and Marshalling:

File f = new File("D:/temp/instance.xml"));
Customer c = jaxbContext.createUnmarshaller().unmarshal(f);
 
System.out.println(c);
 
   // Output:
   // Customer(Bob Smith) L15 C35 file:/D:/temp/instance.xml
 
jaxbContext.createMarshaller().marshal(c, System.out);
 
   // Output:
   // <?xml version="1.0" encoding="UTF-8"?>
   // <customer>
   //   <id>1872874</id>
   //   <name>Bob Smith</name>
   //   <locator>
   //      <columnNumber>35</columnNumber>
   //      <lineNumber>15</lineNumber>
   //      <systemId>file:/D:/temp/instance.xml</systemId>
   //   </locator>
   // </customer>


Design

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.


Document History

Date Author Version Description & Notes
110926 Rick Barkhouse 1.00 : First draft

Back to the top