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)refis usually equals toimplClassand both holdsCode ModelimplClassis 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/implClassandtarget? New field added toimplClassshould 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 oftargetandimplClasscontent?