HHH-18828 - Migrate to hisrc-basicjaxb for xjc plugins

This commit is contained in:
Steve Ebersole 2024-11-08 16:23:47 -07:00
parent 839793e543
commit 2a9f4c41a8
20 changed files with 344 additions and 15 deletions

View File

@ -7,7 +7,7 @@
import org.apache.tools.ant.filters.ReplaceTokens
plugins {
id 'org.hibernate.build.xjc-jakarta'
id "local-xjc-plugin"
}
description = 'Hibernate\'s core ORM functionality'
@ -87,10 +87,6 @@ dependencies {
// dependency here.
antlr libs.antlr
antlr libs.antlrRuntime
xjc jakartaLibs.xjc
xjc jakartaLibs.jaxb
xjc rootProject.fileTree(dir: 'patched-libs/jaxb2-basics', include: '*.jar')
}
jar {

View File

@ -9,7 +9,7 @@
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.hibernate.org/xsd/orm/hbm"
xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
xmlns:simplify="http://jaxb2-commons.dev.java.net/basic/simplify"
xmlns:simplify="http://jvnet.org/basicjaxb/xjc/simplify"
targetNamespace="http://www.hibernate.org/xsd/orm/hbm"
elementFormDefault="qualified"
jaxb:extensionBindingPrefixes="simplify"

View File

@ -3,7 +3,7 @@
<jaxb:bindings xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:inheritance="http://jaxb2-commons.dev.java.net/basic/inheritance"
xmlns:inheritance="http://jvnet.org/basicjaxb/xjc/inheritance"
jaxb:extensionBindingPrefixes="inheritance"
version="3.0">

View File

@ -4,8 +4,8 @@
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
jaxb:extensionBindingPrefixes="inheritance simplify"
xmlns:inheritance="http://jaxb2-commons.dev.java.net/basic/inheritance"
xmlns:simplify="http://jaxb2-commons.dev.java.net/basic/simplify"
xmlns:inheritance="http://jvnet.org/basicjaxb/xjc/inheritance"
xmlns:simplify="http://jvnet.org/basicjaxb/xjc/simplify"
version="3.0">
<bindings schemaLocation="../resources/org/hibernate/xsd/mapping/mapping-7.0.xsd" node="/xsd:schema">

View File

@ -4,18 +4,24 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
plugins {
id "java-gradle-plugin"
id "groovy"
}
repositories {
mavenCentral()
}
apply plugin: 'java-gradle-plugin'
group = 'org.hibernate.build'
version = '1.0.0-SNAPSHOT'
buildDir = "target"
dependencies {
implementation gradleApi()
implementation "jakarta.inject:jakarta.inject-api:2.0.0"
implementation 'io.smallrye:jandex:3.1.2'
implementation 'org.apache.httpcomponents:httpclient:4.5.13'
implementation 'jakarta.json.bind:jakarta.json.bind-api:2.0.0'
@ -89,6 +95,10 @@ gradlePlugin {
id = "org.hibernate.build.maven-embedder"
implementationClass = "org.hibernate.build.maven.embedder.MavenEmbedderPlugin"
}
register( "xjc-plugin" ) {
id = "local-xjc-plugin"
implementationClass = "org.hibernate.build.xjc.XjcPlugin"
}
}
}

View File

@ -0,0 +1,85 @@
package org.hibernate.build.xjc;
import org.gradle.api.Named;
import org.gradle.api.Project;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.SetProperty;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* @author Steve Ebersole
*/
public class SchemaDescriptor implements Named {
private final String name;
private final Project project;
private final RegularFileProperty xsdFile;
private final RegularFileProperty xjcBindingFile;
private final SetProperty<String> xjcExtensions;
public SchemaDescriptor(String name, Project project) {
this.name = name;
this.project = project;
xsdFile = project.getObjects().fileProperty();
xjcBindingFile = project.getObjects().fileProperty();
xjcExtensions = project.getObjects().setProperty( String.class );
}
@Override
public final String getName() {
return name;
}
@InputFile
public RegularFileProperty getXsdFile() {
return xsdFile;
}
public void setXsdFile(Object reference) {
xsdFile.set( project.file( reference ) );
}
public void xsdFile(Object reference) {
setXsdFile( reference );
}
@InputFile
public RegularFileProperty getXjcBindingFile() {
return xjcBindingFile;
}
public void setXjcBindingFile(Object reference) {
xjcBindingFile.set( project.file( reference ) );
}
public void xjcBindingFile(Object reference) {
setXjcBindingFile( reference );
}
@Input
public SetProperty<String> ___xjcExtensions() {
return xjcExtensions;
}
public Set<String> getXjcExtensions() {
return xjcExtensions.get();
}
public void setXjcExtensions(Set<String> xjcExtensions) {
this.xjcExtensions.set( xjcExtensions );
}
public void setXjcExtensions(String... xjcExtensions) {
xjcExtensions( xjcExtensions );
}
public void xjcExtensions(String... xjcExtensions) {
setXjcExtensions( new HashSet<>( Arrays.asList( xjcExtensions) ) );
}
}

