The Java EE 5 Tutorial

Customization Overview

This section explains some core JAXB customization concepts:

Inline and External Customizations

Customizations to the default JAXB bindings are made in the form of binding declarations passed to the JAXB binding compiler. These binding declarations can be made in either of two ways:

For some people, using inline customizations is easier because you can see your customizations in the context of the schema to which they apply. Conversely, using an external binding customization file enables you to customize JAXB bindings without having to modify the source schema, and enables you to easily apply customizations to several schema files at once.


Note –

You can combine the two types of customizations. For example, you could include a reference to an external binding customizations file in an inline annotation. However, you cannot declare both an inline and external customization on the same schema element.


Each of these types of customization is described in more detail below.

Inline Customizations

Customizations to JAXB bindings made by means of inline binding declarations in an XML schema file take the form of <xsd:appinfo> elements embedded in schema <xsd:annotation> elements (xsd: is the XML schema namespace prefix, as defined in W3C XML Schema Part 1: Structures). The general form for inline customizations is shown below.

<xs:annotation>
   <xs:appinfo>
      .
      .
      binding declarations      .
      .
   </xs:appinfo>
</xs:annotation>

Customizations are applied at the location at which they are declared in the schema. For example, a declaration at the level of a particular element would apply to that element only. Note that the XMLSchema namespace prefix must be used with the <annotation> and <appinfo> declaration tags. In the example above, xs: is used as the namespace prefix, so the declarations are tagged <xs:annotation> and <xs:appinfo>.

External Binding Customization Files

Customizations to JAXB bindings made by means of an external file containing binding declarations take the general form shown below.

<jxb:bindings schemaLocation = "xs:anyURI">
   <jxb:bindings node = "xs:string">*
      <binding declaration>
   <jxb:bindings>
</jxb:bindings>

For example, the first schemaLocation/node declaration in a JAXB binding declarations file specifies the schema name and the root schema node:

<jxb:bindings schemaLocation="po.xsd" node="/xs:schema">

A subsequent schemaLocation/node declaration, say for a simpleType element named ZipCodeType in the above schema, would take the form:

<jxb:bindings node="//xs:simpleType[@name=’ZipCodeType’]">

Binding Customization File Format

Binding customization files should be straight ASCII text. The name or extension does not matter, although a typical extension, used in this chapter, is .xjb.

Passing Customization Files to the JAXB Binding Compiler

Customization files containing binding declarations are passed to the JAXB Binding compiler, xjc, using the following syntax:

xjc -b file schema

where file is the name of binding customization file, and schema is the name of the schema or schemas you want to pass to the binding compiler.

You can have a single binding file that contains customizations for multiple schemas, or you can break the customizations into multiple bindings files; for example:

xjc schema1.xsd schema2.xsd schema3.xsd -b bindings123.xjb
xjc schema1.xsd schema2.xsd schema3.xsd -b bindings1.xjb -b bindings2.xjb -b bindings3.xjb

Note that the ordering of schema files and binding files on the command line does not matter, although each binding customization file must be preceded by its own -b switch on the command line.

For more information about xjc compiler options in general, see JAXB Compiler Options.

Restrictions for External Binding Customizations

There are several rules that apply to binding declarations made in an external binding customization file that do not apply to similar declarations made inline in a source schema:

To summarize these rules, the external binding element <jxb:bindings> is only recognized for processing by a JAXB binding compiler in three cases:

Scope, Inheritance, and Precedence

Default JAXB bindings can be customized or overridden at four different levels, or scopes.

Figure 17–3 illustrates the inheritance and precedence of customization declarations. Specifically, declarations towards the top of the pyramid inherit and supersede declarations below them. For example, Component declarations inherit from and supersede Definition declarations; Definition declarations inherit and supersede Schema declarations; and Schema declarations inherit and supersede Global declarations.

Figure 17–3 Customization Scope Inheritance and Precedence

Diagram of scope inheritance. Top to bottom: Component
Scope, Definition Scope, Schema Scope, and Global Scope.

Customization Syntax

The syntax for the four types of JAXB binding declarations, as well as the syntax for the XML-to-Java data type binding declarations and the customization namespace prefix, are described below.

Global Binding Declarations

Global scope customizations are declared with <globalBindings>. The syntax for global scope customizations is as follows:

<globalBindings>
    [ collectionType = "collectionType" ]
    [ fixedAttributeAsConstantProperty    = "true" | "false" | "1" | "0" ]
    [ generateIsSetMethod    = "true" | "false" | "1" | "0" ]
    [ enableFailFastCheck = "true" | "false" | "1" | "0" ]
    [ choiceContentProperty = "true" | "false" | "1" | "0" ]
    [ underscoreBinding = "asWordSeparator" | "asCharInWord" ]
    [ typesafeEnumBase = "typesafeEnumBase" ]
    [ typesafeEnumMemberName = "generateName" | "generateError" ]
    [ enableJavaNamingConventions = "true" | "false" | "1" | "0" ]
    [ bindingStyle = "elementBinding" | "modelGroupBinding" ]
    [ <javaType> ... </javaType> ]*
</globalBindings>

<globalBindings> declarations are only valid in the annotation element of the top-level schema element. There can only be a single instance of a <globalBindings> declaration in any given schema or binding declarations file. If one source schema includes or imports a second source schema, the <globalBindings> declaration must be declared in the first source schema.

Schema Binding Declarations

Schema scope customizations are declared with <schemaBindings>. The syntax for schema scope customizations is:

<schemaBindings>
    [ <package> package </package> ]
    [ <nameXmlTransform> ... </nameXmlTransform> ]*
</schemaBindings>
    
<package [ name = "packageName" ]
    [ <javadoc> ... </javadoc> ]
