Reputation: 949
Using this (demo) schema, I am generating Java objects with JAXB:
<xsd:complexType name="someType">
<xsd:sequence>
<xsd:element name="myOtherType" type="otherType" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="otherType">
<!-- ... -->
</xsd:complexType>
This class gets generated:
@XmlType
public class SomeType {
@XmlElement(name = "myOtherType")
OtherType myOtherType;
}
But I would like to use interfaces instead of implementations in my JAXB-generated objects.
So I write this interface:
public interface OtherTypeInterface {
// ....
}
And I let the generated OtherType class implement it, with the help of a binding file:
<jxb:bindings node="//xs:complexType[@name='otherType']">
<inheritance:implements>com.example.OtherTypeInterface</inheritance:implements>
</jxb:bindings>
So far, so good:
public class OtherType implements OtherTypeInterface {
// ...
}
But I need the SomeType object to use this interface too, instead of the OtherType implementation. As suggested in the unofficial JAXB guide in section 3.2.2. Use @XmlJavaTypeAdapter, I would like to use a homemade XML adapter to map OtherType to its interface, and vice-versa:
public class HcpartyTypeAdapter extends XmlAdapter<OtherType, OtherTypeInterface> {
@Override
public OtherTypeInterface unmarshal(OtherType v) throws Exception {
return v;
}
@Override
public OtherType marshal(OtherTypeInterface v) throws Exception {
return (OtherType) v;
}
}
But it looks like mapping an XML complex type in my binding file with the following configuration is a big no-no:
<jxb:globalBindings>
<xjc:javaType name="com.example.OtherTypeInterface" xmlType="ex:otherType" adapter="com.example.OtherTypeAdapter"/>
</jxb:globalBindings>
The generation fails with this error:
com.sun.istack.SAXParseException2; systemId: file:/.../bindings.xjb; lineNumber: 8; columnNumber: 22; undefined simple type "{http://www.example.com}otherType".
With a bit of googling, I've found out that it is apparently impossible to use XML adapters for complex types in schema-generated classes. However, if I'm manually editing the files to use my adapter, it works perfectly:
public class SomeType {
@XmlElement(name = "myOtherType")
@XmlJavaTypeAdapter(OtherTypeAdapter.class)
@XmlSchemaType(name = "otherType")
OtherTypeInterface myOtherType;
}
I can marshal and unmarshal it flawlessly; but it seems to me that editing the generated classes defeats the whole purpose of the automatic processing. I'm dealing with multiple schemas defining many, many types.
So my question is: does anyone know a workaround to use XML adapters to map XML complex types to Java objects in schema-generated classes without resorting to manually edit the code?
Potential answer here: https://stackoverflow.com/a/1889584/946800. I'm hoping that since 2009, someone may have found some way to solve this issue...
Upvotes: 1
Views: 2316
Reputation: 1089
you can use jaxb2 annotate
maven plugin to add annotations to the generated JAXB
classes.
<plugin>
<!-- this plugin is used to add annotation for the models -->
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics-annotate</artifactId>
<version>1.0.2</version>
</plugin>
In the .xjb
bindings,
<jxb:bindings schemaLocation="sample.xsd">
<jxb:bindings node="//xs:complexType[@name='otherType']">
<annox:annotate target="field">
<annox:annotate annox:class="@javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter"
value="com.example.OtherTypeAdapter.class" />
</annox:annotate>
</jxb:bindings>
</jxb:bindings>
Upvotes: 1