Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAXB classImpl binding (to use specific impl that extends generated impl) but getter return super type

Tags:

java

jaxb

xjc

to wrap some generated classes, i use the classImpl binding but collections in generated classes return the generated type instead of the type in classImpl and i want a list of classImpl of course ...

my xsd:

<complexType name="A">
<xs:sequence>
    <element name="listB" type="sbs:B" minOccurs="0" maxOccurs="unbounded"></element>
    <element name="singleB" type="sbs:B" minOccurs="1" maxOccurs="1"></element>
</xs:sequence>
</complexType>
<complexType name="B">
<xs:annotation><xs:appinfo>
    <jxb:class implClass="BWrapper" />
</xs:appinfo></xs:annotation>
</complexType>

generated classes are:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "A", propOrder = {
    "listB",
    "singleB"
})
public class A {
    @XmlElement(type = BWrapper.class)
    protected List<B> listB;
    @XmlElement(required = true, type = BWrapper.class)
    protected BWrapper singleB;

as expected singleB is typed BWrapper, so, why a listB is a list of B instead of a list of BWrapper ???

thanks in advance for your help !!

like image 766
fedevo Avatar asked Nov 18 '25 23:11

fedevo


1 Answers

You have defined that the type can be implemented by BWrapper. You must explicitly say that the element listB should reference BWrapper.

I couldn't figure out how to set this inline in the schema, so I had to use an external .xjb file.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxb:bindings version="2.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb">
    <!-- bindings in the scope of the schema -->
    <jaxb:bindings schemaLocation="./Test.xsd" node="/xs:schema">

        <!-- apply bindings in the scope of the complex type B. -->
        <jaxb:bindings node="//xs:complexType[@name='B']">
            <!-- the java BWrapper extends the B object created by XJC -->
            <jaxb:class implClass="com.foobar.BWrapper"/>
        </jaxb:bindings>

        <!-- specify bindings in the scope of the element 'listB' within -->
        <!-- the the complex type A -->
        <jaxb:bindings node="//xs:complexType[@name='A']//xs:element[@name='listB']">
            <!-- the element should reference the BWrapper cLass -->
            <jaxb:class ref="com.foobar.BWrapper"/>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>

This will generate:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "A", propOrder = {
    "listB",
    "singleB"
})
public class A {
    protected List<com.foobar.BWrapper> listB;
    @XmlElement(required = true, type = com.foobar.BWrapper.class)
    protected com.foobar.BWrapper singleB;

And the getter for listB returns a list of BWrappers. I'm not sure why there is this inconsistency between single items and lists, but at least this works.

like image 105
user2384226 Avatar answered Nov 21 '25 14:11

user2384226