如何在运行时以编程方式添加 xjc 插件?

How do I add an xjc plugin programmatically at runtime?

我在运行时使用 XJC 从 xsd 生成 JAXB 类。但默认情况下,xsd 中的 maxLength 限制没有注释。

我找到了一个插件来处理这个问题,krasa-jaxb-tools。我已经将依赖项添加到我的 POM 中,但我似乎无法将插件添加到 XJC 进程中。

我使用的是 jaxb-xjc 工具的 2.2.11 版。这是我的依赖项:

<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-xjc</artifactId>
    <version>2.2.11</version>
</dependency>

<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.2.11</version>
</dependency>

<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-core</artifactId>
    <version>2.2.11</version>
</dependency>

<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-jxc</artifactId>
    <version>2.2.11</version>
</dependency>

<dependency>
    <groupId>com.github.krasa</groupId>
    <artifactId>krasa-jaxb-tools</artifactId>
    <version>1.3</version>
</dependency>

我正在尝试实例化插件,对其进行配置并将其传递给 S2JJAXBModel 模型上的 generateCode(Plugins[] extensions, ErrorListener errorListener) 方法,但它似乎没有任何效果。这是我的代码:

SchemaCompiler schemaCompiler = XJC.createSchemaCompiler();
schemaCompiler.forcePackageName(packageRoot);

// JAXB Plugin used to get the proper @Size annotations on all fields.
JaxbValidationsPlugins jaxbValidationPlugin = new JaxbValidationsPlugins();

// Build up list of options for the plugin.
// First option must be the name of the plugin itself.
// Options must be prefixed with dashes
String[] args = new String[] { "-" + JaxbValidationsPlugins.PLUGIN_OPTION_NAME };

try {
    // Activate plugin
    jaxbValidationPlugin.parseArgument(new Options(), args, 0);
} catch (BadCommandLineException | IOException e1) {
    e1.printStackTrace();
}

InputSource inputSource = new InputSource(schemaFile.toURI().toString());

schemaCompiler.parseSchema(inputSource);
S2JJAXBModel model = schemaCompiler.bind();

// Passing the plugin to the method
JCodeModel jCodeModel = model.generateCode(new Plugin[] {jaxbValidationPlugin}, null);

我做错了什么?

下面是 #generateCode() 方法在版本 2.2.11

中的实际实现方式
// com.sun.tools.xjc.api.impl.s2j.JAXBModelImpl.java

public JCodeModel generateCode(Plugin[] extensions,ErrorListener errorListener) {
    // we no longer do any code generation
    return outline.getCodeModel();
}

如您所见,参数被吞没了。

要添加插件,您需要访问 SchemaCompiler 中的 Options 并在那里添加您的插件。还要注意 parseArgument() 调用应该在选项上进行,而不是插件。

以下是实现方法:

SchemaCompiler schemaCompiler = XJC.createSchemaCompiler();
schemaCompiler.forcePackageName(packageRoot);

// JAXB Plugin used to get the proper @Size annotations on all fields.
JaxbValidationsPlugins jaxbValidationPlugin = new JaxbValidationsPlugins();

// Build up list of options for the plugin.
// First option must be the name of the plugin itself.
// Options must be prefixed with dashes
String[] args = new String[] { "-" + JaxbValidationsPlugins.PLUGIN_OPTION_NAME };

// Get the options for the schema compiler, this is where we add plugins.
Options schemaCompilerOptions = ((SchemaCompilerImpl) schemaCompiler).getOptions();
schemaCompilerOptions.getAllPlugins().add(jaxbValidationPlugin);

// Call the parseArgument method on the options, not the plugin
// Passing in zero because we want to parse the first argument in the array
try {
    schemaCompilerOptions.parseArgument(args, 0);
} catch (BadCommandLineException e1) {
    e1.printStackTrace();
}

InputSource inputSource = new InputSource(schemaFile.toURI().toString());
schemaCompiler.parseSchema(inputSource);
S2JJAXBModel model = schemaCompiler.bind();

JCodeModel jCodeModel = model.generateCode(null, null);