我的问题是关于编写JAXB插件,特别是ClassOutline
内部。
在com.sun.tools.xjc.outline.ClassOutline
中有字段:
代码:
/**
* 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;
据我所知(CORS):
target
- 保存Model
中的信息,代表已解析和分析的模式文件(.xsd)ref
通常等于implClass
并且都保持Code Model
implClass
是放置新生成的字段,方法等的正确位置。implRef
- 它是什么?我想将新字段添加到ClassOutline
描述的类中,因此代码如下所示:
JDefinedClass dstClass = classOutline.ref;
JFieldVar dstField = dstClass.field(srcField.mods().getValue(),
srcField.type(), srcField.name());
它很有效,直到有另一个插件在上面的代码执行后运行并使用com.sun.tools.xjc.outline.ClassOutline.getDeclaredFields()
方法。
想象一下 - Plugin1
创建新字段然后执行SO Answer并想要添加clone()
方法,该方法会复制每个字段。但是CopyablePlugin
没有看到Plugin1
新生成的字段 - 因为从ClassOutline
CopyablePlugin
使用com.sun.tools.xjc.outline.ClassOutline.getDeclaredFields()
方法检索所有字段,如下所示:
/**
* Gets all the {@link FieldOutline}s newly declared
* in this class.
*/
public final FieldOutline[] getDeclaredFields() {
List<CPropertyInfo> props = target.getProperties();
// ...
请注意,getDeclaredFields()
从ClassOutline.target
字段(这是Model
- 已解析的XSD架构)中检索属性,并完全忽略生成的代码ClassOutline.implClass
。< / p>
是错误还是功能?
目前我找到了解决方法。同一字段也作为属性添加到target
:
classOutline.target.addProperty(prop);
问题
ref/implClass/implRef
的作用是什么?ref/implClass
?ref/implClass
和target
之间的一致性?添加到implClass
的新字段也应添加到target
,对吧?com.sun.tools.xjc.outline.ClassOutline.getDeclaredFields()
是否正确?或者如何从ClassOutline中正确检索所有字段?也许这应该是target
和implClass
内容的结合?答案 0 :(得分:1)
我建议不要在ClassOutline
添加字段。太晚了,太麻烦了。相信我,我已经尝试过了。
我发现更容易,更优雅的是向CClassInfo
添加属性。这是一个阶段,在这里你操纵模型。然后在下一步中,将从模型生成轮廓,这样您甚至不必关心向ClassOutline
添加任何内容。
要向CClassInfo
添加属性,只需实例化该属性(例如new CAttributePropertyInfo(...)
),然后将其添加到CClassInfo
:myClassInfo.addProperty(myPropertyInfo);
。
对于Copyable
插件,如果您的插件向模型添加属性并且您的插件在Copyable
插件之前被调用,则后者将看到新添加的字段。这正是我建议扩充模型的原因,而不是破解大纲或代码模型。
现在回答你的问题。
ref
/ implClass
/ implRef
通常都只是目标生成的类。分离是由于XJC产生的一些代modi和公共接口&#34;和#34;实施课程&#34;分别。我不知道implRef
是什么,JavaDoc说了一些关于用户指定类的内容,所以我想到了jaxb:class/@ref
绑定。但是从来没有处理过它。
最好是扩充模型(如果要添加新属性/字段)。如果您想添加一些与模型无关的代码(例如clone
插件中的Copyable
方法),我只需将其添加到classOutline.implClass
。
从技术上讲,无需保持代码模型(classOutline.implClass
)和模型(classOutline.target
)同步。如果你不这样做,这不会打破XJC。我可以想象这可能会破坏一些XJC插件。例如,插件可以迭代JDefinedClass
中的字段并尝试查找相应的模型属性。但危险是理论上的。
ClassOutline.getDeclaredFields()
正确,但它只为您提供此类中声明的字段 - 没有来自超类的字段。但是递归地收集所有字段是非常微不足道的。
getDeclaredFields()
根据FieldOutline
target
中的属性生成CClassInfo
个。
忘记implClass
,这只是ClassOutline
的代表。
所以&#34; target
和implClass
&#34;的结合没有多大意义。