HHH-18060 - HbmXmlTransformer
testing an alternative approach using the boot model
This commit is contained in:
parent
2d0f1a76cc
commit
6bd37f535c
|
@ -299,8 +299,9 @@ public class StandardServiceRegistryBuilder {
|
||||||
/**
|
/**
|
||||||
* Discard all the settings applied so far.
|
* Discard all the settings applied so far.
|
||||||
*/
|
*/
|
||||||
public void clearSettings() {
|
public StandardServiceRegistryBuilder clearSettings() {
|
||||||
settings.clear();
|
settings.clear();
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.gradle.api.tasks.OutputDirectory;
|
||||||
import org.gradle.api.tasks.SourceTask;
|
import org.gradle.api.tasks.SourceTask;
|
||||||
import org.gradle.api.tasks.TaskAction;
|
import org.gradle.api.tasks.TaskAction;
|
||||||
|
|
||||||
|
import org.hibernate.boot.MetadataSources;
|
||||||
import org.hibernate.boot.jaxb.Origin;
|
import org.hibernate.boot.jaxb.Origin;
|
||||||
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmHibernateMapping;
|
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmHibernateMapping;
|
||||||
import org.hibernate.boot.jaxb.hbm.transform.HbmXmlTransformer;
|
import org.hibernate.boot.jaxb.hbm.transform.HbmXmlTransformer;
|
||||||
|
@ -28,7 +29,12 @@ import org.hibernate.boot.jaxb.hbm.transform.UnsupportedFeatureHandling;
|
||||||
import org.hibernate.boot.jaxb.internal.MappingBinder;
|
import org.hibernate.boot.jaxb.internal.MappingBinder;
|
||||||
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
import org.hibernate.boot.jaxb.mapping.spi.JaxbEntityMappingsImpl;
|
||||||
import org.hibernate.boot.jaxb.spi.Binding;
|
import org.hibernate.boot.jaxb.spi.Binding;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
import org.hibernate.boot.spi.MetadataImplementor;
|
||||||
import org.hibernate.boot.xsd.MappingXsdSupport;
|
import org.hibernate.boot.xsd.MappingXsdSupport;
|
||||||
|
import org.hibernate.cfg.JdbcSettings;
|
||||||
|
import org.hibernate.dialect.Database;
|
||||||
|
|
||||||
import jakarta.xml.bind.JAXBException;
|
import jakarta.xml.bind.JAXBException;
|
||||||
import jakarta.xml.bind.Marshaller;
|
import jakarta.xml.bind.Marshaller;
|
||||||
|
@ -57,7 +63,8 @@ import jakarta.xml.bind.Marshaller;
|
||||||
*/
|
*/
|
||||||
@CacheableTask
|
@CacheableTask
|
||||||
public abstract class TransformHbmXmlTask extends SourceTask {
|
public abstract class TransformHbmXmlTask extends SourceTask {
|
||||||
private final Property<TransformationNaming> renaming;
|
private final TransformationNaming renaming;
|
||||||
|
private final Property<String> targetDatabaseName;
|
||||||
private final Property<UnsupportedFeatureHandling> unsupportedFeatures;
|
private final Property<UnsupportedFeatureHandling> unsupportedFeatures;
|
||||||
private final Property<Boolean> deleteHbmFiles;
|
private final Property<Boolean> deleteHbmFiles;
|
||||||
|
|
||||||
|
@ -66,8 +73,10 @@ public abstract class TransformHbmXmlTask extends SourceTask {
|
||||||
public TransformHbmXmlTask() {
|
public TransformHbmXmlTask() {
|
||||||
this.outputDirectory = getProject().getObjects().directoryProperty();
|
this.outputDirectory = getProject().getObjects().directoryProperty();
|
||||||
|
|
||||||
this.renaming = getProject().getObjects().property( TransformationNaming.class );
|
this.renaming = new TransformationNaming( getProject().getObjects() );
|
||||||
this.renaming.set( new TransformationNaming( getProject().getObjects() ) );
|
|
||||||
|
this.targetDatabaseName = getProject().getObjects().property( String.class );
|
||||||
|
this.targetDatabaseName.convention( "H2" );
|
||||||
|
|
||||||
this.unsupportedFeatures = getProject().getObjects().property( UnsupportedFeatureHandling.class );
|
this.unsupportedFeatures = getProject().getObjects().property( UnsupportedFeatureHandling.class );
|
||||||
this.unsupportedFeatures.convention( UnsupportedFeatureHandling.ERROR );
|
this.unsupportedFeatures.convention( UnsupportedFeatureHandling.ERROR );
|
||||||
|
@ -81,10 +90,19 @@ public abstract class TransformHbmXmlTask extends SourceTask {
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Nested
|
@Nested
|
||||||
public Property<TransformationNaming> getRenaming() {
|
public TransformationNaming getRenaming() {
|
||||||
return renaming;
|
return renaming;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Database
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Input
|
||||||
|
public Property<String> getTargetDatabaseName() {
|
||||||
|
return targetDatabaseName;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How should features supported in `hbm.xml` files, which are not supported for transformation, be handled?
|
* How should features supported in `hbm.xml` files, which are not supported for transformation, be handled?
|
||||||
*/
|
*/
|
||||||
|
@ -108,7 +126,7 @@ public abstract class TransformHbmXmlTask extends SourceTask {
|
||||||
* E.g. transforming the resource `org/hibernate/test/my_mappings.hbm.xml`
|
* E.g. transforming the resource `org/hibernate/test/my_mappings.hbm.xml`
|
||||||
* into `/home/me/hibernate` would transform the HBM mapping and save it
|
* into `/home/me/hibernate` would transform the HBM mapping and save it
|
||||||
* as `/home/me/hibernate/org/hibernate/test/my_mappings.hbm.xml` (depending
|
* as `/home/me/hibernate/org/hibernate/test/my_mappings.hbm.xml` (depending
|
||||||
* on {@link #getRenaming() naming} any config
|
* on {@link #getRenaming() naming} config)
|
||||||
*/
|
*/
|
||||||
@OutputDirectory
|
@OutputDirectory
|
||||||
public DirectoryProperty getOutputDirectory() {
|
public DirectoryProperty getOutputDirectory() {
|
||||||
|
@ -122,14 +140,6 @@ public abstract class TransformHbmXmlTask extends SourceTask {
|
||||||
unsupportedFeatures.getOrElse( UnsupportedFeatureHandling.ERROR )
|
unsupportedFeatures.getOrElse( UnsupportedFeatureHandling.ERROR )
|
||||||
);
|
);
|
||||||
|
|
||||||
final Marshaller marshaller;
|
|
||||||
try {
|
|
||||||
marshaller = mappingBinder.mappingJaxbContext().createMarshaller();
|
|
||||||
}
|
|
||||||
catch (JAXBException e) {
|
|
||||||
throw new RuntimeException( "Unable to create JAXB Marshaller", e );
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<Binding<JaxbHbmHibernateMapping>> hbmBindings = new ArrayList<>();
|
final List<Binding<JaxbHbmHibernateMapping>> hbmBindings = new ArrayList<>();
|
||||||
getSource().forEach( (hbmXmlFile) -> {
|
getSource().forEach( (hbmXmlFile) -> {
|
||||||
final Origin origin = new OriginImpl( hbmXmlFile );
|
final Origin origin = new OriginImpl( hbmXmlFile );
|
||||||
|
@ -137,8 +147,25 @@ public abstract class TransformHbmXmlTask extends SourceTask {
|
||||||
hbmBindings.add( hbmBinding );
|
hbmBindings.add( hbmBinding );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
try ( StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
|
||||||
|
.clearSettings()
|
||||||
|
.applySetting( JdbcSettings.JAKARTA_HBM2DDL_DB_NAME, targetDatabaseName.get() )
|
||||||
|
.applySetting( JdbcSettings.ALLOW_METADATA_ON_BOOT, false )
|
||||||
|
.build() ) {
|
||||||
|
performTransformation( hbmBindings, mappingBinder, serviceRegistry );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performTransformation(
|
||||||
|
List<Binding<JaxbHbmHibernateMapping>> hbmBindings,
|
||||||
|
MappingBinder mappingBinder, StandardServiceRegistry serviceRegistry) {
|
||||||
|
final MetadataSources metadataSources = new MetadataSources( serviceRegistry );
|
||||||
|
hbmBindings.forEach( metadataSources::addHbmXmlBinding );
|
||||||
|
|
||||||
final List<Binding<JaxbEntityMappingsImpl>> transformedBindings = HbmXmlTransformer.transform(
|
final List<Binding<JaxbEntityMappingsImpl>> transformedBindings = HbmXmlTransformer.transform(
|
||||||
hbmBindings,
|
hbmBindings,
|
||||||
|
(MetadataImplementor) metadataSources.buildMetadata(),
|
||||||
|
serviceRegistry,
|
||||||
unsupportedFeatures.get()
|
unsupportedFeatures.get()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -160,6 +187,16 @@ public abstract class TransformHbmXmlTask extends SourceTask {
|
||||||
final File copyFile = determineCopyFile( copyName, hbmXmlFile );
|
final File copyFile = determineCopyFile( copyName, hbmXmlFile );
|
||||||
//noinspection ResultOfMethodCallIgnored
|
//noinspection ResultOfMethodCallIgnored
|
||||||
copyFile.getParentFile().mkdirs();
|
copyFile.getParentFile().mkdirs();
|
||||||
|
|
||||||
|
|
||||||
|
final Marshaller marshaller;
|
||||||
|
try {
|
||||||
|
marshaller = mappingBinder.mappingJaxbContext().createMarshaller();
|
||||||
|
}
|
||||||
|
catch (JAXBException e) {
|
||||||
|
throw new RuntimeException( "Unable to create JAXB Marshaller", e );
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
marshaller.marshal( transformedBinding.getRoot(), copyFile );
|
marshaller.marshal( transformedBinding.getRoot(), copyFile );
|
||||||
}
|
}
|
||||||
|
@ -194,11 +231,6 @@ public abstract class TransformHbmXmlTask extends SourceTask {
|
||||||
|
|
||||||
private String determineCopyName(File hbmXmlFile) {
|
private String determineCopyName(File hbmXmlFile) {
|
||||||
final String hbmXmlFileName = hbmXmlFile.getName();
|
final String hbmXmlFileName = hbmXmlFile.getName();
|
||||||
if ( !renaming.isPresent() ) {
|
|
||||||
return hbmXmlFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
final TransformationNaming renaming = this.renaming.get();
|
|
||||||
if ( renaming.areNoneDefined() ) {
|
if ( renaming.areNoneDefined() ) {
|
||||||
return hbmXmlFileName;
|
return hbmXmlFileName;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import javax.inject.Inject;
|
||||||
import org.gradle.api.model.ObjectFactory;
|
import org.gradle.api.model.ObjectFactory;
|
||||||
import org.gradle.api.provider.Property;
|
import org.gradle.api.provider.Property;
|
||||||
import org.gradle.api.tasks.Input;
|
import org.gradle.api.tasks.Input;
|
||||||
|
import org.gradle.api.tasks.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines how we rename a file being transformed.
|
* Defines how we rename a file being transformed.
|
||||||
|
@ -43,6 +44,7 @@ public class TransformationNaming implements Serializable {
|
||||||
* @see #getExtension()
|
* @see #getExtension()
|
||||||
*/
|
*/
|
||||||
@Input
|
@Input
|
||||||
|
@Optional
|
||||||
public Property<String> getPrefix() {
|
public Property<String> getPrefix() {
|
||||||
return prefix;
|
return prefix;
|
||||||
}
|
}
|
||||||
|
@ -57,11 +59,13 @@ public class TransformationNaming implements Serializable {
|
||||||
* @see #getExtension()
|
* @see #getExtension()
|
||||||
*/
|
*/
|
||||||
@Input
|
@Input
|
||||||
|
@Optional
|
||||||
public Property<String> getSuffix() {
|
public Property<String> getSuffix() {
|
||||||
return suffix;
|
return suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Input
|
@Input
|
||||||
|
@Optional
|
||||||
public Property<String> getExtension() {
|
public Property<String> getExtension() {
|
||||||
return extension;
|
return extension;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.tooling.gradle;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
import org.gradle.testkit.runner.BuildResult;
|
||||||
|
import org.gradle.testkit.runner.BuildTask;
|
||||||
|
import org.gradle.testkit.runner.GradleRunner;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.gradle.testkit.runner.TaskOutcome.SUCCESS;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic functional tests
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
class HbmTransformerTests {
|
||||||
|
@Test
|
||||||
|
void testSimpleTransformation(@TempDir Path projectDir) throws IOException {
|
||||||
|
final String buildFilePath = "hbm/build.gradle";
|
||||||
|
|
||||||
|
Copier.copyProject( buildFilePath, projectDir );
|
||||||
|
|
||||||
|
System.out.println( "Starting execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
|
||||||
|
final GradleRunner gradleRunner = GradleRunner.create()
|
||||||
|
.withProjectDir( projectDir.toFile() )
|
||||||
|
.withPluginClasspath()
|
||||||
|
.withDebug( true )
|
||||||
|
.withArguments( "clean", "hbmTransform", "--stacktrace", "--no-build-cache" )
|
||||||
|
.forwardOutput();
|
||||||
|
final BuildResult result = gradleRunner.build();
|
||||||
|
|
||||||
|
final BuildTask transformationResult = result.task( ":hbmTransform" );
|
||||||
|
assertThat( transformationResult ).isNotNull();
|
||||||
|
assertThat( transformationResult.getOutcome() ).isEqualTo( SUCCESS );
|
||||||
|
|
||||||
|
final File targetDir = new File( projectDir.toFile(), "build" );
|
||||||
|
final File transformationOutputDir = new File( targetDir, "resources/hbm-transformed" );
|
||||||
|
assertThat( transformationOutputDir ).exists();
|
||||||
|
assertThat( transformationOutputDir ).isNotEmptyDirectory();
|
||||||
|
|
||||||
|
final File[] transformedFiles = transformationOutputDir.listFiles();
|
||||||
|
assertThat( transformedFiles ).hasSize( 1 );
|
||||||
|
final String transformedFileContent = Files.readString( transformedFiles[0].toPath() );
|
||||||
|
assertThat( transformedFileContent ).doesNotContain( "<hibernate-mapping" );
|
||||||
|
assertThat( transformedFileContent ).doesNotContain( "</hibernate-mapping>" );
|
||||||
|
assertThat( transformedFileContent ).contains( "<entity-mappings" );
|
||||||
|
assertThat( transformedFileContent ).contains( "<entity name=\"simple\" metadata-complete=\"true\">" );
|
||||||
|
assertThat( transformedFileContent ).contains( "</entity-mappings>" );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
import org.hibernate.orm.tooling.gradle.misc.TransformHbmXmlTask
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
id 'org.hibernate.orm'
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
|
||||||
|
maven {
|
||||||
|
name 'jboss-snapshots-repository'
|
||||||
|
url 'https://repository.jboss.org/nexus/content/repositories/snapshots'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// NOTE : The version used here is irrelevant in terms of testing the plugin.
|
||||||
|
// We just need a resolvable version
|
||||||
|
implementation 'org.hibernate.orm:hibernate-core:6.1.0.Final'
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register( "hbmTransform", TransformHbmXmlTask ) {
|
||||||
|
source "src/main/resources"
|
||||||
|
getRenaming().getExtension().set( "xml" )
|
||||||
|
getOutputDirectory().set( project.layout.buildDirectory.dir( "resources/hbm-transformed" ) )
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
~
|
||||||
|
~ 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.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||||
|
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||||
|
|
||||||
|
<hibernate-mapping>
|
||||||
|
<class entity-name="simple">
|
||||||
|
<id name="id" type="integer"/>
|
||||||
|
<property name="name" type="string"/>
|
||||||
|
</class>
|
||||||
|
</hibernate-mapping>
|
Loading…
Reference in New Issue