# JavaTM Architecture for XML Binding

## Implications of Type Substitution for Subclassing

Specification Version: 1.0
Reference Implementation (RI) Version: 1.0.6

Main: Release Notes | XJC | Ant task | Sample Apps | Changelog
JAXB RI Extensions: Runtime Properties | XJC Customizations
JAXB RI Schema Languages: W3C XML Schema | RELAX NG | DTD
JAXB Community: Java.net Homepage | Developer interest list | FAQ

You can enable type substitution support in your bindings by adding a customization to your schema and using the `-extension` switch when you recompile. This may have implications for your application if, in addition, your bindings support application-specific subclasses incorporated by way of the `implClass` customization.

To support type substitution, a schema-derived element impl class no longer extends its type's impl class. Instead, the element impl class has a reference to an instance of that type or any type that extends the element's schema defined type.

For example, given this schema,

>     <element name="foo" type="Base"/>
>     <complexType name="Base"> ...
>     <complexType name="Derived">... <xs:extension base="Base">

The generated impl class for element foo used to be:

>     impl/Foo.java
>     class Foo extends impl.Base {}

To support type substitution that allows instances of "Derived" to be associated with element foo, the following code is generated by JAXB 1.0.2 xjc with extension mode on:

>     impl/Foo.java
>     class Foo implements Base {
>        Base getValueObject();
>        /** val can be of type "Base" or "Derived"
>        void setValueObject(Base val);

>        // all methods on Base can be called.
>     }

If your subclass contains the method `methodInSubclass`, let's say, and you created your bindings without type substitution support, you can access `methodInSubclass` simply by casting the returned `Element` instance down to your subclass:

>     ((subclass)FooElementInstance).methodInSubclass

However, if you regenerate your bindings with type substitution support, this technique now results in a `ClassCastException` at runtime. The fix is to cast the object returned by the unmarshalled object's `getValueObject()` method down to your subclass.

For example, let's say you have a `MyUSAddress` class that extends the schema-derived class `primer.address.USAddress`. That is, your schema contains:

>     <xsd:annotation>
>       <xsd:appinfo>
>         <jxb:schemaBindings>
>           <jxb:package name="primer.address"/>
>         </jxb:schemaBindings>
>       </xsd:appinfo>
>     </xsd:annotation>

>     <xsd:complexType name="USAddress">
>       <xsd:annotation>
>         <xsd:appinfo>
>           <jxb:class implClass="primer.MyUSAddress"/>
>         </xsd:appinfo>
>       </xsd:annotation>
>     .
>     .
>     .

If your schema's not customized for type substitution, then the following application code would work with the resulting bindings:

>     primer.MyUSAddress myAddr =
>         (primer.MyUSAddress)u.unmarshal(new FileInputStream("address.xml"));

where `address.xml` contains:

>     <Address country="US">
>         <name>Alice Smith</name>
>         <street>123 Maple Street</street>
>         <city>Cambridge</city>
>         <state>MA</state>
>         <zip>12345</zip>
>     </Address>

That is, it would be okay to cast the unmarshalled object down to your `primer.MyUSAddress`.

However if, for some reason, you were to add an `typeSubstitution` customization to your schema and recompile, your application would fail with a `ClassCastException`. The fix is to cast the object returned by the `getValueObject()` method that the schema-derived class now contains down to `MyUSAddress`:

>     Address addr = (Address)u.unmarshal(new FileInputStream("address.xml"));
>     primer.MyUSAddress myAddr=(primer.MyUSAddress)addr.getValueObject();

Type substitution support is experimental at present. JAXB 2.0 will specify the standard binding for type substitution.

$Revision: 1.1 $
$Date: 2008/11/03 06:51:11 $