Extras XJC Plugin

A XJC plugin to provide extended mapping functionality for schema based generation.

License

License

GroupId

GroupId

io.fares.bind.xjc.plugins
ArtifactId

ArtifactId

extras-xjc-plugin
Last Version

Last Version

0.0.4
Release Date

Release Date

Type

Type

jar
Description

Description

Extras XJC Plugin
A XJC plugin to provide extended mapping functionality for schema based generation.
Project URL

Project URL

https://github.com/bertramn/extras-xjc-plugin
Source Code Management

Source Code Management

https://github.com/bertramn/extras-xjc-plugin.git

Download extras-xjc-plugin

How to add to project

<!-- https://jarcasting.com/artifacts/io.fares.bind.xjc.plugins/extras-xjc-plugin/ -->
<dependency>
    <groupId>io.fares.bind.xjc.plugins</groupId>
    <artifactId>extras-xjc-plugin</artifactId>
    <version>0.0.4</version>
</dependency>
// https://jarcasting.com/artifacts/io.fares.bind.xjc.plugins/extras-xjc-plugin/
implementation 'io.fares.bind.xjc.plugins:extras-xjc-plugin:0.0.4'
// https://jarcasting.com/artifacts/io.fares.bind.xjc.plugins/extras-xjc-plugin/
implementation ("io.fares.bind.xjc.plugins:extras-xjc-plugin:0.0.4")
'io.fares.bind.xjc.plugins:extras-xjc-plugin:jar:0.0.4'
<dependency org="io.fares.bind.xjc.plugins" name="extras-xjc-plugin" rev="0.0.4">
  <artifact name="extras-xjc-plugin" type="jar" />
</dependency>
@Grapes(
@Grab(group='io.fares.bind.xjc.plugins', module='extras-xjc-plugin', version='0.0.4')
)
libraryDependencies += "io.fares.bind.xjc.plugins" % "extras-xjc-plugin" % "0.0.4"
[io.fares.bind.xjc.plugins/extras-xjc-plugin "0.0.4"]

Dependencies

compile (5)

Group / Artifact Type Version
org.jvnet.jaxb2_commons : jaxb2-basics-tools jar 0.12.0
net.bytebuddy : byte-buddy jar 1.9.12
net.bytebuddy : byte-buddy-agent jar 1.9.12
org.slf4j : jcl-over-slf4j jar 1.7.26
ch.qos.logback : logback-classic jar 1.2.3

provided (3)

Group / Artifact Type Version
jakarta.xml.bind : jakarta.xml.bind-api jar 2.3.2
org.glassfish.jaxb : jaxb-xjc jar 2.3.2
org.glassfish.jaxb : codemodel jar 2.3.2

Project Modules

There are no modules declared in this project.

Extras XJC Plugin

This plugin provides some extra (missing) XJC features to generated Java Beans.

Usage

Add this library to the JAXB compiler plugin and activate the respective plugins.

<plugin>
  <groupId>org.jvnet.jaxb2.maven2</groupId>
  <artifactId>maven-jaxb2-plugin</artifactId>
  <configuration>
    <plugins>
      <plugin>
        <groupId>io.fares.bind.xjc.plugins</groupId>
        <artifactId>extras-xjc-plugin</artifactId>
        <version>0.0.4</version>
      </plugin>
    </plugins>
    <extension>true</extension>
    <args>
      <arg>-Xxml-adapter</arg>
    </args>
  </configuration>
</plugin>

Add XmlAdapter for Simple Types

This plugin can also be used to "override" XJC adapters that have been attached to a simple type in the global bindings.

<jaxb:globalBindings>

  <xjc:javaType name="java.time.OffsetDateTime"
                xmlType="xsd:dateTime"
                adapter="test.time.OffsetDateTimeAdapter"/>

</jaxb:globalBindings>

To override the default adapter binding just add the extras:xml-adapter annotations to either xsd:element or xsd:attribute:

