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

Difference between revisions of "EclipseLink/Release/2.4.0/JAXB RI Extensions/XML Location"

 
(78 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
<div style="margin:5px;float:right;border:1px solid #000000;padding:5px">__TOC__</div>
 
<div style="margin:5px;float:right;border:1px solid #000000;padding:5px">__TOC__</div>
  
= Design Documentation: @XmlLocation =
+
= XML Location =
  
[http://bugs.eclipse.org/355766 ER 355766]
+
In the current JAXB RI, developed by Sun, there is a series of "proprietary" JAXB extensions which provide advanced functionality outside of the JAXB specification (these extension classes and properties reside in the '''com.sun.xml.bind''' package).
  
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).
  
The '''@XmlLocation''' annotation is one of these extensions - it allows the user to specify a field 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.
+
= 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.
  
= Requirements =
+
Not all unmarshal sources will be able to provide XML location information.  For example, unmarshalling from a '''File''' would be able to give you line, column and system ID (filename); system ID is not available when unmarshalling from an '''InputStream'''; unmarshalling from a '''Node''' would give you no XML location information at all.
  
* Deliver an '''@XmlLocation''' annotation in the EclipseLink library that will provide the same functionality as the Sun extension.
+
 
** Line number
+
{|{{BMTableStyle}}
** Column number
+
|-{{BMTHStyle}}
** System ID, if applicable
+
! Unmarshal Source
* Have zero impact on memory/performance if the user is not using '''@XmlLocation'''.
+
! Line #
 +
! Column #
 +
! System ID
 +
|-
 +
| java.io.File
 +
| [[Image:Ok_green.gif]]
 +
| [[Image:Ok_green.gif]]
 +
| [[Image:Ok_green.gif]]
 +
|-
 +
| java.io.InputStream
 +
| [[Image:Ok_green.gif]]
 +
| [[Image:Ok_green.gif]]
 +
| [[Image:Delete.gif]]
 +
|-
 +
| java.io.Reader
 +
| [[Image:Ok_green.gif]]
 +
| [[Image:Ok_green.gif]]
 +
| [[Image:Delete.gif]]
 +
|-
 +
| java.net.URL
 +
| [[Image:Ok_green.gif]]
 +
| [[Image:Ok_green.gif]]
 +
| [[Image:Ok_green.gif]]
 +
|-
 +
| javax.xml.stream.XMLEventReader
 +
| [[Image:Ok_green.gif]]
 +
| [[Image:Ok_green.gif]]
 +
| [[Image:Delete.gif]]
 +
|-
 +
| javax.xml.stream.XMLStreamReader
 +
| [[Image:Ok_green.gif]]
 +
| [[Image:Ok_green.gif]]
 +
| [[Image:Delete.gif]]
 +
|-
 +
| org.w3c.dom.Node
 +
| [[Image:Delete.gif]]
 +
| [[Image:Delete.gif]]
 +
| [[Image:Delete.gif]]
 +
|-
 +
| org.xml.sax.InputSource
 +
| [[Image:Ok_green.gif]]
 +
| [[Image:Ok_green.gif]]
 +
| [[Image:Delete.gif]]
 +
|}<br>
  
  
Line 25: Line 68:
 
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  
 
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.
 
'''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.
 +
 +
Properties marked with '''@XmlLocation''' should also be marked as '''@XmlTransient''', as the location information is not relevant in a marshalled document.
 +
 +
EclipseLink will also recognize the Sun versions of this annotation ('''com.sun.xml.bind.annotation.XmlLocation''' and '''com.sun.xml.internal.bind.annotation.XmlLocation''').
  
  
 
== Annotations ==
 
== Annotations ==
  
<div style="width:900px">
+
<div style="width:800px">
 
<source lang="java">
 
<source lang="java">
 
package org.eclipse.persistence.oxm.annotations;
 
package org.eclipse.persistence.oxm.annotations;
Line 47: Line 94:
  
  
== OXM Metadata ==
+
== XML Bindings ==
  
<div style="width:900px">
+
eclipselink_oxm_2_4.xsd:
<source lang="java">
+
<div style="width:800px">
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.</source>
+
<source lang="xml">
 +
...
 +
    <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>
 +
...
 +
</source>
 
</div>
 
</div>
  
  
== Example ==
+
== Config Options ==
  
<div style="width:900px">
+
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.
 +
 
 +
 
 +
= Examples =
 +
 
 +
The following examples refer to this XML instance document:
 +
 
 +
<div style="width:800px">
 +
<source lang="xml">
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<customer>
 +
  <id>1872874</id>
 +
  <name>Bob Smith</name>
 +
</customer>
 +
</source>
 +
</div>
 +
 
 +
 
 +
== Example 1 ==
 +
 
 +
This example shows the most basic use case;  the '''Locator''' field is annotated with '''@XmlLocation''' (or, in XML Bindings, the "xml-transient" element has its "xml-location" attribute set to "true").
 +
 
 +
Annotations:
 +
<div style="width:800px">
 
<source lang="java">
 
<source lang="java">
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.</source>
+
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
 +
  @XmlTransient
 +
  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;
 +
    }
 +
 
 +
}
 +
</source>
 
</div>
 
</div>
  
 +
Equivalent XML Bindings:
 +
<div style="width:800px">
 +
<source lang="xml">
 +
...
 +
    <java-types>
 +
        <java-type name="Customer">
 +
            <xml-root-element />
 +
            <java-attributes>
 +
                <xml-element java-attribute="id" />
 +
                <xml-element java-attribute="name" />
 +
                <xml-transient java-attribute="locator" xml-location="true" />
 +
            </java-attributes>
 +
        </java-type>
 +
    </java-types>
 +
...
 +
</source>
 +
</div>
  
== Config Options ==
+
When a '''Customer''' is unmarshalled, the '''Locator''' field is automatically set to contain the XML location information for that object.
  
 +
<div style="width:800px">
 +
<source lang="java">
 +
File f = new File("D:/temp/instance.xml"));
 +
Customer c = jaxbContext.createUnmarshaller().unmarshal(f);
  
=== Specifying Alternate Accessor Methods ===
+
System.out.println(c);
  
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.
+
  // Output:
 +
  // Customer(Bob Smith) L2 C1 file:/D:/temp/instance.xml
  
 +
</source>
 +
</div>
  
=== Schema Generation Options ===
 
  
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.
+
== Example 2 ==
  
 +
Accessor methods can be annotated instead of the actual Java field:
  
=== XmlAccessorType and XmlTransient ===
+
<div style="width:800px">
 +
<source lang="java">
 +
import javax.xml.bind.annotation.*;
  
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.
+
import org.eclipse.persistence.oxm.annotations.XmlLocation;
  
 +
import org.xml.sax.Locator;
  
= Design =
+
@XmlRootElement
 +
public class Customer {
  
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.
+
  private int id;
  
 +
  private String name;
  
= Document History =
+
  private Locator locator;
{|{{BMTableStyle}}
+
 
|-{{BMTHStyle}}
+
  @XmlLocation
! Date
+
  @XmlTransient
! Author
+
  public Locator getLocator() {
! Version Description & Notes
+
      return this.locator;
|-
+
  }
| 110926
+
 
| Rick Barkhouse
+
  public void setLocator(Locator l) {
| 1.00 : First draft
+
      this.locator = l;
|}<br>
+
  }
 +
 
 +
  ...
 +
 
 +
}
 +
</source>
 +
</div>

Latest revision as of 11:36, 18 June 2012

XML Location

In the current JAXB RI, developed by Sun, there is a series of "proprietary" JAXB extensions which provide advanced functionality outside of the JAXB specification (these extension classes and properties 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).


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.

Not all unmarshal sources will be able to provide XML location information. For example, unmarshalling from a File would be able to give you line, column and system ID (filename); system ID is not available when unmarshalling from an InputStream; unmarshalling from a Node would give you no XML location information at all.


Unmarshal Source Line # Column # System ID
java.io.File Ok green.gif Ok green.gif Ok green.gif
java.io.InputStream Ok green.gif Ok green.gif Delete.gif
java.io.Reader Ok green.gif Ok green.gif Delete.gif
java.net.URL Ok green.gif Ok green.gif Ok green.gif
javax.xml.stream.XMLEventReader Ok green.gif Ok green.gif Delete.gif
javax.xml.stream.XMLStreamReader Ok green.gif Ok green.gif Delete.gif
org.w3c.dom.Node Delete.gif Delete.gif Delete.gif
org.xml.sax.InputSource Ok green.gif Ok green.gif Delete.gif


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.

Properties marked with @XmlLocation should also be marked as @XmlTransient, as the location information is not relevant in a marshalled document.

EclipseLink will also recognize the Sun versions of this annotation (com.sun.xml.bind.annotation.XmlLocation and com.sun.xml.internal.bind.annotation.XmlLocation).


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.


Examples

The following examples refer to this XML instance document:

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


Example 1

This example shows the most basic use case; the Locator field is annotated with @XmlLocation (or, in XML Bindings, the "xml-transient" element has its "xml-location" attribute set to "true").

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
   @XmlTransient
   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-transient java-attribute="locator" xml-location="true" />
            </java-attributes>
        </java-type>
    </java-types>
...

When a Customer is unmarshalled, the Locator field is automatically set to contain the XML location information for that object.

File f = new File("D:/temp/instance.xml"));
Customer c = jaxbContext.createUnmarshaller().unmarshal(f);
 
System.out.println(c);
 
   // Output:
   // Customer(Bob Smith) L2 C1 file:/D:/temp/instance.xml


Example 2

Accessor methods can be annotated instead of the actual Java field:

import javax.xml.bind.annotation.*;
 
import org.eclipse.persistence.oxm.annotations.XmlLocation;
 
import org.xml.sax.Locator;
 
@XmlRootElement
public class Customer {
 
   private int id;
 
   private String name;
 
   private Locator locator;
 
   @XmlLocation
   @XmlTransient
   public Locator getLocator() {
      return this.locator;
   }
 
   public void setLocator(Locator l) {
      this.locator = l;
   }
 
   ...
 
}

Back to the top