XJC生成另一个字段类型(对get方法有影响)

时间:2011-03-02 16:24:37

标签: jaxb xjc

使用最新的JAXB(Metro)并使用XJC生成Java ....

希望(正如其他用户所要求的那样)生成java.util.Set作为表示无界序列的字段的类型。看起来这种类型的字段被XJC捕获为UntypedListField,默认行为是生成java.util.List(只有getter)。如果我执行类似于collection-setter-injector插件的操作并调整字段的类型,如

 public boolean run(Outline model, Options opt, ErrorHandler errorHandler) {
    for (ClassOutline co : model.getClasses()) {
       FieldOutline[] fo = co.getDeclaredFields();

       for ...
          if ((fo[i] instanceof UntypedListField)) {
            --> DO SOMETHING WITH THIS FIELD
          }
    }
 }

人们如何调整类型或者更容易构建新字段然后在类大纲中的声明字段集中替换它?如何搞乱字段的类型会影响属性上get方法的生成?

1 个答案:

答案 0 :(得分:1)

看起来你正在寻找自己的XJC插件。所以这就是你需要做的。将--> DO SOMETHING WITH THIS FIELD行替换为以下内容。

首先,弄清楚fo[i](我称之为f)的参数化类型是什么。 然后,创建Set JType。最后将f的类型设置为setType

JType inner = ((JClass)f.type()).getTypeParameters().get(0);
JType setType = co.parent().getCodeModel().ref(Set.class).narrow(inner);
f.type(setType);

方法narrow()用于设置参数化类型。

到目前为止看起来不错,但问题是该插件将在XJC生成类之后运行。这意味着吸气剂已经存在。所以我们需要更换它。

这是replaceGetter()方法

private void replaceGetter(ClassOutline co, JFieldVar f, JType inner) {
    //Create the method name
    String get = "get";
    String name  = f.name().substring(0, 1).toUpperCase() 
            + f.name().substring(1);
    String methodName = get+name;

    //Create HashSet JType
    JType hashSetType = co.parent().getCodeModel().ref(HashSet.class).narrow(inner);

    //Find and remove Old Getter!
    JMethod oldGetter = co.implClass.getMethod(methodName, new JType[0]);
    co.implClass.methods().remove(oldGetter);

    //Create New Getter
    JMethod getter = co.implClass.method(JMod.PUBLIC, f.type(), methodName);

    //Create Getter Body -> {if (f = null) f = new HashSet(); return f;}
    getter.body()._if(JExpr.ref(f.name()).eq(JExpr._null()))._then()
    .assign(f, JExpr._new(hashSetType));

    getter.body()._return(JExpr.ref(f.name()));
}

希望您觉得这很有帮助。