My question concerns writing JAXB plugins, in particular ClassOutline
internals.
In com.sun.tools.xjc.outline.ClassOutline
there are fields:
- target
- ref
- implClass
- implRef
Code:
/**
* This {@link ClassOutline} holds information about this {@link CClassInfo}.
*/
public final @NotNull CClassInfo target;
/**
* The exposed aspect of the a bean.
*
* implClass is always assignable to this type.
* <p>
* Usually this is the public content interface, but
* it could be the same as the implClass.
*/
public final @NotNull JDefinedClass ref;
/**
* The implementation aspect of a bean.
* The actual place where fields/methods should be generated into.
*/
public final @NotNull JDefinedClass implClass;
/**
* The implementation class that shall be used for reference.
* <p>
* Usually this field holds the same value as the {@link #implClass} method,
* but sometimes it holds the user-specified implementation class
* when it is specified.
* <p>
* This is the type that needs to be used for generating fields.
*/
public final @NotNull JClass implRef;
As far as I know (SO Answer):
target
- holds information inModel
, which represents parsed and analysed schema file (.xsd)ref
is usually equals toimplClass
and both holdsCode Model
implClass
is the right place to put newly generated fields, method, etc.implRef
- what is it?
I want to add new field to class described by ClassOutline
, so the code looks like this:
JDefinedClass dstClass = classOutline.ref;
JFieldVar dstField = dstClass.field(srcField.mods().getValue(),
srcField.type(), srcField.name());
It works great, until there is another plugin which works after above code is executed and uses com.sun.tools.xjc.outline.ClassOutline.getDeclaredFields()
method.
Imagine - Plugin1
creates new fields and then CopyablePlugin is executed and wants to add clone()
method, which copy every field. But CopyablePlugin
doesn't see fields newly generated by Plugin1
- because to retrieve all fields from ClassOutline
the CopyablePlugin
uses com.sun.tools.xjc.outline.ClassOutline.getDeclaredFields()
method which looks like:
/**
* Gets all the {@link FieldOutline}s newly declared
* in this class.
*/
public final FieldOutline[] getDeclaredFields() {
List<CPropertyInfo> props = target.getProperties();
// ...
Notice, that getDeclaredFields()
retrieves properties from ClassOutline.target
field (this's the Model
- parsed XSD schema) and completely ignores code generated to ClassOutline.implClass
.
Is it a bug or a feature?
For now I found workaround. The same field is also added as property to target
:
classOutline.target.addProperty(prop);
Questions
- Could you explain me, what is the role of
ref/implClass/implRef
? - Where I should generate completely new fields/method? Into
ref/implClass
? - Does it necessary to keep consistency between
ref/implClass
andtarget
? New field added toimplClass
should be also added totarget
, right? - Is
com.sun.tools.xjc.outline.ClassOutline.getDeclaredFields()
correct? Or How properly retrieve all fields from ClassOutline? Maybe this should be union oftarget
andimplClass
content?