JAXB、XJC:生成字段到 Class 大纲
JAXB, XJC: Generating field to Class Outline
我的问题涉及编写 JAXB 插件,特别是 ClassOutline
内部。
在com.sun.tools.xjc.outline.ClassOutline
中有字段:
- 目标
- 参考
- implClass
- implRef
代码:
/**
* 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;
据我所知(SO Answer):
target
- 在 Model
中保存信息,表示已解析和分析的架构文件 (.xsd)
ref
通常等于 implClass
并且两者都成立 Code Model
implClass
是放置新生成的字段、方法等的正确位置
implRef
- 这是什么?
我想向 ClassOutline
描述的 class 添加新字段,因此代码如下所示:
JDefinedClass dstClass = classOutline.ref;
JFieldVar dstField = dstClass.field(srcField.mods().getValue(),
srcField.type(), srcField.name());
它工作得很好,直到有另一个插件在执行上面的代码并使用 com.sun.tools.xjc.outline.ClassOutline.getDeclaredFields()
方法后工作。
假设 - Plugin1
创建新字段然后执行 CopyablePlugin 并希望添加 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
的代码.
这是错误还是功能?
现在我找到了解决方法。同样的字段也被添加为 属性 到 target
:
classOutline.target.addProperty(prop);
问题
- 你能解释一下吗,
ref/implClass/implRef
的作用是什么?
- 我应该在哪里生成全新的 fields/method?进入
ref/implClass
?
ref/implClass
和target
有必要保持一致吗?添加到 implClass
的新字段也应该添加到 target
,对吗?
com.sun.tools.xjc.outline.ClassOutline.getDeclaredFields()
是否正确?或者如何正确地从 ClassOutline 中检索所有字段?也许这应该是 target
和 implClass
内容的结合?
我建议不要向 ClassOutline
添加字段。太晚了,太麻烦了。相信我,我试过了。
我发现向 CClassInfo
添加属性更容易也更优雅。这是更早的一个阶段,在这里您可以操纵模型。然后在下一步中将从模型生成轮廓,因此您甚至不必关心向 ClassOutline
.
添加任何内容
要将 属性 添加到 CClassInfo
,您只需实例化 属性(例如 new CAttributePropertyInfo(...)
),然后将其添加到 CClassInfo
: myClassInfo.addProperty(myPropertyInfo);
.
在 Copyable
插件的情况下,如果您的插件向模型添加属性并且您的插件在 Copyable
插件之前被调用,则后者将看到新添加的字段。这正是我建议扩充模型而不是破解大纲或代码模型的原因。
现在回答你的问题。
ref
/implClass
/implRef
通常都是生成的目标 class。分离是由于一些生成模式,其中 XJC 分别生成 "public interface" 和 "implementing class"。我不知道 implRef
是什么,JavaDoc 说了一些关于用户指定的 classes 所以我在考虑 jaxb:class/@ref
绑定。不过从来没有处理过。
最好是扩充模型(如果你想添加新的 properties/fields)。如果你想添加一些与模型无关的代码(比如 Copyable
插件中的 clone
方法),我只是将它添加到 classOutline.implClass
.
从技术上讲,无需保持代码模型 (classOutline.implClass
) 和模型 (classOutline.target
) 同步。如果你不这样做,这不会破坏 XJC。我可以想象这可能会破坏一些 XJC 插件。例如,插件可能会遍历 JDefinedClass
中的字段并尝试找到相应的模型属性。但危险是理论上的。
ClassOutline.getDeclaredFields()
是 正确的,但它只为您提供在此 class 中声明的字段 - 没有来自 super[= 的字段73=]。但是递归地收集所有字段是非常微不足道的。
getDeclaredFields()
根据 target
CClassInfo
的属性生成 FieldOutline
s。
忘记 implClass
,那只是 ClassOutline
的表示。
所以"union of target
and implClass
"没有多大意义。
我的问题涉及编写 JAXB 插件,特别是 ClassOutline
内部。
在com.sun.tools.xjc.outline.ClassOutline
中有字段:
- 目标
- 参考
- implClass
- implRef
代码:
/**
* 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;
据我所知(SO Answer):
target
- 在Model
中保存信息,表示已解析和分析的架构文件 (.xsd)ref
通常等于implClass
并且两者都成立Code Model
implClass
是放置新生成的字段、方法等的正确位置implRef
- 这是什么?
我想向 ClassOutline
描述的 class 添加新字段,因此代码如下所示:
JDefinedClass dstClass = classOutline.ref;
JFieldVar dstField = dstClass.field(srcField.mods().getValue(),
srcField.type(), srcField.name());
它工作得很好,直到有另一个插件在执行上面的代码并使用 com.sun.tools.xjc.outline.ClassOutline.getDeclaredFields()
方法后工作。
假设 - Plugin1
创建新字段然后执行 CopyablePlugin 并希望添加 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
的代码.
这是错误还是功能?
现在我找到了解决方法。同样的字段也被添加为 属性 到 target
:
classOutline.target.addProperty(prop);
问题
- 你能解释一下吗,
ref/implClass/implRef
的作用是什么? - 我应该在哪里生成全新的 fields/method?进入
ref/implClass
? ref/implClass
和target
有必要保持一致吗?添加到implClass
的新字段也应该添加到target
,对吗?com.sun.tools.xjc.outline.ClassOutline.getDeclaredFields()
是否正确?或者如何正确地从 ClassOutline 中检索所有字段?也许这应该是target
和implClass
内容的结合?
我建议不要向 ClassOutline
添加字段。太晚了,太麻烦了。相信我,我试过了。
我发现向 CClassInfo
添加属性更容易也更优雅。这是更早的一个阶段,在这里您可以操纵模型。然后在下一步中将从模型生成轮廓,因此您甚至不必关心向 ClassOutline
.
要将 属性 添加到 CClassInfo
,您只需实例化 属性(例如 new CAttributePropertyInfo(...)
),然后将其添加到 CClassInfo
: myClassInfo.addProperty(myPropertyInfo);
.
在 Copyable
插件的情况下,如果您的插件向模型添加属性并且您的插件在 Copyable
插件之前被调用,则后者将看到新添加的字段。这正是我建议扩充模型而不是破解大纲或代码模型的原因。
现在回答你的问题。
ref
/implClass
/implRef
通常都是生成的目标 class。分离是由于一些生成模式,其中 XJC 分别生成 "public interface" 和 "implementing class"。我不知道implRef
是什么,JavaDoc 说了一些关于用户指定的 classes 所以我在考虑jaxb:class/@ref
绑定。不过从来没有处理过。最好是扩充模型(如果你想添加新的 properties/fields)。如果你想添加一些与模型无关的代码(比如
Copyable
插件中的clone
方法),我只是将它添加到classOutline.implClass
.从技术上讲,无需保持代码模型 (
classOutline.implClass
) 和模型 (classOutline.target
) 同步。如果你不这样做,这不会破坏 XJC。我可以想象这可能会破坏一些 XJC 插件。例如,插件可能会遍历JDefinedClass
中的字段并尝试找到相应的模型属性。但危险是理论上的。ClassOutline.getDeclaredFields()
是 正确的,但它只为您提供在此 class 中声明的字段 - 没有来自 super[= 的字段73=]。但是递归地收集所有字段是非常微不足道的。getDeclaredFields()
根据target
CClassInfo
的属性生成FieldOutline
s。 忘记implClass
,那只是ClassOutline
的表示。 所以"union oftarget
andimplClass
"没有多大意义。