JAXB绑定从非抽象XML类型生成抽象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

是否有任何JAXB绑定可以告诉JAXB代码生成器生成一个Java类作为
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.