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/Development/2.1/DynamicMOXy/296967/BootstrapFromXSD"

(Generating a DynamicProject with XJC)
 
(47 intermediate revisions by the same user not shown)
Line 17: Line 17:
 
# An <tt>org.eclipse.persistence.oxm.XMLContext</tt> is then created from the Dynamic Project, and a <tt>DynamicJAXBContext</tt> is returned backed by this <tt>XMLContext</tt>.
 
# An <tt>org.eclipse.persistence.oxm.XMLContext</tt> is then created from the Dynamic Project, and a <tt>DynamicJAXBContext</tt> is returned backed by this <tt>XMLContext</tt>.
  
<br><br>
+
<br>
  
 
== Development Phases ==
 
== Development Phases ==
Line 31: Line 31:
 
! Field  
 
! Field  
 
! Method
 
! Method
! Schema Representation
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlNs.html XmlNs]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlNs.html XmlNs]  
Line 39: Line 38:
 
| align="center" | &nbsp;  
 
| align="center" | &nbsp;  
 
| align="center" | &nbsp;
 
| align="center" | &nbsp;
| align="center" | N/A ?
 
Only used for package-info.java
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlSchema.html XmlSchema]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlSchema.html XmlSchema]  
Line 48: Line 45:
 
| align="center" | &nbsp;  
 
| align="center" | &nbsp;  
 
| align="center" | &nbsp;
 
| align="center" | &nbsp;
| align="center" | N/A ?
 
Only used for package-info.java
 
 
<source lang="DOS">
 
@javax.xml.bind.annotation.XmlSchema (
 
  namespace = "http://www.example.com/MYPO1"
 
)
 
 
<schema
 
  xmlns=...
 
  xmlns:po=....
 
  targetNamespace="http://www.example.com/MYPO1">
 
 
 
@javax.xml.bind.annotation.XmlSchema (
 
  xmlns = {
 
      @javax.xml.bind.annotation.XmlNs(prefix = "po",
 
        namespaceURI="http://www.example.com/myPO1"),
 
      @javax.xml.bind.annotation.XmlNs(prefix="xs",
 
        namespaceURI="http://www.w3.org/2001/XMLSchema")
 
  )
 
)
 
 
<schema
 
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
 
  xmlns:po="http://www.example.com/PO1"
 
  targetNamespace="http://www.example.com/PO1">
 
 
 
@javax.xml.bind.annotation.XmlSchema (
 
  elementFormDefault=XmlNsForm.UNQUALIFIED
 
  ...
 
)
 
 
<schema
 
  xmlns="http://www.w3.org/2001/XMLSchema"
 
  xmlns:po="http://www.example.com/PO1"
 
  elementFormDefault="unqualified">
 
</source>
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlSeeAlso.html XmlSeeAlso]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlSeeAlso.html XmlSeeAlso]  
Line 94: Line 52:
 
| align="center" | &nbsp;  
 
| align="center" | &nbsp;  
 
| align="center" | &nbsp;
 
| align="center" | &nbsp;
| align="center" | N/A
 
XmlSeeAlso will be generated if there
 
is an inheritance relationship in the schema's
 
complex types.
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlTransient.html XmlTransient]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlTransient.html XmlTransient]  
Line 105: Line 59:
 
| align="center" | X  
 
| align="center" | X  
 
| align="center" | X
 
| align="center" | X
| align="center" | N/A
 
 
|}
 
|}
  
<br><br>
+
<br>
 +
 
 +
The following example schema demonstrates how these annotations will be derived from the schema:
 +
 
 +
==== Example Schema ====
 +
 
 +
<source lang="xml">
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<xs:schema targetNamespace="myNamespace" xmlns:myns="myNamespace" xmlns:xs="http://www.w3.org/2001/XMLSchema"
 +
    attributeFormDefault="qualified" elementFormDefault="qualified">
 +
 
 +
    <xs:element name="person" type="myns:person"/>
 +
 
 +
    <xs:complexType name="person">
 +
        <xs:sequence>
 +
            <xs:element name="name" type="xs:string"/>
 +
        </xs:sequence>
 +
    </xs:complexType>
 +
 
 +
    <xs:complexType name="customer">
 +
        <xs:complexContent>
 +
            <xs:extension base="myns:person">
 +
                <xs:sequence>
 +
                    <xs:element name="customer-id" type="xs:int"/>
 +
                </xs:sequence>
 +
            </xs:extension>
 +
        </xs:complexContent>
 +
    </xs:complexType>
 +
 
 +
    <xs:complexType name="employee">
 +
        <xs:complexContent>
 +
            <xs:extension base="myns:person">
 +
                <xs:sequence>
 +
                    <xs:element name="employee-id" type="xs:string"/>
 +
                </xs:sequence>
 +
            </xs:extension>
 +
        </xs:complexContent>
 +
    </xs:complexType>
 +
 
 +
</xs:schema>
 +
</source>
 +
 
 +
* The <tt>targetNamespace</tt> and <tt>elementFormDefault</tt> property will result in an <tt>@XmlSchema</tt> annotation on the generated <tt>package-info</tt> class.
 +
* The inheritance relationship between <tt>person</tt>, <tt>customer</tt>, and <tt>employee</tt> will result in an <tt>@XmlSeeAlso</tt> annotation on the generated <tt>Person</tt> class.
  
 
==== Limitations ====
 
==== Limitations ====
  
* XJC does not interpret the "attributeFormDefault" property during schema parsing, and will therefore not generate this property in the XmlSchema annotation.
+
* XJC does not interpret the <tt>attributeFormDefault</tt> property during schema parsing, and will therefore not generate this property in the <tt>@XmlSchema</tt> annotation.
* There is no XML Schema construct that will result in an XmlTransient annotation being generated.
+
* There is no XML Schema construct that will result in an <tt>@XmlTransient</tt> annotation being generated.
  
 
<br><br>
 
<br><br>
Line 127: Line 123:
 
! Field  
 
! Field  
 
! Method
 
! Method
! Schema Representation
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlAccessorOrder.html XmlAccessorOrder]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlAccessorOrder.html XmlAccessorOrder]  
Line 135: Line 130:
 
| align="center" | &nbsp;  
 
| align="center" | &nbsp;  
 
| align="center" | &nbsp;
 
| align="center" | &nbsp;
| align="center" | N/A
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlAccessorType.html XmlAccessorType]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlAccessorType.html XmlAccessorType]  
Line 143: Line 137:
 
| align="center" | &nbsp;  
 
| align="center" | &nbsp;  
 
| align="center" | &nbsp;
 
