自定义JAXB(xjc)绑定编译器以使用空列表实例化列表成员

时间:2013-09-04 08:44:13

标签: java jaxb

是否可以使用Java XML绑定编译器(xjc)生成代码,该编译器使用空列表而不是null来实例化列表成员?

示例

XSD-File FooBar.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://foo.bar"
    targetNamespace="http://foo.bar" version="1.0">

    <xs:complexType name="FooBar">
        <xs:sequence>
            <xs:element name="entry" type="xs:string"
                maxOccurs="unbounded" minOccurs="0" />
        </xs:sequence>
    </xs:complexType>

</xs:schema>

使用此文件运行绑定编译器,例如

xjc FooBar.xsd

像这样生成Java源代码

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "FooBar", propOrder = {
    "entry"
})
public class FooBar {

    protected List<String> entry;

    public List<String> getEntry() {
        if (entry == null) {
            entry = new ArrayList<String>();
        }
        return this.entry;
    }

}

使用null实例化条目列表,并在getter方法中完成空检查。但我需要使用空列表实例化条目mamber:

 protected List<String> entry = new ArrayList<String>();

这在某种程度上可以通过自定义吗?我没找到怎么样?

1 个答案:

答案 0 :(得分:3)

嗯,Ben Thurley's suggestion是个好人。但是,我一直在研究但未完全完成的另一种方法是创建一个插件。

我写了一篇short tutorial,关于如何创建一个允许你实例化字段的XJC插件。

添加以下行:

f.init(JExpr._new(co.parent().getCodeModel().ref(ArrayList.class)));

我能够生成以下代码:

@XmlElement(required = true)
protected List<Word> word = new ArrayList();

再次,没有完成,但很有希望;)

<强>更新

run()方法中:替换以下if语句

if (types.contains(f.type())){ 
    //If the type is defined in the schema
    //3. Instantiate
    f.init(JExpr._new(f.type())); 
}

使用以下if语句

if (f.type().boxify().getTypeParameters()!=null && 
    f.type().boxify().getTypeParameters().size()==1){
        // f.type() is a list
        JType inner = f.type().boxify().getTypeParameters().get(0);
    f.init(JExpr._new(co.parent().getCodeModel()
            .ref(ArrayList.class).narrow(inner)));
}

它将正确实例化带参数化的数组列表。

这里的if语句基本上是说,如果这个类型是参数化的,并且如果参数的数量正好是一个(两个意味着它是一个映射),则假定它是一个列表并将其实例化为ArrayList。方法narrow()执行参数化。

更新2

因为创建插件可能看起来很多工作。我已经提交了我一直致力于GitHub的插件。此插件现在可以实例化字段,列表(到ArrayLists),甚至将列表转换为Set!

现在你需要做的就是获取插件。使用mvn install安装它。这将它添加到您的pom文件中,如GitHub上的自述文件所示。

我认为这是最接近“配置可能性”的方法。

玩得开心!