View File

@ -0,0 +1,68 @@
package org.hibernate.build.xjc;
import org.gradle.api.NamedDomainObjectFactory;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.file.Directory;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.api.tasks.TaskProvider;
import static org.gradle.api.tasks.SourceSet.MAIN_SOURCE_SET_NAME;
/**
* Used as the factory for instances added to the {@link XjcExtension#getSchemas()} container.
* <p>
* For each schema descriptor, an XjcTask is created and wired up.
*
* @author Steve Ebersole
*/
public class SchemaDescriptorFactory implements NamedDomainObjectFactory<SchemaDescriptor> {
private final XjcExtension xjcExtension;
private final Task groupingTask;
private final Project project;
public SchemaDescriptorFactory(XjcExtension xjcExtension, Task groupingTask, Project project) {
this.xjcExtension = xjcExtension;
this.groupingTask = groupingTask;
this.project = project;
}
@Override
public SchemaDescriptor create(String name) {
final SchemaDescriptor schemaDescriptor = new SchemaDescriptor( name, project );
final String taskName = determineXjcTaskName( schemaDescriptor );
final Provider<Directory> taskOutputDirectory = xjcExtension.getOutputDirectory().dir( name );
// register the XjcTask for the schema
final TaskProvider<XjcTask> xjcTaskRef = project.getTasks().register( taskName, XjcTask.class, (task) -> {
task.setGroup( "xjc" );
task.setDescription( "XJC generation for the " + name + " descriptor" );
// wire up the inputs and outputs
task.getXsdFile().set( schemaDescriptor.getXsdFile() );
task.getXjcBindingFile().set( schemaDescriptor.getXjcBindingFile() );
task.getXjcExtensions().set( schemaDescriptor.___xjcExtensions() );
task.getOutputDirectory().set( taskOutputDirectory );
} );
final SourceSetContainer sourceSets = project.getExtensions().getByType( SourceSetContainer.class );
final SourceSet mainSourceSet = sourceSets.getByName( MAIN_SOURCE_SET_NAME );
mainSourceSet.getJava().srcDir( xjcTaskRef );
groupingTask.dependsOn( xjcTaskRef );
return schemaDescriptor;
}
private static String determineXjcTaskName(SchemaDescriptor schemaDescriptor) {
assert schemaDescriptor.getName() != null;
final char initialLetterCap = Character.toUpperCase( schemaDescriptor.getName().charAt( 0 ) );
final String rest = schemaDescriptor.getName().substring( 1 );
return "xjc" + initialLetterCap + rest;
}
}

View File

@ -0,0 +1,52 @@
package org.hibernate.build.xjc;
import groovy.lang.Closure;
import jakarta.inject.Inject;
import org.gradle.api.NamedDomainObjectContainer;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.OutputDirectory;
/**
* @author Steve Ebersole
*/
public abstract class XjcExtension {
private final DirectoryProperty outputDirectory;
private final Property<String> jaxbBasicsVersion;
private final NamedDomainObjectContainer<SchemaDescriptor> schemas;
@Inject
public XjcExtension(Task groupingTask, Project project) {
outputDirectory = project.getObjects().directoryProperty();
outputDirectory.convention( project.getLayout().getBuildDirectory().dir( "generated/sources/xjc/main" ) );
jaxbBasicsVersion = project.getObjects().property( String.class );
jaxbBasicsVersion.convention( "2.2.1" );
// Create a dynamic container for SchemaDescriptor definitions by the user.
// - for each schema they define, create a Task to perform the "compilation"
schemas = project.container( SchemaDescriptor.class, new SchemaDescriptorFactory( this, groupingTask, project ) );
}
@OutputDirectory
public DirectoryProperty getOutputDirectory() {
return outputDirectory;
}
public Property<String> getJaxbBasicsVersion() {
return jaxbBasicsVersion;
}
@SuppressWarnings("unused")
public final NamedDomainObjectContainer<SchemaDescriptor> getSchemas() {
return schemas;
}
@SuppressWarnings({ "unused", "rawtypes" })
public NamedDomainObjectContainer<SchemaDescriptor> schemas(Closure closure) {
return schemas.configure( closure );
}
}