| align="center" | &nbsp;
| align="center" | N/A
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlRootElement.html XmlRootElement]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlRootElement.html XmlRootElement]  
Line 151: Line 144:
 
| align="center" | &nbsp;  
 
| align="center" | &nbsp;  
 
| align="center" | &nbsp;
 
| align="center" | &nbsp;
| align="center" | <source lang="DOS">
 
@XmlRootElement(name="PriceElement")
 
public class USPrice {
 
}
 
 
<!-- Example: XML schema definition -->
 
<xs:element name="PriceElement" type="USPrice"/>
 
  <xs:complexType name="USPrice">
 
      <xs:sequence>
 
        <xs:element name="price" type="xs:decimal"/>
 
      </sequence>
 
  </xs:complexType>
 
 
</source>
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlType.html XmlType]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlType.html XmlType]  
Line 172: Line 151:
 
| align="center" | &nbsp;  
 
| align="center" | &nbsp;  
 
| align="center" | &nbsp;
 
| align="center" | &nbsp;
| align="center" | <source lang="DOS">
+
|}
@XmlType(propOrder={"street", "city" , "state", "zip", "name" })
+
public class USAddress {
+
}
+
  
<xs:complexType name="USAddress">
+
<br>
  <xs:sequence>
+
 
      <xs:element name="street" type="xs:string"/>
+
The following example schema demonstrates how these annotations will be derived from the schema:
      <xs:element name="city" type="xs:string"/>
+
 
      <xs:element name="state" type="xs:string"/>
+
==== Example Schema ====
      <xs:element name="zip" type="xs:decimal"/>
+
<source lang="xml">
      <xs:element name="name" type="xs:string"/>
+
<?xml version="1.0" encoding="UTF-8"?>
  </xs:all>
+
<xs:schema targetNamespace="myNamespace" xmlns:myns="myNamespace" xmlns:xs="http://www.w3.org/2001/XMLSchema"
</xs:complexType>  
+
    attributeFormDefault="qualified" elementFormDefault="qualified">
 +
 
 +
    <xs:element name="individuo" type="myns:person"/>
 +
 
 +
    <xs:complexType name="person">
 +
        <xs:sequence>
 +
            <xs:element name="id" type="xs:int"/>
 +
            <xs:element name="first-name" type="xs:string"/>
 +
            <xs:element name="last-name" type="xs:string"/>
 +
            <xs:element name="phone-number" type="xs:string"/>
 +
            <xs:element name="email" type="xs:string"/>          
 +
        </xs:sequence>
 +
    </xs:complexType>
 +
 
 +
</xs:schema>
 
</source>
 
</source>
|}
+
 
 +
* The <tt>name</tt> property of the root element will appear in the <tt>@XmlRootElement</tt> annotation's <tt>name</tt> property.
 +
* The order of the elements of the <tt>person</tt> type will be captured in the <tt>@XmlType</tt> annotation's <tt>propOrder</tt> property.
 +
 
 +
==== Limitations ====
 +
 
 +
* There is no XML Schema construct that will result in the generation of <tt>@XmlAccessorOrder</tt> or <tt>@XmlAccessorType</tt> annotations.
  
 
<br><br>
 
<br><br>
Line 201: Line 197:
 
! Field  
 
! Field  
 
! Method
 
! Method
! Schema Representation
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlAttribute.html XmlAttribute]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlAttribute.html XmlAttribute]  
Line 209: Line 204:
 
| align="center" | X  
 
| align="center" | X  
 
| align="center" | X
 
| align="center" | X
| align="center" | <source lang="DOS">
 
public class USPrice {
 
  @XmlAttribute
 
  public java.math.BigDecimal price;
 
}
 
 
<xs:complexType name="USPrice">
 
  <xs:sequence>
 
  </xs:sequence>
 
  <xs:attribute name="price" type="xs:decimal"/>
 
</xs:complexType>
 
</source>
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlElement.html XmlElement]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlElement.html XmlElement]  
Line 228: Line 211:
 
| align="center" | X  
 
| align="center" | X  
 
| align="center" | X
 
| align="center" | X
| align="center" | <source lang="DOS">
 
public class USPrice {
 
  @XmlElement(name="itemprice")
 
  public java.math.BigDecimal price;
 
}
 
 
<xs:complexType name="USPrice"/>
 
  <xs:sequence>
 
      <xs:element name="itemprice" type="xs:decimal" minOccurs="0"/>
 
  </sequence>
 
</xs:complexType>
 
</source>
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html XmlAdapter]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html XmlAdapter]  
Line 247: Line 218:
 
| align="center" | X  
 
| align="center" | X  
 
| align="center" | X
 
| align="center" | X
| align="center" | N/A ?
 
Referenced in XJC code but unsure how it is specified from Schema
 
 
|}
 
|}
 +
 +
<br>
 +
 +
The following example schema demonstrates how these annotations will be derived from the schema:
 +
 +
==== Example Schema ====
 +
<source lang="xml">
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<xs:schema targetNamespace="myNamespace" xmlns:myns="myNamespace" xmlns:xs="http://www.w3.org/2001/XMLSchema">
 +
 +
    <xs:element name="person" type="myns:person"/>
 +
 +
    <xs:complexType name="person">
 +
        <xs:sequence>
 +
            <xs:element name="type" type="xs:string"/>
 +
        </xs:sequence>
 +
        <xs:attribute name="id" type="xs:int"/>
 +
    </xs:complexType>
 +
 +
</xs:schema>
 +
</source>
 +
 +
* The <tt>type</tt> field of the generated class will be annotated with <tt>@XmlElement</tt>.
 +
* The <tt>id</tt> field of the generated class will be annotated with <tt>@XmlAttribute</tt>.
 +
 +
==== Limitations ====
 +
 +
* There is no XML Schema construct that will result in the generation of an <tt>@XmlAdapter</tt> annotation.
  
 
<br><br>
 
<br><br>
Line 263: Line 260:
 
! Field  
 
! Field  
 
! Method
 
! Method
! Schema Representation
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlElementWrapper.html XmlElementWrapper]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlElementWrapper.html XmlElementWrapper]  
Line 271: Line 267:
 
| align="center" | X  
 
| align="center" | X  
 
| align="center" | X
 
| align="center" | X
| align="center" | N/A
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlList.html XmlList]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlList.html XmlList]  
Line 279: Line 274:
 
| align="center" | X  
 
| align="center" | X  
 
| align="center" | X
 
| align="center" | X
| align="center" | N/A
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlValue.html XmlValue]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlValue.html XmlValue]  
Line 287: Line 281:
 
| align="center" | X  
 
| align="center" | X  
 
| align="center" | X
 
