JAXB绑定从非抽象XML类型生成抽象Java类 简言之
是否有任何JAXB绑定可以告诉JAXB代码生成器生成一个Java类作为JAXB绑定从非抽象XML类型生成抽象Java类 简言之,xml,binding,jaxb,xjc,Xml,Binding,Jaxb,Xjc,是否有任何JAXB绑定可以告诉JAXB代码生成器生成一个Java类作为abstract,而不必在XSD中将相应的XML类型标记为abstract 描述 情况如下: 我在XSD中定义了一个模式:mySchema.XSD 我使用内联JAXB绑定(“直接在模式中内联”==”来指示应在其中生成JAXB类的包(my.package.JAXB): 我从模式生成JAXB类。这导致: my.package.jaxb |- MyAbstractType |- MyAType (extends My
abstract
,而不必在XSD中将相应的XML类型标记为abstract
描述
情况如下:
- 我在XSD中定义了一个模式:
mySchema.XSD
- 我使用内联JAXB绑定(“直接在模式中内联”==”来指示应在其中生成JAXB类的包(
):my.package.JAXB
- 我从模式生成JAXB类。这导致:
my.package.jaxb |- MyAbstractType |- MyAType (extends MyAbstractClass) |- MyBType (extends MyAbstractClass)
- 我自己写课程:
my.package.impl |- MyAbstractClass (extends MyAbstractType) |- MyAClass (extends MyAType) |- MyBClass (extends MyBType)
my.package.jaxb.
)与手册(my.package.impl.
)分开。这样,当XSD中发生更改时,我可以重新生成my.package.jaxb.*
类,并在我的手册my.package.impl.*
类中进行一些更改,以合并新的行为
到目前为止还不错。问题是,在MyAbstractClass
中,我想定义一个抽象的方法
protected abstract void doSomething();
…然后通过MyAClass
和MyBClass
以不同的方式实现。
但是,生成的MyAType
和MyBType
类现在有编译错误,因为它们没有声明为抽象类,但它们现在继承了一个抽象方法(请注意,它们都扩展了MyAbstractClass
)
我不能在XSD中将它们声明为抽象(abstract=“true”
),因为这样做会导致以下错误,无论何时我在XML中声明类型为myAType
或myBType
:
cvc-type.2: The type definition cannot be abstract for element someElementName.
我想使用一些JAXB绑定告诉JAXB代码生成器将类MyAType
和MyBType
生成为abstract
,而不必将XML类型标记为abstract
。有这样的约束吗?到目前为止我还没有找到它
很抱歉解释得太长,请提前感谢。我最终创建了一个。代码如下:
import java.lang.reflect.Method;
导入javax.xml.namespace.QName;
导入org.xml.sax.ErrorHandler;
导入org.xml.sax.SAXException;
导入com.sun.codemodel.JMod;
导入com.sun.codemodel.JMods;
导入com.sun.tools.xjc.Options;
导入com.sun.tools.xjc.outline.ClassOutline;
导入com.sun.tools.xjc.outline.outline;
导入com.sun.tools.xjc.reader.xmlschema.bindinfo.BIDeclaration;
导入com.sun.tools.xjc.reader.xmlschema.bindinfo.bindinfo;
导入com.sun.xml.xsom.xsm注释;
公共类AbstractModifierPlugin扩展com.sun.tools.xjc.Plugin{
私有静态最终QName抽象_QName=新QName(“http://www.example.com/jaxb/abstract-modifier/1-0“,”摘要“);
私有静态最终字符串集\u标志\u方法\u NAME=“setFlag”;
私有静态最终字符串选项\u NAME=“Xabstract修饰符”;
@凌驾
公共字符串getOptionName(){
返回选项名称;
}
@凌驾
公共字符串getUsage(){
return“-”+OPTION_NAME+”:将与标记为“”的XML类型对应的生成类标记为抽象类
+ "";
}
@凌驾
公共布尔运行(大纲、选项、ErrorHandler ErrorHandler)引发SAXException{
方法setFlagMethod=null;
试一试{
//没有使类抽象的方法;我们只能使用setFlag,它是私有的,因此
//我们必须通过反思来获得它,并使其易于访问。
setFlagMethod=JMods.class.getDeclaredMethod(SET_FLAG_METHOD_NAME,int.class,boolean.class);
setFlagMethod.setAccessible(true);
}捕获(可丢弃的e){
System.err.println(“检索“+JMods.class.getName()+”+SET_FLAG_方法_名称时出错
+“方法(见下文)=>无法设置任何类的抽象标志=>此插件将中止”);
e、 printStackTrace();
返回false;
}
for(类大纲:outline.getClasses()){
if(hasAbstractAnnotation(classOutline)){
试一试{
调用(classOutline.implClass.mods(),JMod.ABSTRACT,true);
}捕获(可丢弃的e){
System.err.println(“无法生成”+classOutline.implClass.fullName()
+“摘要(见下文)”;
e、 printStackTrace();
}
}
}
返回true;
}
受保护的布尔hasAbstractAnnotation(ClassOutline ClassOutline){
XSAnnotation annotation=classOutline.target.getSchemaComponent().getAnnotation();
if(注释!=null){
对象innerAnnotation=annotation.getAnnotation();
if(BindInfo的innerAnnotation实例){
for(BIDeclaration bindInfoDeclaration:(BindInfo)innerAnnotation){
if(ABSTRACT_QNAME.equals(bindInfoDeclaration.getName())){
返回true;
}
}
}
}
返回false;
}
}
下面是abstract.xsd
,它定义了用于指示生成的类应为抽象类的
元素:
用法(按照我原来问题中的示例):
...
...
my.package.impl
|- MyAbstractClass (extends MyAbstractType)
|- MyAClass (extends MyAType)
|- MyBClass (extends MyBType)
cvc-type.2: The type definition cannot be abstract for element someElementName.