XJC генерирует другой тип поля (влияет на метод get) - PullRequest
3 голосов
/ 02 марта 2011

Использование последней версии JAXB (Metro) и создание Java с помощью XJC ....

Хотите (как просили другие пользователи) генерировать java.util.Set в качестве типа для полей, которые представляют неограниченные последовательности.Похоже, что этот тип поля захвачен XJC как UntypedListField, и поведение по умолчанию - генерировать java.util.List (только получатель).Если я сделаю что-то похожее на плагин сбора-установки-инжектора и отрегулирую тип поля как

 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 Ответ

1 голос
/ 08 сентября 2013

Похоже, вы собираетесь использовать свой собственный плагин 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()));
}

Надеюсь, вы найдете это полезным.

...