| align="center" | X
| align="center" | <source lang="DOS">
 
public class USPrice {
 
  @XmlValue
 
  public java.math.BigDecimal price;
 
}
 
 
 
<xs:simpleType name="USPrice">
 
  <xs:restriction base="xs:decimal"/>
 
</xs:simpleType>
 
 
 
public class InternationalPrice {
 
  @XmlValue
 
  public java.math.BigDecimal price;
 
  @XmlAttribute
 
  public String currency;
 
}
 
 
 
<xs:complexType name="InternationalPrice">
 
  <xs:simpleContent>
 
      <xs:extension base="xs:decimal">
 
        <xs:attribute name="currency" type="xs:string"/>
 
      </xs:extension>
 
  </xs:simpleContent>
 
</xs:complexType>
 
</source>
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlAnyElement.html XmlAnyElement]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlAnyElement.html XmlAnyElement]  
Line 320: Line 288:
 
| align="center" | X  
 
| align="center" | X  
 
| align="center" | X
 
| align="center" | X
| align="center" | <source lang="DOS">
 
class Foo {
 
  int a;
 
  int b;
 
  @XmlAnyElement
 
  List<Element> any;
 
}
 
 
<xs:complexType name="foo">
 
  <xs:sequence>
 
      <xs:element name="a" type="xs:int" />
 
      <xs:element name="b" type="xs:int" />
 
      <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
 
  </xs:sequence>
 
</xs:complexType>
 
</source>
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlAnyAttribute.html XmlAnyAttribute]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlAnyAttribute.html XmlAnyAttribute]  
Line 343: Line 295:
 
| align="center" | X  
 
| align="center" | X  
 
| align="center" | X
 
| align="center" | X
| align="center" | N/A ?
 
Referenced in XJC code but unsure how it is specified from Schema
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlMixed.html XmlMixed]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlMixed.html XmlMixed]  
Line 352: Line 302:
 
| align="center" | X  
 
| align="center" | X  
 
| align="center" | X
 
| align="center" | X
| align="center" | <source lang="DOS">
+
|}
public class LetterBody {
+
  @XmlMixed
+
  @XmlElementRefs({
+
      @XmlElementRef(name="productName", type=JAXBElement.class),
+
      @XmlElementRef(name="quantity", type=JAXBElement.class),
+
      @XmlElementRef(name="name", type=JAXBElement.class)})
+
  List getContent() {...}
+
}
+
  
<xs:complexType name="letterBody" mixed="true">
+
<br>
  <xs:sequence>
+
 
      <xs:element name="name" type="xs:string"/>
+
The following example schema demonstrates how these annotations will be derived from the schema:
      <xs:element name="quantity" type="xs:positiveInteger"/>
+
 
      <xs:element name="productName" type="xs:string"/>
+
==== Example Schemas ====
  </xs:sequence>
+
 
</xs:complexType>
+
<source lang="xml">
 +
<!-- XmlList -->
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<xs:schema ...>
 +
 
 +
    <xs:element name="person">
 +
        <xs:complexType>
 +
            <xs:sequence>
 +
                <xs:element name="name" type="xs:string"/>
 +
                <xs:element name="codes" type="myns:codes"/>
 +
            </xs:sequence>
 +
        </xs:complexType>
 +
    </xs:element>
 +
 
 +
    <xs:simpleType name="codes">
 +
        <xs:list itemType="xs:string"/>
 +
    </xs:simpleType>
 +
 
 +
</xs:schema>
 
</source>
 
</source>
|}
+
 
 +
* An <tt>xs:simpleType</tt> containing an <tt>xs:list</tt> results in an <tt>@XmlList</tt> annotation on the <tt>codes</tt> field
 +
 
 +
<source lang="xml">
 +
<!-- XmlValue -->
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<xs:schema ...>
 +
 
 +
    <xs:element name="person" type="myns:person"/>
 +
 
 +
    <xs:complexType name="person">
 +
        <xs:sequence>
 +
            <xs:element name="name" type="xs:string"/>
 +
            <xs:element name="salary" type="myns:cdn_currency"/>
 +
        </xs:sequence>
 +
    </xs:complexType>
 +
 
 +
    <xs:complexType name="cdn_currency">
 +
        <xs:simpleContent>
 +
            <xs:extension base="xs:decimal"/>
 +
        </xs:simpleContent>
 +
    </xs:complexType>
 +
 
 +
</xs:schema>
 +
</source>
 +
 
 +
* An <tt>xs:complexType</tt> containing <tt>xs:simpleContent</tt> results in an <tt>@XmlValue</tt> annotation on the <tt>value</tt> field of the <tt>CdnCurrency</tt> type.
 +
 
 +
<source lang="xml">
 +
<!-- XmlAnyElement / XmlAnyAttribute -->
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<xs:schema ...>
 +
 
 +
    <xs:element name="person">
 +
        <xs:complexType>
 +
            <xs:sequence>
 +
                <xs:element name="name" type="xs:string"/>
 +
                <xs:any/>
 +
            </xs:sequence>
 +
            <xs:anyAttribute/>
 +
        </xs:complexType>
 +
    </xs:element>
 +
 
 +
</xs:schema>
 +
</source>
 +
 
 +
* The <tt>xs:any</tt> element results in the generation of an <tt>any</tt> field on <tt>Person</tt>, annotated with <tt>@XmlAnyElement</tt>.
 +
* The <tt>xs:anyAttribute</tt> element results in the generation of an <tt>otherAttributes</tt> field on <tt>Person</tt>, annotated with <tt>@XmlAnyAttribute</tt>.
 +
 
 +
<source lang="xml">
 +
<!-- XmlMixed -->
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<xs:schema ...>
 +
 
 +
    <xs:element name="person">
 +
        <xs:complexType mixed="true">
 +
            <xs:sequence>
 +
                <xs:element name="title" type="xs:string"/>
 +
                <xs:element name="name" type="xs:string"/>
 +
                <xs:element name="rewardPoints" type="xs:positiveInteger"/>               
 +
            </xs:sequence>
 +
        </xs:complexType>
 +
    </xs:element>
 +
 
 +
</xs:schema>
 +
</source>
 +
 
 +
* <tt>mixed=true</tt> results in the generation of a <tt>content</tt> field on <tt>Person</tt>, annotated with <tt>@XmlMixed</tt> (as well as <tt>@XmlElementRefs</tt> for each possible value)
 +
 
 +
==== Limitations ====
 +
 
 +
* There is no XML Schema construct that will result in an <tt>@XmlElementWrapper</tt> annotation being generated.
  
 
<br><br>
 