View File

@ -0,0 +1,47 @@
package org.hibernate.build.xjc;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.dsl.DependencyHandler;
import java.util.LinkedHashMap;
/**
* @author Steve Ebersole
*/
public class XjcPlugin implements Plugin<Project> {
public static final String XJC_BASIC_PLUGIN = "org.patrodyne.jvnet:hisrc-basicjaxb-plugins:2.2.1";
public static final String XJC_BASIC_TOOLS = "org.patrodyne.jvnet:hisrc-basicjaxb-tools:2.2.1";
public static final String XJC_BASIC_ANT = "org.patrodyne.jvnet:hisrc-basicjaxb-ant:2.2.1";
public static final String ANT_TASK_NAME = "org.jvnet.basicjaxb.xjc.XJC2Task";
@Override
public void apply(Project project) {
// Create the xjc grouping task
final Task groupingTask = project.getTasks().create( "xjc", xjcTask -> {
xjcTask.setGroup( "xjc" );
xjcTask.setDescription( "Grouping task for executing one-or-more XJC compilations" );
} );
// Create the Plugin extension object (for users to configure our execution).
project.getExtensions().create( "xjc", XjcExtension.class, groupingTask, project );
final DependencyHandler dependencyHandler = project.getDependencies();
final Configuration antTaskDependencies = project.getConfigurations().detachedConfiguration(
dependencyHandler.create( XJC_BASIC_ANT ),
dependencyHandler.create( XJC_BASIC_PLUGIN ),
dependencyHandler.create( XJC_BASIC_TOOLS ),
dependencyHandler.gradleApi()
);
final LinkedHashMap<String, String> map = new LinkedHashMap<>( 3 );
map.put( "name", "xjc" );
map.put( "classname", ANT_TASK_NAME );
map.put( "classpath", antTaskDependencies.getAsPath() );
project.getAnt().invokeMethod( "taskdef", new Object[] { map } );
project.getAnt().setSaveStreams( false );
}
}

View File

@ -0,0 +1,71 @@
package org.hibernate.build.xjc
import org.gradle.api.DefaultTask
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.SetProperty
import org.gradle.api.tasks.*
/**
* @author Steve Ebersole
*/
@CacheableTask
class XjcTask extends DefaultTask {
private final DirectoryProperty outputDirectory
private final RegularFileProperty xsdFile
private final RegularFileProperty xjcBindingFile
private final SetProperty<String> xjcExtensions
XjcTask() {
xsdFile = project.getObjects().fileProperty()
xjcBindingFile = project.getObjects().fileProperty()
xjcExtensions = project.objects.setProperty( String.class )
outputDirectory = project.objects.directoryProperty()
}
@InputFile
@PathSensitive( PathSensitivity.RELATIVE )
RegularFileProperty getXsdFile() {
return xsdFile
}
@InputFile
@PathSensitive( PathSensitivity.RELATIVE )
RegularFileProperty getXjcBindingFile() {
return xjcBindingFile
}
@Input
SetProperty<String> getXjcExtensions() {
return xjcExtensions
}
@OutputDirectory
DirectoryProperty getOutputDirectory() {
return outputDirectory
}
@TaskAction
void generateJaxbBindings() {
project.delete( outputDirectory.get().asFileTree )
project.ant.xjc(
destdir: outputDirectory.get().asFile.absolutePath,
binding: xjcBindingFile.get().asFile.absolutePath,
schema: xsdFile.get().asFile.absolutePath,
extension: 'true') {
project.ant.arg line: '-no-header'
project.ant.arg line: '-npa'
if ( xjcExtensions.isPresent() ) {
def extensionsToEnable = xjcExtensions.get()
if ( ! extensionsToEnable.isEmpty() ) {
def extensionsSwitches = extensionsToEnable.collect { "-X${it}" }.join( " " )
project.ant.arg line: extensionsSwitches
}
}
}
}
}