<xsd:schema targetNamespace="urn:replacesimpletype.test"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
            xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
            xmlns:extras="http://jaxb2-commons.dev.java.net/xjc/extras"
            elementFormDefault="qualified"
            jaxb:version="2.1"
            jaxb:extensionBindingPrefixes="xjc extras">

  <xsd:annotation>
    <xsd:appinfo>
      <jaxb:globalBindings fixedAttributeAsConstantProperty="true">
        <xjc:javaType name="java.time.OffsetDateTime"
                      xmlType="xsd:dateTime"
                      adapter="test.time.OffsetDateTimeAdapter"/>
      </jaxb:globalBindings>
    </xsd:appinfo>
  </xsd:annotation>

  <xsd:complexType name="Book">
        <xsd:sequence>
          <xsd:element name="overrideElement" type="xsd:dateTime">
            <xsd:annotation>
              <xsd:appinfo>
                <extras:xml-adapter name="test.time.LocalDateTimeAdapter"/>
              </xsd:appinfo>
            </xsd:annotation>
          </xsd:element>
        </xsd:sequence>
        <xsd:attribute  name="overrideAttribute" type="xsd:dateTime">
          <xsd:annotation>
            <xsd:appinfo>
              <extras:xml-adapter name="test.time.LocalDateTimeAdapter"/>
            </xsd:appinfo>
          </xsd:annotation>
        </xsd:attribute>
  </xsd:complexType>

  <xsd:attribute name="refAttribute1" type="xsd:dateTime"/>
  <xsd:attribute name="refAttribute2" type="xsd:string"/>

  <!-- this one currently would not work -->
  <xsd:attribute name="refAttribute3" type="xsd:dateTime">
    <xsd:annotation>
      <xsd:appinfo>
        <extras:xml-adapter name="test.time.LocalDateTimeAdapter"/>
      </xsd:appinfo>
    </xsd:annotation>
  </xsd:attribute>

</xsd:schema>

Note: Annotations on the ref attribute currently do not work

Add XmlAdapter for Complex Types

For some reason, XJC does not allow global bindings of complex types. Below will fail with an error message com.sun.istack.SAXParseException2: undefined simple type "{urn:complextypeadapter.test}Amount":

<jaxb:globalBindings>

  <xjc:javaType name="javax.money.MonetaryAmount"
                xmlType="c:Amount"
                adapter="test.complextypeadapter.AmountXmlAdapter"/>

</jaxb:globalBindings>

Unfortunately XJC does not support custom XJC plugin extensions for globalBindings. The best we can do is either attach customisations to a schema or to the target type we want to map.

Below example will attach a customisation to the complex type that we want to map using the AmountXmlAdapter. The plugin will process every generated field and if the field is of xml type c:Amount, it will attach the XmlAdapter as specified in extras:xml-adapter/@name. It will also ensure that the type of the field exactly matches the custom type of the XmlAdapter to prevent extended types to be wrongly adapted to prevent loss of data.

<xsd:schema targetNamespace="urn:complextypeadapter.test"
            xmlns:tns="urn:complextypeadapter.test"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
            xmlns:extras="http://jaxb2-commons.dev.java.net/xjc/extras"
            jaxb:version="2.1"
            jaxb:extensionBindingPrefixes="extras">

  <xsd:element name="Amount" type="tns:Amount"/>
  <xsd:complexType name="Amount">
    <xsd:annotation>
      <xsd:appinfo>
        <extras:xml-adapter name="test.complextypeadapter.AmountXmlAdapter"/>
      </xsd:appinfo>
    </xsd:annotation>
    <xsd:simpleContent>
      <xsd:extension base="xsd:decimal">
        <xsd:attribute name="currency" type="tns:CurrencyCode" use="required">
          <xsd:annotation>
            <xsd:documentation>The ISO 4217 compliant currency code the currency ammount is nominated in.</xsd:documentation>
          </xsd:annotation>
        </xsd:attribute>
      </xsd:extension>
    </xsd:simpleContent>
  </xsd:complexType>

  <xsd:simpleType name="CurrencyCode">
    <xsd:annotation>
      <xsd:documentation>Use ISO 4217 three letter alpha code. </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="[A-Z]{3}"/>
    </xsd:restriction>
  </xsd:simpleType>

</xsd:schema>

When using this type in another schema, the generate a field is of type javax.money.MonetaryAmount instead of the corresponding generated XML type and the relevant @XmlJavaTypeAdapter annotation is in place.

<xsd:schema targetNamespace="urn:book.test"
            xmlns:c="urn:complextypeadapter.test"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <xsd:import namespace="urn:complextypeadapter.test" schemaLocation="Amount.xsd" />

  <xsd:complexType name="Book">
        <xsd:sequence>
          <xsd:element name="isbn" type="xsd:string" />
          <xsd:element name="price" type="c:Amount" />
        </xsd:sequence>
  </xsd:complexType>

</xsd:schema>
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Book", propOrder = {
    "isbn",
    "price"
})
public class Book {

    @XmlElement(required = true)
    protected String isbn;

    @XmlElement(required = true, type = Amount.class)
    @XmlJavaTypeAdapter(AmountXmlAdapter.class)
    protected MonetaryAmount price;

    ...

}

Versions

Version
0.0.4
0.0.3
0.0.2
0.0.1