<br><br>
Line 384: Line 415:
 
! Field  
 
! Field  
 
! Method
 
! Method
! Schema Representation
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlID.html XmlID<br>]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlID.html XmlID<br>]  
Line 392: Line 422:
 
| align="center" | X  
 
| align="center" | X  
 
| align="center" | X
 
| align="center" | X
| align="center" | <source lang="DOS">
 
public class Customer {
 
  @XmlAttribute
 
  @XmlID
 
  public String getCustomerID();
 
  public void setCustomerID(String id);
 
}
 
 
<xs:complexType name="Customer">
 
  <xs:complexContent>
 
      <xs:sequence>
 
        ....
 
      </xs:sequence>
 
      <xs:attribute name="customerID" type="xs:ID"/>
 
  </xs:complexContent>
 
</xs:complexType>
 
</source>
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlIDREF.html XmlIDREF]<br>  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlIDREF.html XmlIDREF]<br>  
Line 416: Line 429:
 
| align="center" | X<br>  
 
| align="center" | X<br>  
 
| align="center" | X<br>
 
| align="center" | X<br>
| align="center" | <source lang="DOS">
+
|}
public class Shipping {
+
  @XmlIDREF
+
  public Customer getCustomer();
+
  public void setCustomer(Customer customer);
+
  ....
+
}
+
  
<xs:complexType name="Shipping">
+
<br>
  <xs:complexContent>
+
 
      <xs:sequence>
+
The following example schema demonstrates how these annotations will be derived from the schema:
        <xs:element name="customer" type="xs:IDREF"/>
+
 
        ....
+
==== Example Schema ====
      </xs:sequence>
+
 
  </xs:complexContent>
+
<source lang="xml">
</xs:complexType>
+
<?xml version="1.0" encoding="UTF-8"?>
 +
<xs:schema ...>
 +
 
 +
    <xs:element name="data">
 +
        <xs:complexType>
 +
            <xs:sequence>
 +
                <xs:element name="person" type="myns:person"/>
 +
                <xs:element name="company" type="myns:company"/>
 +
            </xs:sequence>
 +
        </xs:complexType>
 +
    </xs:element>
 +
 
 +
    <xs:complexType name="person">
 +
        <xs:sequence>
 +
            <xs:element name="name" type="xs:string"/>
 +
            <xs:element name="company" type="xs:IDREF"/>
 +
        </xs:sequence>
 +
    </xs:complexType>
 +
 
 +
    <xs:complexType name="company">
 +
        <xs:sequence>
 +
            <xs:element name="name" type="xs:string"/>
 +
            <xs:element name="address" type="xs:string"/>          
 +
        </xs:sequence>
 +
        <xs:attribute name="id" type="xs:ID"/>
 +
    </xs:complexType>
 +
 
 +
</xs:schema>
 
</source>
 
</source>
|}
+
 
 +
* The <tt>id</tt> attribute, of type <tt>xs:ID</tt>, in the <tt>company</tt> type results in an <tt>@XmlID</tt> annotation on the <tt>id</tt> field.
 +
* The <tt>company</tt> element, of type <tt>xs:IDREF</tt>, in the <tt>person</tt> type results in an <tt>@XmlIDREF</tt> annotation on the <tt>company</tt> field.
 +
 
 +
==== Limitations ====
 +
 
 +
* Currently disabled due to bug [https://bugs.eclipse.org/bugs/show_bug.cgi?id=307939 Bug 307939]
  
 
<br><br>
 
<br><br>
Line 447: Line 487:
 
! Field  
 
! Field  
 
! Method
 
! Method
! Schema Representation
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlElements.html XmlElements]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlElements.html XmlElements]  
Line 455: Line 494:
 
| align="center" | X  
 
| align="center" | X  
 
| align="center" | X
 
| align="center" | X
| align="center" | <source lang="DOS">
 
public class Foo {
 
  @XmlElements(
 
      @XmlElement(name="A", type=Integer.class),
 
      @XmlElement(name="B", type=Float.class)
 
  }
 
  public List items;
 
}
 
 
<xs:complexType name="Foo">
 
  <xs:sequence>
 
      <xs:choice minOccurs="0" maxOccurs="unbounded">
 
        <xs:element name="A" type="xs:int"/>
 
        <xs:element name="B" type="xs:float"/>
 
      <xs:choice>
 
  </xs:sequence>
 
</xs:complexType>
 
</source>
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlElementRef.html XmlElementRef]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlElementRef.html XmlElementRef]  
Line 480: Line 501:
 
| align="center" | X  
 
| align="center" | X  
 
| align="center" | X
 
| align="center" | X
| align="center" | <source lang="DOS">
 
@XmlRootElement(name="target")
 
class Target {
 
  // The presence of @XmlElementRef indicates that the XML
 
  // element name will be derived from the @XmlRootElement
 
  // annotation on the type (for e.g. "jar" for JarTask).
 
  @XmlElementRef
 
  List<Task> tasks;
 
}
 
 
abstract class Task {}
 
 
@XmlRootElement(name="jar")
 
class JarTask extends Task {
 
  ...
 
}
 
 
@XmlRootElement(name="javac")
 
class JavacTask extends Task {
 
  ...
 
}
 
 
<xs:element name="target" type="Target">
 
  <xs:complexType name="Target">
 
      <xs:sequence>
 
        <xs:choice maxOccurs="unbounded">
 
            <xs:element ref="jar">
 
            <xs:element ref="javac">
 
        </xs:choice>
 
      </xs:sequence>
 
  </xs:complexType>
 
</source>
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlElementRefs.html XmlElementRefs]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlElementRefs.html XmlElementRefs]  
Line 519: Line 508:
 
| align="center" | X<br>  
 
| align="center" | X<br>  
 
| align="center" | X<br>
 
| align="center" | X<br>
| align="center" | N/A ?
 
Referenced in XJC code but unsure how it is specified from Schema
 
 
|}
 
|}
 +
 +
<br>
 +
 +
The following example schema demonstrates how these annotations will be derived from the schema:
 +
 +
==== Example Schema ====
 +
 +
<source lang="xml">
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<xs:schema ...>
 +
 +
    <xs:element name="person">
 +
        <xs:complexType>
 +
            <xs:sequence>
 +
                <xs:choice minOccurs="1" maxOccurs="unbounded">
 +
                    <xs:element name="name" type="xs:string"/>
 +
                    <xs:element name="reference-number" type="xs:int"/>
 +
                </xs:choice>
 +
            </xs:sequence>
 +
        </xs:complexType>
 +
    </xs:element>
 +
 +
</xs:schema>
 +
</source>
 +
 +
