HHH-16677 - Drop JPA static metamodel generation from Gradle plugin
This commit is contained in:
parent
2bebcf5e95
commit
2e98c1678d
|
@ -13,21 +13,11 @@ import org.gradle.api.Action;
|
|||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.Task;
|
||||
import org.gradle.api.artifacts.Dependency;
|
||||
import org.gradle.api.file.DirectoryProperty;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.plugins.JvmEcosystemPlugin;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
import org.gradle.api.tasks.compile.AbstractCompile;
|
||||
import org.gradle.api.tasks.compile.JavaCompile;
|
||||
|
||||
import org.hibernate.orm.tooling.gradle.enhance.EnhancementHelper;
|
||||
import org.hibernate.orm.tooling.gradle.metamodel.JpaMetamodelGenerationTask;
|
||||
|
||||
import static org.hibernate.orm.tooling.gradle.HibernateOrmSpec.HIBERNATE;
|
||||
import static org.hibernate.orm.tooling.gradle.metamodel.JpaMetamodelGenerationTask.COMPILE_META_TASK_NAME;
|
||||
import static org.hibernate.orm.tooling.gradle.metamodel.JpaMetamodelGenerationTask.GEN_TASK_NAME;
|
||||
|
||||
/**
|
||||
* Hibernate ORM Gradle plugin
|
||||
|
@ -42,7 +32,6 @@ public class HibernateOrmPlugin implements Plugin<Project> {
|
|||
final HibernateOrmSpec ormDsl = project.getExtensions().create( HibernateOrmSpec.DSL_NAME, HibernateOrmSpec.class, project );
|
||||
|
||||
prepareEnhancement( ormDsl, project );
|
||||
prepareModelGen( ormDsl, project );
|
||||
prepareHbmTransformation( ormDsl, project );
|
||||
|
||||
|
||||
|
@ -94,64 +83,6 @@ public class HibernateOrmPlugin implements Plugin<Project> {
|
|||
} );
|
||||
}
|
||||
|
||||
private void prepareModelGen(HibernateOrmSpec ormDsl, Project project) {
|
||||
final TaskProvider<JavaCompile> modelCompileTaskRef = project.getTasks().register( COMPILE_META_TASK_NAME, JavaCompile.class, (modelCompileTask) -> {
|
||||
modelCompileTask.onlyIf( (t) -> ormDsl.isMetamodelGenerationEnabled() );
|
||||
|
||||
modelCompileTask.setGroup( HIBERNATE );
|
||||
modelCompileTask.setDescription( "Compiles the JPA static metamodel generated by `" + GEN_TASK_NAME + "`" );
|
||||
} );
|
||||
|
||||
project.getTasks().register( GEN_TASK_NAME, JpaMetamodelGenerationTask.class, (genTask) -> {
|
||||
genTask.onlyIf( (t) -> ormDsl.isMetamodelGenerationEnabled() );
|
||||
|
||||
if ( !ormDsl.isMetamodelGenerationEnabled() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
genTask.injectSourceSet( ormDsl.getSourceSet() );
|
||||
|
||||
genTask.getGenerationOutputDirectory().convention( ormDsl.getJpaMetamodel().getGenerationOutputDirectory() );
|
||||
|
||||
genTask.getApplyGeneratedAnnotation().convention( ormDsl.getJpaMetamodel().getApplyGeneratedAnnotation() );
|
||||
genTask.getSuppressions().convention( ormDsl.getJpaMetamodel().getSuppressions() );
|
||||
|
||||
final JavaCompile modelCompileTask = modelCompileTaskRef.get();
|
||||
|
||||
final SourceSet sourceSet = ormDsl.getSourceSet().get();
|
||||
sourceSet.getAllSource().minus( sourceSet.getAllSource() ).forEach( (dir) -> {
|
||||
final String language = dir.getName();
|
||||
final String languageCompileTaskName = sourceSet.getCompileTaskName( language );
|
||||
final AbstractCompile languageCompileTask = (AbstractCompile) project.getTasks().getByName( languageCompileTaskName );
|
||||
genTask.dependsOn( languageCompileTask );
|
||||
|
||||
modelCompileTask.setSourceCompatibility( languageCompileTask.getSourceCompatibility() );
|
||||
modelCompileTask.setTargetCompatibility( languageCompileTask.getTargetCompatibility() );
|
||||
|
||||
modelCompileTask.finalizedBy( modelCompileTask );
|
||||
} );
|
||||
|
||||
genTask.dependsOn( sourceSet.getProcessResourcesTaskName() );
|
||||
|
||||
genTask.finalizedBy( modelCompileTask );
|
||||
modelCompileTask.dependsOn( genTask );
|
||||
modelCompileTask.source( project.files( ormDsl.getJpaMetamodel().getGenerationOutputDirectory() ) );
|
||||
modelCompileTask.getDestinationDirectory().set( ormDsl.getJpaMetamodel().getCompileOutputDirectory() );
|
||||
|
||||
FileCollection metamodelCompileClasspath = project.getConfigurations().getByName( "runtimeClasspath" )
|
||||
.plus( sourceSet.getCompileClasspath() )
|
||||
.plus( sourceSet.getRuntimeClasspath() );
|
||||
if ( ormDsl.getJpaMetamodel().getApplyGeneratedAnnotation().getOrElse( true ) ) {
|
||||
final Dependency jakartaAnnotationsDep = project.getDependencies().create( "jakarta.annotation:jakarta.annotation-api:2.0.0" );
|
||||
metamodelCompileClasspath = metamodelCompileClasspath.plus(
|
||||
project.getConfigurations().detachedConfiguration( jakartaAnnotationsDep )
|
||||
);
|
||||
}
|
||||
|
||||
modelCompileTask.setClasspath( metamodelCompileClasspath );
|
||||
} );
|
||||
}
|
||||
|
||||
private void prepareHbmTransformation(HibernateOrmSpec ormDsl, Project project) {
|
||||
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import org.gradle.api.provider.SetProperty;
|
|||
import org.gradle.api.tasks.SourceSet;
|
||||
|
||||
import org.hibernate.orm.tooling.gradle.enhance.EnhancementSpec;
|
||||
import org.hibernate.orm.tooling.gradle.metamodel.JpaMetamodelGenerationSpec;
|
||||
|
||||
/**
|
||||
* Main DSL extension for Hibernate ORM. Available as `project.hibernate`
|
||||
|
@ -33,14 +32,12 @@ public abstract class HibernateOrmSpec implements ExtensionAware {
|
|||
private final Project project;
|
||||
|
||||
private EnhancementSpec enhancementDsl;
|
||||
private JpaMetamodelGenerationSpec jpaMetamodelDsl;
|
||||
|
||||
private final Property<Boolean> useSameVersion;
|
||||
private final Property<SourceSet> sourceSet;
|
||||
private final SetProperty<String> languages;
|
||||
|
||||
private final Provider<EnhancementSpec> enhancementDslAccess;
|
||||
private final Provider<JpaMetamodelGenerationSpec> jpaMetamodelDslAccess;
|
||||
|
||||
|
||||
@Inject
|
||||
|
@ -57,7 +54,6 @@ public abstract class HibernateOrmSpec implements ExtensionAware {
|
|||
languages.convention( Arrays.asList( "java", "kotlin" ) );
|
||||
|
||||
enhancementDslAccess = project.provider( () -> enhancementDsl );
|
||||
jpaMetamodelDslAccess = project.provider( () -> jpaMetamodelDsl );
|
||||
}
|
||||
|
||||
private static SourceSet mainSourceSet(Project project) {
|
||||
|
@ -121,33 +117,11 @@ public abstract class HibernateOrmSpec implements ExtensionAware {
|
|||
action.execute( getEnhancement() );
|
||||
}
|
||||
|
||||
/**
|
||||
* DSL extension for configuring JPA static metamodel generation. Also acts as the trigger for
|
||||
* opting into the generation
|
||||
*/
|
||||
public JpaMetamodelGenerationSpec getJpaMetamodel() {
|
||||
if ( jpaMetamodelDsl == null ) {
|
||||
jpaMetamodelDsl = getExtensions().create( JpaMetamodelGenerationSpec.DSL_NAME, JpaMetamodelGenerationSpec.class, this, project );
|
||||
}
|
||||
return jpaMetamodelDsl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getJpaMetamodel()
|
||||
*/
|
||||
public void jpaMetamodel(Action<JpaMetamodelGenerationSpec>action) {
|
||||
action.execute( getJpaMetamodel() );
|
||||
}
|
||||
|
||||
|
||||
public boolean isEnhancementEnabled() {
|
||||
return enhancementDsl != null;
|
||||
}
|
||||
|
||||
public boolean isMetamodelGenerationEnabled() {
|
||||
return jpaMetamodelDsl != null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see #getUseSameVersion()
|
||||
|
@ -238,15 +212,4 @@ public abstract class HibernateOrmSpec implements ExtensionAware {
|
|||
public Provider<EnhancementSpec> getEnhancementDslAccess() {
|
||||
return enhancementDslAccess;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Provider access to {@link #getJpaMetamodel()}
|
||||
*
|
||||
* @deprecated See the Gradle property naming <a href="https://docs.gradle.org/current/userguide/lazy_configuration.html#lazy_configuration_faqs">guidelines</a>
|
||||
*/
|
||||
@Deprecated
|
||||
public Provider<JpaMetamodelGenerationSpec> getJpaMetamodelDslAccess() {
|
||||
return jpaMetamodelDslAccess;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,111 +0,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
|
||||
*/
|
||||
package org.hibernate.orm.tooling.gradle.metamodel;
|
||||
|
||||
import java.util.Arrays;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.file.DirectoryProperty;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.SetProperty;
|
||||
|
||||
import org.hibernate.orm.tooling.gradle.HibernateOrmSpec;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class JpaMetamodelGenerationSpec {
|
||||
public static final String JPA_METAMODEL = "jpaMetamodel";
|
||||
public static final String DSL_NAME = JPA_METAMODEL;
|
||||
|
||||
private final Project project;
|
||||
|
||||
private final DirectoryProperty generationOutputDirectory;
|
||||
private final DirectoryProperty compileOutputDirectory;
|
||||
|
||||
private final Property<Boolean> applyGeneratedAnnotation;
|
||||
private final SetProperty<String> suppressions;
|
||||
|
||||
@Inject
|
||||
public JpaMetamodelGenerationSpec(HibernateOrmSpec ormDsl, Project project) {
|
||||
this.project = project;
|
||||
|
||||
generationOutputDirectory = project.getObjects().directoryProperty();
|
||||
generationOutputDirectory.convention(
|
||||
project.getLayout().getBuildDirectory().dir( "generated/sources/" + JPA_METAMODEL )
|
||||
);
|
||||
|
||||
compileOutputDirectory = project.getObjects().directoryProperty();
|
||||
compileOutputDirectory.convention(
|
||||
project.getLayout().getBuildDirectory().dir( "classes/java/" + JPA_METAMODEL )
|
||||
);
|
||||
|
||||
applyGeneratedAnnotation = project.getObjects().property( Boolean.class );
|
||||
applyGeneratedAnnotation.convention( true );
|
||||
|
||||
suppressions = project.getObjects().setProperty( String.class );
|
||||
suppressions.convention( Arrays.asList( "raw", "deprecation" ) );
|
||||
}
|
||||
|
||||
public Property<Boolean> getApplyGeneratedAnnotation() {
|
||||
return applyGeneratedAnnotation;
|
||||
}
|
||||
|
||||
public SetProperty<String> getSuppressions() {
|
||||
return suppressions;
|
||||
}
|
||||
|
||||
public DirectoryProperty getGenerationOutputDirectory() {
|
||||
return generationOutputDirectory;
|
||||
}
|
||||
|
||||
public DirectoryProperty getCompileOutputDirectory() {
|
||||
return compileOutputDirectory;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see #getApplyGeneratedAnnotation()
|
||||
*
|
||||
* @deprecated See the Gradle property naming <a href="https://docs.gradle.org/current/userguide/lazy_configuration.html#lazy_configuration_faqs">guidelines</a>
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public void applyGeneratedAnnotation(boolean apply) {
|
||||
applyGeneratedAnnotation.set( apply );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getSuppressions()
|
||||
*
|
||||
* @deprecated See the Gradle property naming <a href="https://docs.gradle.org/current/userguide/lazy_configuration.html#lazy_configuration_faqs">guidelines</a>
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public void suppress(String warning) {
|
||||
suppressions.add( warning );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getGenerationOutputDirectory()
|
||||
*
|
||||
* @deprecated See the Gradle property naming <a href="https://docs.gradle.org/current/userguide/lazy_configuration.html#lazy_configuration_faqs">guidelines</a>
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public void generationOutputDirectory(Object ref) {
|
||||
generationOutputDirectory.set( project.file( ref ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getCompileOutputDirectory()
|
||||
*
|
||||
* @deprecated See the Gradle property naming <a href="https://docs.gradle.org/current/userguide/lazy_configuration.html#lazy_configuration_faqs">guidelines</a>
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public void compileOutputDirectory(Object ref) {
|
||||
compileOutputDirectory.set( project.file( ref ) );
|
||||
}
|
||||
}
|
|
@ -1,177 +0,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
|
||||
*/
|
||||
package org.hibernate.orm.tooling.gradle.metamodel;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Properties;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.gradle.api.DefaultTask;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.file.ConfigurableFileTree;
|
||||
import org.gradle.api.file.Directory;
|
||||
import org.gradle.api.file.DirectoryProperty;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.provider.Property;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.provider.SetProperty;
|
||||
import org.gradle.api.tasks.Input;
|
||||
import org.gradle.api.tasks.InputFiles;
|
||||
import org.gradle.api.tasks.OutputDirectory;
|
||||
import org.gradle.api.tasks.SkipWhenEmpty;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.gradle.api.tasks.TaskAction;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.orm.tooling.gradle.Helper;
|
||||
import org.hibernate.orm.tooling.gradle.HibernateOrmSpec;
|
||||
import org.hibernate.orm.tooling.gradle.metamodel.model.GenerationOptions;
|
||||
import org.hibernate.orm.tooling.gradle.metamodel.model.JpaStaticMetamodelGenerator;
|
||||
|
||||
import static org.hibernate.orm.tooling.gradle.HibernateOrmSpec.HIBERNATE;
|
||||
|
||||
/**
|
||||
* Generates the "JPA static metamodel" from the domain model defined by the project
|
||||
* via classes and possibly XML mappings
|
||||
*
|
||||
* @apiNote While there is also an annotation-processor that performs the same
|
||||
* general function, that approach is limited in that it can only process compiled
|
||||
* classes based on annotations. This task accounts for both classes and XML mappings
|
||||
*/
|
||||
public class JpaMetamodelGenerationTask extends DefaultTask {
|
||||
public static final String GEN_TASK_NAME = "generateJpaMetamodel";
|
||||
public static final String COMPILE_META_TASK_NAME = "compileJpaMetamodel";
|
||||
|
||||
private final Property<SourceSet> sourceSetProperty;
|
||||
|
||||
private final DirectoryProperty generationOutputDirectory;
|
||||
|
||||
private final Property<Boolean> applyGeneratedAnnotation;
|
||||
private final SetProperty<String> suppressions;
|
||||
|
||||
|
||||
|
||||
@Inject
|
||||
public JpaMetamodelGenerationTask() {
|
||||
setGroup( HIBERNATE );
|
||||
setDescription( "Generates the JPA 'static metamodel'" );
|
||||
|
||||
sourceSetProperty = getProject().getObjects().property( SourceSet.class );
|
||||
|
||||
generationOutputDirectory = getProject().getObjects().directoryProperty();
|
||||
|
||||
applyGeneratedAnnotation = getProject().getObjects().property( Boolean.class );
|
||||
suppressions = getProject().getObjects().setProperty( String.class );
|
||||
|
||||
}
|
||||
|
||||
public void injectSourceSet(Provider<SourceSet> sourceSetAccess) {
|
||||
sourceSetProperty.set( sourceSetAccess );
|
||||
}
|
||||
|
||||
@OutputDirectory
|
||||
public DirectoryProperty getGenerationOutputDirectory() {
|
||||
return generationOutputDirectory;
|
||||
}
|
||||
|
||||
@InputFiles
|
||||
@SkipWhenEmpty
|
||||
public FileCollection getSources() {
|
||||
return sourceSetProperty.get().getOutput();
|
||||
}
|
||||
|
||||
@Input
|
||||
public Property<Boolean> getApplyGeneratedAnnotation() {
|
||||
return applyGeneratedAnnotation;
|
||||
}
|
||||
|
||||
@Input
|
||||
public SetProperty<String> getSuppressions() {
|
||||
return suppressions;
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
public void generateJpaMetamodel() {
|
||||
final ClassLoader classLoader = Helper.toClassLoader( sourceSetProperty.get().getOutput() );
|
||||
final PersistenceUnitInfoImpl unitInfo = new PersistenceUnitInfoImpl(
|
||||
determineUnitUrl(),
|
||||
generateIntegrationSettings(),
|
||||
classLoader
|
||||
);
|
||||
|
||||
|
||||
getSources().forEach( (dir) -> {
|
||||
final ConfigurableFileTree files = getProject().fileTree( dir );
|
||||
files.forEach( (file) -> {
|
||||
if ( file.getName().endsWith( ".class" ) ) {
|
||||
final String className = Helper.determineClassName( dir, file );
|
||||
unitInfo.addManagedClassName( className );
|
||||
}
|
||||
else if ( isMappingFile( file ) ) {
|
||||
unitInfo.addMappingFile( file.getName() );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
JpaStaticMetamodelGenerator.processMetamodel( unitInfo, createGenerationOptions() );
|
||||
}
|
||||
|
||||
private GenerationOptions createGenerationOptions() {
|
||||
return new GenerationOptions() {
|
||||
@Override
|
||||
public Provider<Directory> getGenerationDirectory() {
|
||||
return generationOutputDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Provider<Boolean> getApplyGeneratedAnnotation() {
|
||||
return applyGeneratedAnnotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SetProperty<String> getSuppressions() {
|
||||
return suppressions;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private URL determineUnitUrl() {
|
||||
try {
|
||||
// NOTE : we just need *a* URL - we used the project dir
|
||||
return getProject().getProjectDir().toURI().toURL();
|
||||
}
|
||||
catch (MalformedURLException e) {
|
||||
throw new IllegalStateException( "Could not interpret project directory as URL" );
|
||||
}
|
||||
}
|
||||
|
||||
private Properties generateIntegrationSettings() {
|
||||
final Properties settings = new Properties();
|
||||
|
||||
settings.put( "hibernate.temp.use_jdbc_metadata_defaults", "false" );
|
||||
settings.put( AvailableSettings.DIALECT, "H2" );
|
||||
settings.put( AvailableSettings.USE_SECOND_LEVEL_CACHE, false );
|
||||
settings.put( AvailableSettings.USE_QUERY_CACHE, false );
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
private boolean isMappingFile(File file) {
|
||||
final String fileName = file.getName();
|
||||
|
||||
// convention
|
||||
// - we could allow filters for flexibility?
|
||||
return fileName.endsWith( ".hbm.xml" ) || fileName.endsWith( ".orm.xml" );
|
||||
}
|
||||
|
||||
public static void apply(HibernateOrmSpec pluginDsl, Project project) {
|
||||
// todo : implement it
|
||||
}
|
||||
|
||||
}
|
|
@ -1,131 +0,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.
|
||||
*/
|
||||
package org.hibernate.orm.tooling.gradle.metamodel;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.hibernate.jpa.HibernatePersistenceProvider;
|
||||
|
||||
import jakarta.persistence.SharedCacheMode;
|
||||
import jakarta.persistence.ValidationMode;
|
||||
import jakarta.persistence.spi.ClassTransformer;
|
||||
import jakarta.persistence.spi.PersistenceUnitInfo;
|
||||
import jakarta.persistence.spi.PersistenceUnitTransactionType;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
class PersistenceUnitInfoImpl implements PersistenceUnitInfo {
|
||||
private final URL unitRoot;
|
||||
private final Properties properties;
|
||||
private final ClassLoader classLoader;
|
||||
private final List<String> managedClassNames = new ArrayList<>();
|
||||
private final List<String> mappingFileNames = new ArrayList<>();
|
||||
|
||||
public PersistenceUnitInfoImpl(URL unitRoot, Properties properties, ClassLoader classLoader) {
|
||||
this.unitRoot = unitRoot;
|
||||
this.properties = properties;
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPersistenceUnitName() {
|
||||
return "jpa-static-metamodel-gen";
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getPersistenceUnitRootUrl() {
|
||||
return unitRoot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader getClassLoader() {
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getManagedClassNames() {
|
||||
return managedClassNames;
|
||||
}
|
||||
|
||||
public void addManagedClassName(String className) {
|
||||
getManagedClassNames().add( className );
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMappingFileNames() {
|
||||
return mappingFileNames;
|
||||
}
|
||||
|
||||
public void addMappingFile(String fileName) {
|
||||
getMappingFileNames().add( fileName );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPersistenceProviderClassName() {
|
||||
return HibernatePersistenceProvider.class.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistenceUnitTransactionType getTransactionType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSource getJtaDataSource() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSource getNonJtaDataSource() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<URL> getJarFileUrls() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean excludeUnlistedClasses() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SharedCacheMode getSharedCacheMode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValidationMode getValidationMode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPersistenceXMLSchemaVersion() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTransformer(ClassTransformer transformer) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader getNewTempClassLoader() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,34 +0,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
|
||||
*/
|
||||
package org.hibernate.orm.tooling.gradle.metamodel.model;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
public class AttributeBag extends AttributeSupport {
|
||||
private final Class<?> elementJavaType;
|
||||
|
||||
public AttributeBag(
|
||||
MetamodelClass metamodelClass,
|
||||
String attributeName,
|
||||
Class<?> elementJavaType) {
|
||||
super( metamodelClass, attributeName, Collection.class );
|
||||
this.elementJavaType = elementJavaType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAttributeType(BufferedWriter writer) throws IOException {
|
||||
writer.write(
|
||||
format(
|
||||
"CollectionAttribute<%s,%s>",
|
||||
getOwnerDomainClassName(),
|
||||
elementJavaType.getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,34 +0,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
|
||||
*/
|
||||
package org.hibernate.orm.tooling.gradle.metamodel.model;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
public class AttributeList extends AttributeSupport {
|
||||
private final Class<?> elementJavaType;
|
||||
|
||||
public AttributeList(
|
||||
MetamodelClass metamodelClass,
|
||||
String attributeName,
|
||||
Class<?> elementJavaType) {
|
||||
super( metamodelClass, attributeName, Set.class );
|
||||
this.elementJavaType = elementJavaType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAttributeType(BufferedWriter writer) throws IOException {
|
||||
writer.write(
|
||||
format(
|
||||
"ListAttribute<%s,%s>",
|
||||
getOwnerDomainClassName(),
|
||||
elementJavaType.getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,38 +0,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
|
||||
*/
|
||||
package org.hibernate.orm.tooling.gradle.metamodel.model;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
public class AttributeMap extends AttributeSupport {
|
||||
private final Class<?> keyJavaType;
|
||||
private final Class<?> elementJavaType;
|
||||
|
||||
public AttributeMap(
|
||||
MetamodelClass metamodelClass,
|
||||
String attributeName,
|
||||
Class<?> keyJavaType,
|
||||
Class<?> elementJavaType) {
|
||||
super( metamodelClass, attributeName, Set.class );
|
||||
this.keyJavaType = keyJavaType;
|
||||
this.elementJavaType = elementJavaType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAttributeType(BufferedWriter writer) throws IOException {
|
||||
writer.write(
|
||||
format(
|
||||
"MapAttribute<%s,%s,%s>",
|
||||
getOwnerDomainClassName(),
|
||||
keyJavaType.getName(),
|
||||
elementJavaType.getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,34 +0,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
|
||||
*/
|
||||
package org.hibernate.orm.tooling.gradle.metamodel.model;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
public class AttributeSet extends AttributeSupport {
|
||||
private final Class<?> elementJavaType;
|
||||
|
||||
public AttributeSet(
|
||||
MetamodelClass metamodelClass,
|
||||
String attributeName,
|
||||
Class<?> elementJavaType) {
|
||||
super( metamodelClass, attributeName, Set.class );
|
||||
this.elementJavaType = elementJavaType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAttributeType(BufferedWriter writer) throws IOException {
|
||||
writer.write(
|
||||
format(
|
||||
"SetAttribute<%s,%s>",
|
||||
getOwnerDomainClassName(),
|
||||
elementJavaType.getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,29 +0,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
|
||||
*/
|
||||
package org.hibernate.orm.tooling.gradle.metamodel.model;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
public class AttributeSingular extends AttributeSupport {
|
||||
|
||||
public AttributeSingular(MetamodelClass metamodelClass, String name, Class javaType) {
|
||||
super( metamodelClass, name, javaType );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderAttributeType(BufferedWriter writer) throws IOException {
|
||||
// JPA stuff already imported
|
||||
writer.write(
|
||||
format(
|
||||
"SingularAttribute<%s,%s>",
|
||||
getOwnerDomainClassName(),
|
||||
getAttributeJavaType().getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,75 +0,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
|
||||
*/
|
||||
package org.hibernate.orm.tooling.gradle.metamodel.model;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import static java.lang.Character.LINE_SEPARATOR;
|
||||
|
||||
public abstract class AttributeSupport implements MetamodelAttribute {
|
||||
private final MetamodelClass metamodelClass;
|
||||
private final String name;
|
||||
private final Class<?> javaType;
|
||||
|
||||
public AttributeSupport(
|
||||
MetamodelClass metamodelClass,
|
||||
String name,
|
||||
Class<?> javaType) {
|
||||
this.metamodelClass = metamodelClass;
|
||||
this.name = name;
|
||||
this.javaType = javaType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getAttributeJavaType() {
|
||||
return javaType;
|
||||
}
|
||||
|
||||
public String getOwnerDomainClassName() {
|
||||
return metamodelClass.getMetamodelClassName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderJpaMembers(BufferedWriter writer) {
|
||||
try {
|
||||
writer.write( " public static volatile " );
|
||||
renderAttributeType( writer );
|
||||
writer.write( " " + name );
|
||||
writer.write( ';' );
|
||||
writer.write( LINE_SEPARATOR );
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new IllegalStateException( "Problem writing attribute `" + metamodelClass.getMetamodelClassName() + "#" + name + "` to output stream", e );
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void renderAttributeType(BufferedWriter writer) throws IOException;
|
||||
|
||||
protected String format(String pattern, Object... args) {
|
||||
return String.format( Locale.ROOT, pattern, args );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderNameConstant(BufferedWriter writer) {
|
||||
try {
|
||||
writer.write( " public static final String " );
|
||||
writer.write( getName().toUpperCase( Locale.ROOT ) );
|
||||
writer.write( " = \"" + getName() + "\";" );
|
||||
writer.write( LINE_SEPARATOR );
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new IllegalStateException( "Problem writing attribute `" + metamodelClass.getMetamodelClassName() + "#" + name + "` to output stream", e );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +0,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.
|
||||
*/
|
||||
package org.hibernate.orm.tooling.gradle.metamodel.model;
|
||||
|
||||
import org.gradle.api.file.Directory;
|
||||
import org.gradle.api.provider.Provider;
|
||||
import org.gradle.api.provider.SetProperty;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface GenerationOptions {
|
||||
Provider<Directory> getGenerationDirectory();
|
||||
Provider<Boolean> getApplyGeneratedAnnotation();
|
||||
SetProperty<String> getSuppressions();
|
||||
}
|
|
@ -1,101 +0,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
|
||||
*/
|
||||
package org.hibernate.orm.tooling.gradle.metamodel.model;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.gradle.api.file.Directory;
|
||||
import org.gradle.api.file.RegularFile;
|
||||
|
||||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.jpa.boot.spi.EntityManagerFactoryBuilder;
|
||||
import org.hibernate.mapping.Component;
|
||||
import org.hibernate.mapping.MappedSuperclass;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.mapping.Property;
|
||||
|
||||
import jakarta.persistence.spi.PersistenceUnitInfo;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static org.hibernate.jpa.boot.spi.Bootstrap.getEntityManagerFactoryBuilder;
|
||||
|
||||
public class JpaStaticMetamodelGenerator {
|
||||
|
||||
public static void processMetamodel(PersistenceUnitInfo persistenceUnitInfo, GenerationOptions options) {
|
||||
final EntityManagerFactoryBuilder target = getEntityManagerFactoryBuilder( persistenceUnitInfo, emptyMap() );
|
||||
try {
|
||||
new JpaStaticMetamodelGenerator( options, target.metadata() ).process();
|
||||
}
|
||||
finally {
|
||||
target.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private final GenerationOptions options;
|
||||
private final MetadataImplementor metadata;
|
||||
|
||||
private final Directory generationOutputDirectory;
|
||||
private final ObjectFactory objectFactory;
|
||||
|
||||
private final Set<String> processedDomainTypeNames = new HashSet<>();
|
||||
|
||||
private JpaStaticMetamodelGenerator(GenerationOptions options, MetadataImplementor metadata) {
|
||||
this.options = options;
|
||||
this.metadata = metadata;
|
||||
this.generationOutputDirectory = options.getGenerationDirectory().get();
|
||||
this.objectFactory = new ObjectFactory( metadata );
|
||||
}
|
||||
|
||||
private void process() {
|
||||
final Set<MappedSuperclass> mappedSuperclasses = metadata.getMappedSuperclassMappingsCopy();
|
||||
if ( mappedSuperclasses != null ) {
|
||||
mappedSuperclasses.forEach( this::handleMappedClass );
|
||||
}
|
||||
|
||||
final Collection<PersistentClass> entityBindings = metadata.getEntityBindings();
|
||||
if ( entityBindings != null ) {
|
||||
entityBindings.forEach( this::handlePersistentClass );
|
||||
}
|
||||
}
|
||||
|
||||
private void handleMappedClass(MappedSuperclass mappingDescriptor) {
|
||||
final MetamodelClass metamodelClass = objectFactory.metamodelClass( mappingDescriptor );
|
||||
handleManagedClass( metamodelClass, mappingDescriptor.getDeclaredProperties() );
|
||||
}
|
||||
|
||||
private void handlePersistentClass(PersistentClass persistentClass) {
|
||||
final MetamodelClass metamodelClass = objectFactory.metamodelClass( persistentClass );
|
||||
handleManagedClass( metamodelClass, persistentClass.getDeclaredProperties() );
|
||||
}
|
||||
|
||||
private void handleManagedClass(MetamodelClass metamodelClass, List<Property> properties) {
|
||||
if ( processedDomainTypeNames.add( metamodelClass.getDomainClassName() ) ) {
|
||||
// not yet processed
|
||||
for ( Property property : properties ) {
|
||||
metamodelClass.addAttribute(
|
||||
objectFactory.attribute( property, property.getValue(), metamodelClass, this::handleEmbeddable )
|
||||
);
|
||||
}
|
||||
|
||||
final String replaced = metamodelClass.getMetamodelClassName().replace( '.', '/' );
|
||||
final String metamodelClassJavaFileName = replaced + ".java";
|
||||
final RegularFile metamodelClassJavaFile = generationOutputDirectory.file( metamodelClassJavaFileName );
|
||||
|
||||
final File metamodelClassJavaFileAsFile = metamodelClassJavaFile.getAsFile();
|
||||
metamodelClass.writeToFile( metamodelClassJavaFileAsFile, options );
|
||||
}
|
||||
}
|
||||
|
||||
private void handleEmbeddable(Component embeddedValueMapping) {
|
||||
final MetamodelClass metamodelClass = objectFactory.metamodelClass( embeddedValueMapping );
|
||||
handleManagedClass( metamodelClass, embeddedValueMapping.getProperties() );
|
||||
}
|
||||
}
|
|
@ -1,19 +0,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
|
||||
*/
|
||||
package org.hibernate.orm.tooling.gradle.metamodel.model;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
|
||||
public interface MetamodelAttribute {
|
||||
String getName();
|
||||
|
||||
Class<?> getAttributeJavaType();
|
||||
|
||||
void renderJpaMembers(BufferedWriter writer);
|
||||
|
||||
void renderNameConstant(BufferedWriter writer);
|
||||
}
|
|
@ -1,148 +0,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
|
||||
*/
|
||||
package org.hibernate.orm.tooling.gradle.metamodel.model;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.gradle.api.GradleException;
|
||||
|
||||
import static java.lang.Character.LINE_SEPARATOR;
|
||||
|
||||
/**
|
||||
* Descriptor for a class in the JPA static metamodel being generated
|
||||
*/
|
||||
public class MetamodelClass {
|
||||
|
||||
private final String domainClassName;
|
||||
private final String metamodelClassName;
|
||||
|
||||
private final String metamodelSuperClassName;
|
||||
|
||||
private final TreeSet<MetamodelAttribute> attributes = new TreeSet<>( Comparator.comparing( MetamodelAttribute::getName ) );
|
||||
|
||||
public MetamodelClass(String domainClassName, String superTypeName) {
|
||||
this.domainClassName = domainClassName;
|
||||
this.metamodelClassName = domainClassName + "_";
|
||||
this.metamodelSuperClassName = superTypeName == null ? null : superTypeName + "_";
|
||||
}
|
||||
|
||||
public String getMetamodelClassName() {
|
||||
return metamodelClassName;
|
||||
}
|
||||
|
||||
public String getDomainClassName() {
|
||||
return domainClassName;
|
||||
}
|
||||
|
||||
public void addAttribute(MetamodelAttribute attribute) {
|
||||
assert attribute != null;
|
||||
attributes.add( attribute );
|
||||
}
|
||||
|
||||
public void writeToFile(File outputFile, GenerationOptions options) {
|
||||
prepareOutputFile( outputFile );
|
||||
|
||||
final Path path = outputFile.toPath();
|
||||
|
||||
try ( final BufferedWriter writer = Files.newBufferedWriter( path, StandardCharsets.UTF_8, StandardOpenOption.WRITE ) ) {
|
||||
|
||||
renderClassPreamble( writer, options );
|
||||
writer.write( LINE_SEPARATOR );
|
||||
|
||||
writer.write( "public abstract class " + metamodelClassName );
|
||||
if ( metamodelSuperClassName != null ) {
|
||||
writer.write( " extends " + metamodelSuperClassName );
|
||||
}
|
||||
writer.write( " {" );
|
||||
writer.write( LINE_SEPARATOR );
|
||||
writer.write( LINE_SEPARATOR );
|
||||
|
||||
writer.write( " // Attribute name constants" );
|
||||
writer.write( LINE_SEPARATOR );
|
||||
attributes.forEach( attribute -> attribute.renderNameConstant( writer ) );
|
||||
writer.write( LINE_SEPARATOR );
|
||||
writer.write( LINE_SEPARATOR );
|
||||
|
||||
writer.write( " // JPA static metamodel fields" );
|
||||
writer.write( LINE_SEPARATOR );
|
||||
attributes.forEach( attribute -> attribute.renderJpaMembers( writer ) );
|
||||
writer.write( LINE_SEPARATOR );
|
||||
|
||||
writer.write( "}" );
|
||||
writer.write( LINE_SEPARATOR );
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new IllegalStateException( "Unable to open file : " + outputFile.getAbsolutePath(), e );
|
||||
}
|
||||
}
|
||||
|
||||
private void renderClassPreamble(BufferedWriter writer, GenerationOptions options) throws IOException {
|
||||
final String nowFormatted = DateFormat.getDateInstance().format( new Date() );
|
||||
|
||||
writer.write( "// Generated by Hibernate ORM Gradle tooling - " + nowFormatted );
|
||||
writer.write( LINE_SEPARATOR );
|
||||
writer.write( LINE_SEPARATOR );
|
||||
|
||||
writer.write( "import jakarta.persistence.*;" );
|
||||
writer.write( LINE_SEPARATOR );
|
||||
writer.write( "import jakarta.persistence.metamodel.*;" );
|
||||
writer.write( LINE_SEPARATOR );
|
||||
writer.write( LINE_SEPARATOR );
|
||||
|
||||
writer.write( "/** JPA static metamodel descriptor for the `" + domainClassName + "` domain class */" );
|
||||
writer.write( LINE_SEPARATOR );
|
||||
|
||||
// first, the generated annotation
|
||||
if ( options.getApplyGeneratedAnnotation().getOrElse( true ) ) {
|
||||
final String generatedAnnotationFragment = String.format(
|
||||
Locale.ROOT,
|
||||
"@jakarta.annotation.Generated( value=\"%s\", date=\"%s\", comments=\"%s\" )",
|
||||
JpaStaticMetamodelGenerator.class.getName(),
|
||||
nowFormatted,
|
||||
"Generated by Hibernate ORM Gradle tooling"
|
||||
);
|
||||
writer.write( generatedAnnotationFragment );
|
||||
writer.write( LINE_SEPARATOR );
|
||||
}
|
||||
|
||||
final Set<String> suppressions = options.getSuppressions().getOrElse( Collections.emptySet() );
|
||||
if ( ! suppressions.isEmpty() ) {
|
||||
writer.write( "@SuppressWarnings( { " );
|
||||
for ( String suppression : suppressions ) {
|
||||
writer.write( "\"" + suppression + "\", " );
|
||||
}
|
||||
writer.write( " } )" );
|
||||
writer.write( LINE_SEPARATOR );
|
||||
}
|
||||
|
||||
writer.write( "@StaticMetamodel( " + domainClassName + ".class )" );
|
||||
}
|
||||
|
||||
@SuppressWarnings( "ResultOfMethodCallIgnored" )
|
||||
public void prepareOutputFile(File outputFile) {
|
||||
try {
|
||||
outputFile.getParentFile().mkdirs();
|
||||
outputFile.createNewFile();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new GradleException( "Unable to prepare output file `" + outputFile.getAbsolutePath() + "`", e );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,237 +0,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
|
||||
*/
|
||||
package org.hibernate.orm.tooling.gradle.metamodel.model;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.gradle.api.GradleException;
|
||||
|
||||
import org.hibernate.boot.spi.MetadataImplementor;
|
||||
import org.hibernate.mapping.Any;
|
||||
import org.hibernate.mapping.Bag;
|
||||
import org.hibernate.mapping.BasicValue;
|
||||
import org.hibernate.mapping.Collection;
|
||||
import org.hibernate.mapping.Component;
|
||||
import org.hibernate.mapping.DependantValue;
|
||||
import org.hibernate.mapping.KeyValue;
|
||||
import org.hibernate.mapping.List;
|
||||
import org.hibernate.mapping.Map;
|
||||
import org.hibernate.mapping.MappedSuperclass;
|
||||
import org.hibernate.mapping.OneToMany;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.mapping.Set;
|
||||
import org.hibernate.mapping.ToOne;
|
||||
import org.hibernate.mapping.Value;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ObjectFactory {
|
||||
private final MetadataImplementor metadata;
|
||||
|
||||
public ObjectFactory(MetadataImplementor metadata) {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
public MetamodelClass metamodelClass(PersistentClass entityDescriptor) {
|
||||
return new MetamodelClass( entityDescriptor.getMappedClass().getName(), determineSuperTypeName( entityDescriptor ) );
|
||||
}
|
||||
|
||||
private String determineSuperTypeName(PersistentClass entityDescriptor) {
|
||||
if ( entityDescriptor.getSuperMappedSuperclass() != null ) {
|
||||
return entityDescriptor.getSuperMappedSuperclass().getMappedClass().getName();
|
||||
}
|
||||
|
||||
if ( entityDescriptor.getSuperclass() != null ) {
|
||||
return entityDescriptor.getSuperclass().getMappedClass().getName();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public MetamodelClass metamodelClass(MappedSuperclass mappedSuperclassDescriptor) {
|
||||
return new MetamodelClass( mappedSuperclassDescriptor.getMappedClass().getName(), determineSuperTypeName( mappedSuperclassDescriptor ) );
|
||||
}
|
||||
|
||||
private String determineSuperTypeName(MappedSuperclass mappedSuperclassDescriptor) {
|
||||
if ( mappedSuperclassDescriptor.getSuperMappedSuperclass() != null ) {
|
||||
return mappedSuperclassDescriptor.getSuperMappedSuperclass().getMappedClass().getName();
|
||||
}
|
||||
|
||||
if ( mappedSuperclassDescriptor.getSuperPersistentClass() != null ) {
|
||||
return mappedSuperclassDescriptor.getSuperPersistentClass().getMappedClass().getName();
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public MetamodelClass metamodelClass(Component embeddedMapping) {
|
||||
return new MetamodelClass( embeddedMapping.getComponentClassName(), null );
|
||||
}
|
||||
|
||||
public MetamodelAttribute attribute(
|
||||
Property property,
|
||||
Value propertyValueMapping,
|
||||
MetamodelClass metamodelClass,
|
||||
Consumer<Component> componentConsumer) {
|
||||
if ( propertyValueMapping instanceof DependantValue ) {
|
||||
final DependantValue dependantValue = (DependantValue) propertyValueMapping;
|
||||
final KeyValue wrappedValue = dependantValue.getWrappedValue();
|
||||
return attribute( property, wrappedValue, metamodelClass, componentConsumer );
|
||||
}
|
||||
|
||||
if ( propertyValueMapping instanceof Collection ) {
|
||||
return pluralAttribute( property, (Collection) propertyValueMapping, metamodelClass, componentConsumer );
|
||||
}
|
||||
|
||||
final Class<?> propertyJavaType = determineSingularJavaType( property, propertyValueMapping, metamodelClass, componentConsumer );
|
||||
return new AttributeSingular( metamodelClass, property.getName(), propertyJavaType );
|
||||
}
|
||||
|
||||
private Class<?> determineSingularJavaType(
|
||||
Property property,
|
||||
Value propertyValueMapping,
|
||||
MetamodelClass metamodelClass,
|
||||
Consumer<Component> componentConsumer) {
|
||||
if ( propertyValueMapping instanceof BasicValue ) {
|
||||
final BasicValue basicValue = (BasicValue) propertyValueMapping;
|
||||
return basicValue.resolve().getDomainJavaType().getJavaTypeClass();
|
||||
}
|
||||
|
||||
if ( propertyValueMapping instanceof Component ) {
|
||||
final Component component = (Component) propertyValueMapping;
|
||||
componentConsumer.accept( component );
|
||||
return component.getComponentClass();
|
||||
}
|
||||
|
||||
if ( propertyValueMapping instanceof Any ) {
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
if ( propertyValueMapping instanceof ToOne ) {
|
||||
final ToOne toOne = (ToOne) propertyValueMapping;
|
||||
final String referencedEntityName = toOne.getReferencedEntityName();
|
||||
final PersistentClass entityBinding = metadata.getEntityBinding( referencedEntityName );
|
||||
final Class<?> mappedClass = entityBinding.getMappedClass();
|
||||
if ( mappedClass == null ) {
|
||||
throw new GradleException(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"Could not determine ToOne java type : %s#%s",
|
||||
metamodelClass.getDomainClassName(),
|
||||
property.getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
return mappedClass;
|
||||
}
|
||||
|
||||
propertyValueMapping.setTypeUsingReflection( metamodelClass.getDomainClassName(), property.getName() );
|
||||
return propertyValueMapping.getType().getReturnedClass();
|
||||
}
|
||||
|
||||
private MetamodelAttribute pluralAttribute(
|
||||
Property property,
|
||||
Collection collectionMapping,
|
||||
MetamodelClass metamodelClass,
|
||||
Consumer<Component> componentConsumer) {
|
||||
if ( collectionMapping instanceof Set ) {
|
||||
return new AttributeSet(
|
||||
metamodelClass,
|
||||
property.getName(),
|
||||
determineCollectionPartJavaType( property, collectionMapping.getElement(), metamodelClass, componentConsumer )
|
||||
);
|
||||
}
|
||||
|
||||
if ( collectionMapping instanceof Bag ) {
|
||||
return new AttributeBag(
|
||||
metamodelClass,
|
||||
property.getName(),
|
||||
determineCollectionPartJavaType( property, collectionMapping.getElement(), metamodelClass, componentConsumer )
|
||||
);
|
||||
}
|
||||
|
||||
if ( collectionMapping instanceof List ) {
|
||||
return new AttributeList(
|
||||
metamodelClass,
|
||||
property.getName(),
|
||||
determineCollectionPartJavaType( property, collectionMapping.getElement(), metamodelClass, componentConsumer )
|
||||
);
|
||||
}
|
||||
|
||||
if ( collectionMapping instanceof Map ) {
|
||||
return new AttributeMap(
|
||||
metamodelClass,
|
||||
property.getName(),
|
||||
determineCollectionPartJavaType( property, ( (Map) collectionMapping ).getIndex(), metamodelClass, componentConsumer ),
|
||||
determineCollectionPartJavaType( property, collectionMapping.getElement(), metamodelClass, componentConsumer )
|
||||
);
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException( "Unsupported plural value type : " + collectionMapping.getClass().getName() );
|
||||
}
|
||||
|
||||
private Class<?> determineCollectionPartJavaType(
|
||||
Property property,
|
||||
Value partJavaType,
|
||||
MetamodelClass metamodelClass,
|
||||
Consumer<Component> componentConsumer) {
|
||||
if ( partJavaType instanceof DependantValue ) {
|
||||
final DependantValue dependantValue = (DependantValue) partJavaType;
|
||||
final KeyValue wrappedValue = dependantValue.getWrappedValue();
|
||||
return determineCollectionPartJavaType( property, wrappedValue, metamodelClass, componentConsumer );
|
||||
}
|
||||
|
||||
if ( partJavaType instanceof BasicValue ) {
|
||||
final BasicValue basicValue = (BasicValue) partJavaType;
|
||||
return basicValue.resolve().getDomainJavaType().getJavaTypeClass();
|
||||
}
|
||||
|
||||
if ( partJavaType instanceof Component ) {
|
||||
final Component component = (Component) partJavaType;
|
||||
componentConsumer.accept( component );
|
||||
return component.getComponentClass();
|
||||
}
|
||||
|
||||
if ( partJavaType instanceof Any ) {
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
if ( partJavaType instanceof OneToMany ) {
|
||||
final OneToMany oneToMany = (OneToMany) partJavaType;
|
||||
final PersistentClass associatedClass = oneToMany.getAssociatedClass();
|
||||
return associatedClass.getMappedClass();
|
||||
}
|
||||
|
||||
if ( partJavaType instanceof ToOne ) {
|
||||
final ToOne toOne = (ToOne) partJavaType;
|
||||
final String referencedEntityName = toOne.getReferencedEntityName();
|
||||
if ( referencedEntityName != null ) {
|
||||
final PersistentClass entityBinding = metadata.getEntityBinding( referencedEntityName );
|
||||
if ( entityBinding != null ) {
|
||||
final Class<?> mappedClass = entityBinding.getMappedClass();
|
||||
if ( mappedClass != null ) {
|
||||
return mappedClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new GradleException(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"Could not determine ToOne java type : %s#%s",
|
||||
metamodelClass.getDomainClassName(),
|
||||
property.getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return partJavaType.getType().getReturnedClass();
|
||||
}
|
||||
}
|
|
@ -50,15 +50,4 @@ class JavaProjectTests extends TestsBase {
|
|||
public void testEnhancementUpToDate(@TempDir Path projectDir) throws Exception {
|
||||
super.testEnhancementUpToDate( projectDir );
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testJpaMetamodelGen(@TempDir Path projectDir) {
|
||||
super.testJpaMetamodelGen( projectDir );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJpaMetamodelGenUpToDate(@TempDir Path projectDir) {
|
||||
super.testJpaMetamodelGenUpToDate( projectDir );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,16 +47,4 @@ public class KotlinProjectTests extends TestsBase {
|
|||
public void testEnhancementUpToDate(@TempDir Path projectDir) throws Exception {
|
||||
super.testEnhancementUpToDate( projectDir );
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testJpaMetamodelGen(@TempDir Path projectDir) {
|
||||
super.testJpaMetamodelGen( projectDir );
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
public void testJpaMetamodelGenUpToDate(@TempDir Path projectDir) {
|
||||
super.testJpaMetamodelGenUpToDate( projectDir );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,14 +40,4 @@ public class MultiPartNameTests extends TestsBase {
|
|||
public void testEnhancementUpToDate(@TempDir Path projectDir) throws Exception {
|
||||
super.testEnhancementUpToDate( projectDir );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJpaMetamodelGen(@TempDir Path projectDir) {
|
||||
super.testJpaMetamodelGen( projectDir );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJpaMetamodelGenUpToDate(@TempDir Path projectDir) {
|
||||
super.testJpaMetamodelGenUpToDate( projectDir );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import org.gradle.testkit.runner.GradleRunner;
|
|||
import org.gradle.testkit.runner.TaskOutcome;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
|
||||
|
@ -98,63 +97,4 @@ public abstract class TestsBase {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJpaMetamodelGen(@TempDir Path projectDir) {
|
||||
final String buildFilePath = getProjectName() + "/build.gradle";
|
||||
Copier.copyProject( buildFilePath, projectDir );
|
||||
|
||||
System.out.println( "Starting execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
|
||||
|
||||
final GradleRunner gradleRunner = GradleRunner.create()
|
||||
.withProjectDir( projectDir.toFile() )
|
||||
.withPluginClasspath()
|
||||
.withDebug( true )
|
||||
.withArguments( "clean", "generateJpaMetamodel", "--stacktrace", "--no-build-cache" )
|
||||
.forwardOutput();
|
||||
|
||||
final BuildResult result = gradleRunner.build();
|
||||
final BuildTask task = result.task( ":generateJpaMetamodel" );
|
||||
assertThat( task ).isNotNull();
|
||||
assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS );
|
||||
assertThat( new File( projectDir.toFile(), "build/classes/java/jpaMetamodel" ) ).exists();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJpaMetamodelGenUpToDate(@TempDir Path projectDir) {
|
||||
final String buildFilePath = getProjectName() + "/build.gradle";
|
||||
Copier.copyProject( buildFilePath, projectDir );
|
||||
|
||||
{
|
||||
System.out.println( "Starting first execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
|
||||
final GradleRunner gradleRunner = GradleRunner.create()
|
||||
.withProjectDir( projectDir.toFile() )
|
||||
.withPluginClasspath()
|
||||
.withDebug( true )
|
||||
.withArguments( "clean", "generateJpaMetamodel", "--stacktrace", "--no-build-cache" )
|
||||
.forwardOutput();
|
||||
|
||||
final BuildResult result = gradleRunner.build();
|
||||
final BuildTask task = result.task( ":generateJpaMetamodel" );
|
||||
assertThat( task ).isNotNull();
|
||||
assertThat( task.getOutcome() ).isEqualTo( TaskOutcome.SUCCESS );
|
||||
assertThat( new File( projectDir.toFile(), "build/classes/java/jpaMetamodel" ) ).exists();
|
||||
}
|
||||
|
||||
{
|
||||
System.out.println( "Starting second execution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
|
||||
final GradleRunner gradleRunner2 = GradleRunner.create()
|
||||
.withProjectDir( projectDir.toFile() )
|
||||
.withPluginClasspath()
|
||||
.withDebug( true )
|
||||
.withArguments( "generateJpaMetamodel", "--stacktrace", "--no-build-cache" )
|
||||
.forwardOutput();
|
||||
|
||||
final BuildResult result2 = gradleRunner2.build();
|
||||
final BuildTask task2 = result2.task( ":generateJpaMetamodel" );
|
||||
assertThat( task2 ).isNotNull();
|
||||
assertThat( task2.getOutcome() ).isEqualTo( TaskOutcome.UP_TO_DATE );
|
||||
assertThat( new File( projectDir.toFile(), "build/classes/java/jpaMetamodel" ) ).exists();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -43,6 +43,4 @@ hibernate {
|
|||
enableDirtyTracking.set(true)
|
||||
dirtyTracking = true
|
||||
}
|
||||
jpaMetamodel {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,4 @@ hibernate {
|
|||
enableDirtyTracking.set(true)
|
||||
dirtyTracking = true
|
||||
}
|
||||
jpaMetamodel {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,4 @@ hibernate {
|
|||
enableDirtyTracking.set(true)
|
||||
dirtyTracking = true
|
||||
}
|
||||
jpaMetamodel {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,33 +0,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
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.hibernate.orm'
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
||||
maven {
|
||||
name 'jboss-snapshots-repository'
|
||||
url 'https://repository.jboss.org/nexus/content/repositories/snapshots'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'jakarta.persistence:jakarta.persistence-api:3.0.0'
|
||||
}
|
||||
|
||||
hibernate {
|
||||
enhancement {
|
||||
lazyInitialization( true )
|
||||
dirtyTracking = true
|
||||
}
|
||||
jpaMetamodel {
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue