Reputation: 1884
Using the latest JAXB (Metro) and generating Java with XJC....
Want to (as other users have asked) generate java.util.Set as a type for fields that represent unbounded sequences. Looks like that type of field is captured by XJC as a UntypedListField and the default behavior is to generate java.util.List (only the getter). If I do something similar to the collection-setter-injector plugin and adjust the field's type like
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
}
}
}
How do people adjust the type or is it easier to construct a new field then replace it in the set of declared fields in the class outline? How does messing with the field's type effect the generation of the get method on the property?
Upvotes: 3
Views: 904
Reputation: 666
Looks like you're going for your own XJC Plugin. So here's what you need to do. Replace your --> DO SOMETHING WITH THIS FIELD
line with the following.
First, figure out what's the parameterization type of fo[i]
(which I'm calling f).
Then, create the Set JType. And finally set the type of f
to setType
:
JType inner = ((JClass)f.type()).getTypeParameters().get(0);
JType setType = co.parent().getCodeModel().ref(Set.class).narrow(inner);
f.type(setType);
The method narrow()
is used to set the parametrization type.
Looks good so far, the problem however is that the plugin will run after XJC is done generating the classes. Which means that the getter is already there. So we need to replace it.
And here's the replaceGetter()
method
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()));
}
Hope you find this helpful.
Upvotes: 1