* The <tt>xs:choice</tt> will result in the generation of a <tt>nameOrReferenceNumber</tt> field, which is annotated with <tt>@XmlElements</tt> (with one <tt>@XmlElement</tt> annotation for both <tt>name</tt> and <tt>reference-number</tt>.
 +
* <tt>@XmlElementRefs</tt> is covered along with the <tt>@XmlMixed</tt> annotation from Phase 4.
  
 
<br><br>
 
<br><br>
Line 535: Line 549:
 
! Field  
 
! Field  
 
! Method
 
! Method
! Schema Representation
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlSchemaType.html XmlSchemaType]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlSchemaType.html XmlSchemaType]  
Line 543: Line 556:
 
| align="center" | X  
 
| align="center" | X  
 
| align="center" | X
 
| align="center" | X
| align="center" | <source lang="DOS">
 
public class USPrice {
 
  @XmlElement
 
  @XmlSchemaType(name="date")
 
  public XMLGregorianCalendar date;
 
}
 
 
<xs:complexType name="USPrice"/>
 
  <xs:sequence>
 
      <xs:element name="date" type="xs:date"/>
 
  </sequence>
 
</xs:complexType>
 
</source>
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlSchemaTypes.html XmlSchemaTypes]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlSchemaTypes.html XmlSchemaTypes]  
Line 563: Line 563:
 
| align="center" | &nbsp;<br>  
 
| align="center" | &nbsp;<br>  
 
| align="center" | &nbsp;<br>
 
| align="center" | &nbsp;<br>
| align="center" | N/A
 
 
|}
 
|}
 +
 +
<br>
 +
 +
The following example schema demonstrates how these annotations will be derived from the schema:
 +
 +
==== Example Schema ====
 +
 +
<source lang="xml">
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<xs:schema ...>
 +
 +
    <xs:element name="person">
 +
        <xs:complexType>
 +
            <xs:sequence>
 +
                <xs:element name="date-of-birth" type="xs:date"/>
 +
            </xs:sequence>
 +
        </xs:complexType>
 +
    </xs:element>
 +
 +
</xs:schema>
 +
</source>
 +
 +
* The <tt>dateOfBirth</tt> attribute will be annotated with <tt>@XmlSchemaType</tt>, because its XML type, <tt>xs:date</tt>, is an XML datatype (not a primitive type).
 +
 +
==== Limitations ====
 +
 +
* There is no XML Schema construct that will result in an <tt>@XmlSchemaTypes</tt> annotation being generated.
  
 
<br><br>
 
<br><br>
Line 578: Line 604:
 
! Field  
 
! Field  
 
! Method
 
! Method
! Schema Representation
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlEnum.html XmlEnum]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlEnum.html XmlEnum]  
Line 586: Line 611:
 
| align="center" | &nbsp;  
 
| align="center" | &nbsp;  
 
| align="center" | &nbsp;
 
| align="center" | &nbsp;
| align="center" | <source lang="DOS">
 
@XmlEnum(String.class)
 
public enum Card { CLUBS, DIAMONDS, HEARTS, SPADES }
 
 
<xs:simpleType name="Card">
 
  <xs:restriction base="xs:string"/>
 
      <xs:enumeration value="CLUBS"/>
 
      <xs:enumeration value="DIAMONDS"/>
 
      <xs:enumeration value="HEARTS"/>
 
      <xs:enumeration value="SPADES"/>
 
</xs:simpleType>
 
</source>
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlEnumValue.html XmlEnumValue]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlEnumValue.html XmlEnumValue]  
Line 605: Line 618:
 
| align="center" | X<br>  
 
| align="center" | X<br>  
 
| align="center" | X<br>
 
| align="center" | X<br>
| align="center" | N/A
 
 
|}
 
|}
 +
 +
<br>
 +
 +
The following example schema demonstrates how these annotations will be derived from the schema:
 +
 +
==== Example Schema ====
 +
 +
<source lang="xml">
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<xs:schema ...>
 +
 +
    <xs:element name="person">
 +
        <xs:complexType>
 +
            <xs:sequence>
 +
                <xs:element name="quadrant" type="myns:compass-direction"/>
 +
            </xs:sequence>
 +
        </xs:complexType>
 +
    </xs:element>
 +
 +
    <xs:simpleType name="compass-direction">
 +
        <xs:restriction base="xs:string">
 +
<xs:enumeration value="NORTH"/>
 +
<xs:enumeration value="SOUTH"/>
 +
<xs:enumeration value="EAST"/>
 +
<xs:enumeration value="WEST"/>
 +
        </xs:restriction>
 +
    </xs:simpleType>
 +
 +
</xs:schema>
 +
</source>
 +
 +
==== Limitations ====
 +
 +
* Waiting on [https://bugs.eclipse.org/bugs/show_bug.cgi?id=308367 Bug 308367].
  
 
<br><br>
 
<br><br>
Line 620: Line 666:
 
! Field  
 
! Field  
 
! Method
 
! Method
! Schema Representation
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlInlineBinaryData.html XmlInlineBinaryData]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlInlineBinaryData.html XmlInlineBinaryData]  
Line 628: Line 673:
 
| align="center" | X  
 
| align="center" | X  
 
| align="center" | X
 
| align="center" | X
| align="center" | N/A
 
 
|}
 
|}
 +
 +
<br>
 +
 +
* There is no XML Schema construct that will result in an <tt>@XmlInlineBinaryData</tt> annotation being generated.
  
 
<br><br>
 
<br><br>
Line 643: Line 691:
 
! Field  
 
! Field  
 
! Method
 
! Method
! Schema Representation
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlElementDecl.html XmlElementDecl]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlElementDecl.html XmlElementDecl]  
Line 651: Line 698:
 
| align="center" | X  
 
| align="center" | X  
 
| align="center" | X
 
| align="center" | X
| align="center" | N/A ?
 
Only used for ObjectFactory.java
 
 
|-
 
|-
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlRegistry.html XmlRegistry]  
 
| [http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlRegistry.html XmlRegistry]  
Line 660: Line 705:
 
| align="center" | &nbsp;  
 
| align="center" | &nbsp;  
 
| align="center" | &nbsp;
 
| align="center" | &nbsp;
| align="center" | N/A ?
 
Only used for ObjectFactory.java
 
 
|}
 
|}
 +
 +
<br>
 +
 +
The following example schema demonstrates how these annotations will be derived from the schema:
 +
 +
==== Example Schema ====
 +
 +
<source lang="xml">
 +
<?xml version="1.0" encoding="UTF-8"?>
 +
