I’m currently trying to model the Spring LDAP Filters in my XML schema. This involves polymorphic types, which can be arbitrarily nested:
<andFilter>
<notFilter>
<equalsFilter name="mail" value="asfd@example.com" />
</notFilter>
<likeFilter name="mail" value="asdf*" />
</andFilter>
This is how I’m defining the above filters in my xsd (I actually have some intermediate abstract types defined, but left them out for simplicity):
<xsd:complexType name="baseFilterType" abstract="true" />
<xsd:element name="filter" type="tns:baseFilterType" />
<xsd:complexType name="andFilterType">
<xsd:sequence>
<xsd:element ref="tns:filter" minOccurs="1" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:element name="andFilter" type="tns:andFilterType" substitutionGroup="tns:filter" />
<xsd:complexType name="notFilterType">
<xsd:sequence>
<xsd:element ref="tns:filter" />
</xsd:sequence>
</xsd:complexType>
<xsd:element name="notFilter" type="tns:notFilterType" substitutionGroup="tns:filter" />
<xsd:complexType name="likeFilterType">
<xsd:sequence>
<xsd:element ref="tns:attributeName" />
<xsd:element ref="tns:value" />
</xsd:sequence>
</xsd:complexType>
<xsd:element name="likeFilter" type="tns:likeFilterType" substitutionGroup="tns:filter" />
<xsd:complexType name="equalsFilterType">
<xsd:sequence>
<xsd:element ref="tns:attributeName" />
<xsd:element ref="tns:value" />
</xsd:sequence>
</xsd:complexType>
<xsd:element name="equalsFilter" type="tns:equalsFilterType" substitutionGroup="tns:filter" />
I’ve extended each of the filter classes with some custom behavior (to implement the visitor pattern), but I can’t figure out how to have JAXB bind to those instead of JAXBElement<? extends BaseFilterType> that’s used throughout the generated classes.
The JAXB model classes are generated at build time, and so I can’t modify them directly — I must use external custom bindings for any customizations. I’ve tried the implClass and baseClass customizations but haven’t been able to figure out how to do it.
Can anyone help?
Edit: I’m using Spring’s Jaxb2Marshaller with contextPaths set for marshalling and unmarshalling. I expected this to utilize ObjectFactory for object instantiation, but that doesn’t seem to be the case.
Edit 2: The filter elements are referenced by the top-level element as well as by each other, like:
<xsd:element name="GetAttributesRequest">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="filter:filter" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
So, the GetAttributesRequest object will be marked with @XmlRootElement while the filter classes themselves will not be. However, even the top-level GetAttributesRequest object isn’t being instantiated by ObjectFactory…
Edit :
Solution used by question author :
Original answer :
Yes, it’s possible to add behaviors to the generated classes. You want to have a look at the related documentation
Here’s a simple example from the documentation :
JAXB Generated Code
Extended class
package org.acme.foo.impl;
Example of Unmarshalling
More info here