</package>

<nameXmlTransform>
    [ <typeName [ suffix="suffix" ]
                [ prefix="prefix" ] /> ]
    [ <elementName [ suffix="suffix" ]
                   [ prefix="prefix" ] /> ]
    [ <modelGroupName [ suffix="suffix" ]
                      [ prefix="prefix" ] /> ]
    [ <anonymousTypeName [ suffix="suffix" ]
                         [ prefix="prefix" ] /> ]
</nameXmlTransform>

As shown above, <schemaBinding> declarations include two subcomponents:

Class Binding Declarations

The <class> binding declaration enables you to customize the binding of a schema element to a Java content interface or a Java Element interface. <class> declarations can be used to customize:

The syntax for <class> customizations is:

<class [ name = "className"]
   [ implClass= "implClass" ] >
   [ <javadoc> ... </javadoc> ]
</class>

Property Binding Declarations

The <property> binding declaration enables you to customize the binding of an XML schema element to its Java representation as a property. The scope of customization can either be at the definition level or component level depending upon where the <property> binding declaration is specified.

The syntax for <property> customizations is:

<property
    [ name = "propertyName"]
    [ collectionType = "propertyCollectionType" ]
    [ fixedAttributeAsConstantProperty = "true" | "false" | "1" | "0" ]
    [ generateIsSetMethod = "true" | "false" | "1" | "0" ]
    [ enableFailFastCheck ="true" | "false" | "1" | "0" ]
    [ <baseType> ... </baseType> ]
    [ <javadoc> ... </javadoc> ]
</property>

<baseType>
    <javaType> ... </javaType>
</baseType>

javaType Binding Declarations

The <javaType> declaration provides a way to customize the translation of XML data types to and from Java data types. XML provides more data types than Java, and so the <javaType> declaration lets you specify custom data type bindings when the default JAXB binding cannot sufficiently represent your schema.

The target Java data type can be a Java built-in data type or an application-specific Java data type. If an application-specific data type is used as the target, your implementation must also provide parse and print methods for unmarshalling and marshalling data. To this end, the JAXB specification supports a parseMethod and printMethod:

If you prefer to define your own data type conversions, JAXB defines a static class, DatatypeConverter, to assist in the parsing and printing of valid lexical representations of the XML Schema built-in data types.

The syntax for the <javaType> customization is:

<javaType name= "javaType"
    [ xmlType= "xmlType" ]
    [ hasNsContext = "true" | "false" ]
    [ parseMethod= "parseMethod" ]
    [ printMethod= "printMethod" ]>

The <javaType> declaration can be used in:

See MyDatatypeConverter Class for an example of how <javaType> declarations and the DatatypeConverterInterface interface are implemented in a custom data type converter class.

Typesafe Enumeration Binding Declarations

The typesafe enumeration declarations provide a localized way to map XML simpleType elements to Java typesafe enum classes. There are two types of typesafe enumeration declarations you can make:

In both cases, there are two primary limitations on this type of customization:

The syntax for the <typesafeEnumClass> customization is:

<typesafeEnumClass
    [ name = "enumClassName" ]
    [ <typesafeEnumMember> ... </typesafeEnumMember> ]*
    [ <javadoc> enumClassJavadoc </javadoc> ]
</typesafeEnumClass>

The syntax for the <typesafeEnumMember> customization is:

<typesafeEnumMember name = "enumMemberName">
                    [ value = "enumMemberValue" ]
    [ <javadoc> enumMemberJavadoc </javadoc> ]
</typesafeEnumMember>

For inline annotations, the <typesafeEnumClass> declaration must be specified in the annotation element of the <simpleType> element. The <typesafeEnumMember> must be specified in the annotation element of the enumeration member. This allows the enumeration member to be customized independently from the enumeration class.

For information about typesafe enum design patterns, see the sample chapter of Joshua Bloch’s Effective Java Programming on the Java Developer Connection.

javadoc Binding Declarations

The <javadoc> declaration lets you add custom Javadoc tool annotations to schema-derived JAXB packages, classes, interfaces, methods, and fields. Note that <javadoc> declarations cannot be applied globally; they are only valid as sub-elements of other binding customizations.

The syntax for the <javadoc> customization is:

<javadoc>
    Contents in &lt;b>Javadoc&lt;\b> format.
</javadoc>

or

<javadoc>
    <<![CDATA[
    Contents in <b>Javadoc<\b> format
    ]]>
</javadoc>

Note that documentation strings in <javadoc> declarations applied at the package level must contain <body> open and close tags; for example:

<jxb:package name="primer.myPo">
  <jxb:javadoc>
    <![CDATA[<body>Package level documentation for generated package primer.myPo.</body>]]>
  </jxb:javadoc>
</jxb:package>

Customization Namespace Prefix

All standard JAXB binding declarations must be preceded by a namespace prefix that maps to the JAXB namespace URI (http://java.sun.com/xml/ns/jaxb). For example, in this sample, jxb: is used. To this end, any schema you want to customize with standard JAXB binding declarations must include the JAXB namespace declaration and JAXB version number at the top of the schema file. For example, in po.xsd for the Customize Inline example, the namespace declaration is as follows:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
            jxb:version="1.0">

A binding declaration with the jxb namespace prefix would then take the form:

<xsd:annotation>
   <xsd:appinfo>
      <jxb:globalBindings binding declarations />
      <jxb:schemaBindings>
         .
         .
         binding declarations         .
         .
      </jxb:schemaBindings>
   </xsd:appinfo>
</xsd:annotation>

Note that in this example, the globalBindings and schemaBindings declarations are used to specify, respectively, global scope and schema scope customizations. These customization scopes are described in more detail in Scope, Inheritance, and Precedence.