<xs:schema ...>
 +
 +
    <xs:element name="individuo" type="myns:person"/>
 +
 +
    <xs:complexType name="person">
 +
        <xs:sequence>
 +
            <xs:element name="name" type="xs:string"/>
 +
        </xs:sequence>
 +
    </xs:complexType>
 +
 +
</xs:schema>
 +
</source>
 +
 +
 +
* The element declaration for <tt>individuo</tt> will result in an <tt>@XmlElementDecl</tt> annotation on the generated <tt>ObjectFactory</tt> class.
 +
* As a result of the <tt>@XmlElementDecl</tt> annotation, <tt>ObjectFactory</tt> will also be annotated with an <tt>@XmlRegistry</tt>.
 +
 +
<br><br>
 +
 +
== Design ==
 +
 +
When constructing a <code>DynamicJAXBContext</code> from XML Schema, we can use APIs from the Java XJC compiler to parse a schema and create Java class definitions (XJC's <code>JCodeModel</code>) in memory, then pass these class definitions to an EclipseLink <code>Generator</code> (<code>org.eclipse.persistence.jaxb.compiler.Generator</code>) to generate an EclipseLink project.  After we have created this project, we can use the <code>DynamicTypeBuilder</code> to create a dynamic project, generating Java classes in memory along the way.
 +
 +
First, we use XJC API to parse an XSD and generate a <code>JCodeModel</code>.  Note that this code stops short of actually generating <code>.java</code> files, it only generates an in-memory representation of the Java files that would normally be created.
 +
 +
<source lang="java5">
 +
// Use XJC API to parse the schema and generate its JCodeModel
 +
SchemaCompiler sc = XJC.createSchemaCompiler();
 +
InputSource inputSource = new InputSource(schemaInputStream);
 +
sc.parseSchema(inputSource);
 +
S2JJAXBModel model = sc.bind();
 +
JCodeModel jCodeModel = model.generateCode(new Plugin[0], null);
 +
</source>
 +
 +
We can then wrap these XJC classes in our own implentations of EclipseLink's JAXB <code>JavaModel</code> classes.  This will allow us to use the <code>Generator</code> to create an EclipseLink project and mappings.  The <code>JavaModel</code> interfaces define "wrappers" for the various Java language constructs that make up the domain model (e.g. classes, methods, constructors, annotations, packages, etc).  For example:
 +
 +
<source lang="java5">
 +
public class XJCJavaFieldImpl implements JavaField {
 +
 +
    // XJC's definition of a Field
 +
    protected JFieldVar xjcField;
 +
 +
    ...
 +
 +
    public int getModifiers() {
 +
        return xjcField.mods().getValue();
 +
    }
 +
 +
    public String getName() {
 +
        return xjcField.name();
 +
    }
 +
 +
    ...
 +
}
 +
</source>
 +
 +
Creating the <code>JavaModel</code> classes:
 +
 +
<source lang="java5">
 +
// Create EclipseLink JavaModel objects for each of XJC's JDefinedClasses
 +
ArrayList<JDefinedClass> classesToProcess = new ArrayList<JDefinedClass>();
 +
Iterator<JPackage> packages = jCodeModel.packages();
 +
while (packages.hasNext()) {
 +
  JPackage pkg = packages.next();
 +
  Iterator<JDefinedClass> classes = pkg.classes();
 +
  while (classes.hasNext()) {
 +
      JDefinedClass cls = classes.next();
 +
      classesToProcess.add(cls);
 +
  }
 +
 +
JavaClass[] jotClasses = createClassModelFromXJC(classesToProcess, jCodeModel);
 +
</source>
 +
 +
At this point, we can instantiate a <code>Generator</code> and obtain a "dry" EclipseLink project, which we can then turn into a dynamic project with generated in-memory classes.  Finally, we create and store an <code>XMLContext</code> and a <code>DynamicHelper</code>:
 +
 +
<source lang="java5">
 +
// Use the JavaModel to setup a Generator to generate an EclipseLink project
 +
XJCJavaModelImpl javaModel = new XJCJavaModelImpl(Thread.currentThread().getContextClassLoader(), jCodeModel);
 +
XJCJavaModelInputImpl javaModelInput = new XJCJavaModelInputImpl(jotClasses, javaModel);
 +
Generator g = new Generator(javaModelInput);
 +
Project p = g.generateProject();
 +
       
 +
// Make a Dynamic Project from this project, because these classes do not exist on the classpath
 +
DynamicClassLoader dynamicClassLoader;
 +
if (classLoader instanceof DynamicClassLoader) {
 +
  dynamicClassLoader = classLoader;
 +
} else {
 +
  dynamicClassLoader = new DynamicClassLoader(classLoader);           
 +
}
 +
Project dp = DynamicTypeBuilder.loadDynamicProject(p, null, dynamicClassLoader);
 +
       
 +
this.xmlContext = new XMLContext(dp);
 +
this.dynamicHelper = new DynamicHelper(xmlContext.getSession(0));     
 +
</source>

Latest revision as of 11:36, 13 April 2010

Dynamic MOXy - Bootstrapping from XML Schema

Overview

Support for bootstrapping a DynamicJAXBContext from an XML Schema file (XSD) will be implemented in multiple phases. For each phase, test schemas will be created that would result in the following annotations being generated by XJC. A DynamicJAXBContext will then be created from each schema, and an example object will be marshalled. The resulting document will be inspected to ensure that it was marshalled properly, according to the annotations being tested.

Generating a DynamicJAXBContext with XJC

A DynamicJAXBContext is created from an XSD in the following way:

  1. The schema is parsed using com.sun.tools.xjc.api.SchemaCompiler, resulting in a com.sun.codemodel.JCodeModel being generated.
  2. JCodeModel contains XJC representations (com.sun.codemodel.JDefinedClass) of the classes to be generated. We iterate over the collection of JDefinedClasses to create EclipseLink representations of the same classes (org.eclipse.persistence.jaxb.javamodel.xjc.*)
  3. This collection of EclipseLink javamodel classes is then passed to org.eclipse.persistence.jaxb.compiler.Generator, which generates a standard EclipseLink project.
  4. A Dynamic Project is then created from the standard project via DynamicTypeBuilder.loadDynamicProject().
  5. An org.eclipse.persistence.oxm.XMLContext is then created from the Dynamic Project, and a DynamicJAXBContext is returned backed by this XMLContext.


Development Phases

Phase 1

Annotation XML Metadata Tag Package Type Field Method
XmlNs xml-ns        
XmlSchema xml-schema X      
XmlSeeAlso xml-see-also   X    
XmlTransient xml-transient   X X X


The following example schema demonstrates how these annotations will be derived from the schema:

Example Schema

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="myNamespace" xmlns:myns="myNamespace" xmlns:xs="http://www.w3.org/2001/XMLSchema"
    attributeFormDefault="qualified" elementFormDefault="qualified">
 
    <xs:element name="person" type="myns:person"/>
 
    <xs:complexType name="person">
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
 
    <xs:complexType name="customer">
        <xs:complexContent>
            <xs:extension base="myns:person">
                <xs:sequence>
                    <xs:element name="customer-id" type="xs:int"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
 
    <xs:complexType name="employee">
        <xs:complexContent>
            <xs:extension base="myns:person">
                <xs:sequence>
                    <xs:element name="employee-id" type="xs:string"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
 
</xs:schema>
  • The targetNamespace and elementFormDefault property will result in an @XmlSchema annotation on the generated package-info class.
  • The inheritance relationship between person, customer, and employee will result in an @XmlSeeAlso annotation on the generated Person class.

Limitations

  • XJC does not interpret the attributeFormDefault property during schema parsing, and will therefore not generate this property in the @XmlSchema annotation.
  • There is no XML Schema construct that will result in an @XmlTransient annotation being generated.



Phase 2

Annotation XML Metadata Tag Package Type Field Method
XmlAccessorOrder xml-accessor-order X X    
XmlAccessorType xml-accessor-type X X    
XmlRootElement xml-root-element   X    
XmlType xml-type   X    


The following example schema demonstrates how these annotations will be derived from the schema:

Example Schema

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="myNamespace" xmlns:myns="myNamespace" xmlns:xs="http://www.w3.org/2001/XMLSchema"
    attributeFormDefault="qualified" elementFormDefault="qualified">
 
    <xs:element name="individuo" type="myns:person"/>
 
    <xs:complexType name="person">
        <xs:sequence>
            <xs:element name="id" type="xs:int"/>
            <xs:element name="first-name" type="xs:string"/>
            <xs:element name="last-name" type="xs:string"/>
            <xs:element name="phone-number" type="xs:string"/>
            <xs:element name="email" type="xs:string"/>            
        </xs:sequence>
    </xs:complexType>
 
</xs:schema>
  • The name property of the root element will appear in the @XmlRootElement annotation's name property.
  • The order of the elements of the person type will be captured in the @XmlType annotation's propOrder property.

Limitations

  • There is no XML Schema construct that will result in the generation of @XmlAccessorOrder or @XmlAccessorType annotations.



Phase 3

Annotation XML Metadata Tag Package Type Field Method
XmlAttribute xml-attribute     X X
XmlElement xml-element     X X
XmlAdapter xml-java-type-adapter X X X X


The following example schema demonstrates how these annotations will be derived from the schema:

Example Schema

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="myNamespace" xmlns:myns="myNamespace" xmlns:xs="http://www.w3.org/2001/XMLSchema">
 
    <xs:element name="person" type="myns:person"/>
 
    <xs:complexType name="person">
        <xs:sequence>
            <xs:element name="type" type="xs:string"/>
        </xs:sequence>
        <xs:attribute name="id" type="xs:int"/>
    </xs:complexType>
 
</xs:schema>
  • The type field of the generated class will be annotated with @XmlElement.
  • The id field of the generated class will be annotated with @XmlAttribute.

Limitations

  • There is no XML Schema construct that will result in the generation of an @XmlAdapter annotation.



Phase 4

Annotation XML Metadata Tag Package Type Field Method
XmlElementWrapper xml-element-wrapper     X X
XmlList xml-list     X X
XmlValue xml-value X X
XmlAnyElement xml-any-element     X X
XmlAnyAttribute xml-any-attribute     X X
XmlMixed xml-mixed     X X


The following example schema demonstrates how these annotations will be derived from the schema:

Example Schemas

<!-- XmlList -->
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema ...>
 
    <xs:element name="person">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="name" type="xs:string"/>
                <xs:element name="codes" type="myns:codes"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
 
    <xs:simpleType name="codes">
        <xs:list itemType="xs:string"/>
    </xs:simpleType>
 
</xs:schema>
  • An xs:simpleType containing an xs:list results in an @XmlList annotation on the codes field
<!-- XmlValue -->
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema ...>
 
    <xs:element name="person" type="myns:person"/>
 
    <xs:complexType name="person">
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
            <xs:element name="salary" type="myns:cdn_currency"/>
        </xs:sequence>
    </xs:complexType>
 
    <xs:complexType name="cdn_currency">
        <xs:simpleContent>
            <xs:extension base="xs:decimal"/>
        </xs:simpleContent>
    </xs:complexType>
 
</xs:schema>
  • An xs:complexType containing xs:simpleContent results in an @XmlValue annotation on the value field of the CdnCurrency type.
<!-- XmlAnyElement / XmlAnyAttribute -->
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema ...>
 
    <xs:element name="person">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="name" type="xs:string"/>
                <xs:any/>
            </xs:sequence>
            <xs:anyAttribute/>
        </xs:complexType>
    </xs:element>
 
</xs:schema>
  • The xs:any element results in the generation of an any field on Person, annotated with @XmlAnyElement.
  • The xs:anyAttribute element results in the generation of an otherAttributes field on Person, annotated with @XmlAnyAttribute.
<!-- XmlMixed -->
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema ...>
 
    <xs:element name="person">
        <xs:complexType mixed="true">
            <xs:sequence>
                <xs:element name="title" type="xs:string"/>
                <xs:element name="name" type="xs:string"/>
                <xs:element name="rewardPoints" type="xs:positiveInteger"/>                
            </xs:sequence>
        </xs:complexType>
    </xs:element>
 
</xs:schema>
  • mixed=true results in the generation of a content field on Person, annotated with @XmlMixed (as well as @XmlElementRefs for each possible value)

Limitations

  • There is no XML Schema construct that will result in an @XmlElementWrapper annotation being generated.



Phase 5

Annotation XML Metadata Tag Package Type Field Method
XmlID
xml-id     X X
XmlIDREF
xml-idref   X
X


The following example schema demonstrates how these annotations will be derived from the schema:

Example Schema

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema ...>
 
    <xs:element name="data">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="person" type="myns:person"/>
                <xs:element name="company" type="myns:company"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
 
    <xs:complexType name="person">
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
            <xs:element name="company" type="xs:IDREF"/>
        </xs:sequence>
    </xs:complexType>
 
    <xs:complexType name="company">
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
            <xs:element name="address" type="xs:string"/>            
        </xs:sequence>
        <xs:attribute name="id" type="xs:ID"/>
    </xs:complexType>
 
</xs:schema>
  • The id attribute, of type xs:ID, in the company type results in an @XmlID annotation on the id field.
  • The company element, of type xs:IDREF, in the person type results in an @XmlIDREF annotation on the company field.

Limitations



Phase 6

Annotation XML Metadata Tag Package Type Field Method
XmlElements xml-elements     X X
XmlElementRef xml-element-ref     X X
XmlElementRefs xml-element-refs X
X


The following example schema demonstrates how these annotations will be derived from the schema:

Example Schema

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema ...>
 
    <xs:element name="person">
        <xs:complexType>
            <xs:sequence>
                <xs:choice minOccurs="1" maxOccurs="unbounded">
                    <xs:element name="name" type="xs:string"/>
                    <xs:element name="reference-number" type="xs:int"/>
                </xs:choice>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
 
</xs:schema>
  • The xs:choice will result in the generation of a nameOrReferenceNumber field, which is annotated with @XmlElements (with one @XmlElement annotation for both name and reference-number.
  • @XmlElementRefs is covered along with the @XmlMixed annotation from Phase 4.



Phase 7

Annotation XML Metadata Tag Package Type Field Method
XmlSchemaType xml-schema-type X   X X
XmlSchemaTypes xml-schema-types X    
 


The following example schema demonstrates how these annotations will be derived from the schema:

Example Schema

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema ...>
 
    <xs:element name="person">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="date-of-birth" type="xs:date"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
 
</xs:schema>
  • The dateOfBirth attribute will be annotated with @XmlSchemaType, because its XML type, xs:date, is an XML datatype (not a primitive type).

Limitations

  • There is no XML Schema construct that will result in an @XmlSchemaTypes annotation being generated.



Phase 8

Annotation XML Metadata Tag Package Type Field Method
XmlEnum xml-enum   X    
XmlEnumValue xml-enum-value     X
X


The following example schema demonstrates how these annotations will be derived from the schema:

Example Schema

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema ...>
 
    <xs:element name="person">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="quadrant" type="myns:compass-direction"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
 
    <xs:simpleType name="compass-direction">
        <xs:restriction base="xs:string">
			<xs:enumeration value="NORTH"/>
			<xs:enumeration value="SOUTH"/>
			<xs:enumeration value="EAST"/>
			<xs:enumeration value="WEST"/>
        </xs:restriction> 
    </xs:simpleType>
 
</xs:schema>

Limitations



Phase 9

Annotation XML Metadata Tag Package Type Field Method
XmlInlineBinaryData xml-inline-binary-data   X X X


  • There is no XML Schema construct that will result in an @XmlInlineBinaryData annotation being generated.



Phase 10

Annotation XML Metadata Tag Package Type Field Method
XmlElementDecl xml-element-decl     X X
XmlRegistry xml-registry   X    


The following example schema demonstrates how these annotations will be derived from the schema:

Example Schema

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema ...>
 
    <xs:element name="individuo" type="myns:person"/>
 
    <xs:complexType name="person">
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
 
</xs:schema>


  • The element declaration for individuo will result in an @XmlElementDecl annotation on the generated ObjectFactory class.
  • As a result of the @XmlElementDecl annotation, ObjectFactory will also be annotated with an @XmlRegistry.



Design

When constructing a DynamicJAXBContext from XML Schema, we can use APIs from the Java XJC compiler to parse a schema and create Java class definitions (XJC's JCodeModel) in memory, then pass these class definitions to an EclipseLink Generator (org.eclipse.persistence.jaxb.compiler.Generator) to generate an EclipseLink project. After we have created this project, we can use the DynamicTypeBuilder to create a dynamic project, generating Java classes in memory along the way.

First, we use XJC API to parse an XSD and generate a JCodeModel. Note that this code stops short of actually generating .java files, it only generates an in-memory representation of the Java files that would normally be created.

// Use XJC API to parse the schema and generate its JCodeModel
SchemaCompiler sc = XJC.createSchemaCompiler();
InputSource inputSource = new InputSource(schemaInputStream);
sc.parseSchema(inputSource);
S2JJAXBModel model = sc.bind();
JCodeModel jCodeModel = model.generateCode(new Plugin[0], null);

We can then wrap these XJC classes in our own implentations of EclipseLink's JAXB JavaModel classes. This will allow us to use the Generator to create an EclipseLink project and mappings. The JavaModel interfaces define "wrappers" for the various Java language constructs that make up the domain model (e.g. classes, methods, constructors, annotations, packages, etc). For example:

public class XJCJavaFieldImpl implements JavaField {
 
    // XJC's definition of a Field
    protected JFieldVar xjcField;
 
    ...
 
    public int getModifiers() {
        return xjcField.mods().getValue();
    }
 
    public String getName() {
        return xjcField.name();
    }
 
    ...
}

Creating the JavaModel classes:

// Create EclipseLink JavaModel objects for each of XJC's JDefinedClasses
ArrayList<JDefinedClass> classesToProcess = new ArrayList<JDefinedClass>();
Iterator<JPackage> packages = jCodeModel.packages();
while (packages.hasNext()) {
   JPackage pkg = packages.next();
   Iterator<JDefinedClass> classes = pkg.classes();
   while (classes.hasNext()) {
      JDefinedClass cls = classes.next();
      classesToProcess.add(cls);
   }
}   
JavaClass[] jotClasses = createClassModelFromXJC(classesToProcess, jCodeModel);

At this point, we can instantiate a Generator and obtain a "dry" EclipseLink project, which we can then turn into a dynamic project with generated in-memory classes. Finally, we create and store an XMLContext and a DynamicHelper:

// Use the JavaModel to setup a Generator to generate an EclipseLink project 
XJCJavaModelImpl javaModel = new XJCJavaModelImpl(Thread.currentThread().getContextClassLoader(), jCodeModel);
XJCJavaModelInputImpl javaModelInput = new XJCJavaModelInputImpl(jotClasses, javaModel);
Generator g = new Generator(javaModelInput);
Project p = g.generateProject();
 
// Make a Dynamic Project from this project, because these classes do not exist on the classpath
DynamicClassLoader dynamicClassLoader;
if (classLoader instanceof DynamicClassLoader) {
   dynamicClassLoader = classLoader;
} else {
   dynamicClassLoader = new DynamicClassLoader(classLoader);            
}
Project dp = DynamicTypeBuilder.loadDynamicProject(p, null, dynamicClassLoader);
 
this.xmlContext = new XMLContext(dp);
this.dynamicHelper = new DynamicHelper(xmlContext.getSession(0));

Copyright © Eclipse Foundation, Inc. All Rights Reserved.