diff --git a/tooling/metamodel-generator/hibernate-jpamodelgen.gradle b/tooling/metamodel-generator/hibernate-jpamodelgen.gradle index 259383461e..13654989cc 100644 --- a/tooling/metamodel-generator/hibernate-jpamodelgen.gradle +++ b/tooling/metamodel-generator/hibernate-jpamodelgen.gradle @@ -18,9 +18,27 @@ ext { xsdDir = file( "${projectDir}/src/main/xsd" ) } -configurations { - quarkusOrmPanache - quarkusHrPanache +sourceSets { + quarkusOrmPanache { + java { + srcDirs = ['src/quarkusOrmPanache/java'] + } + resources { + srcDirs tasks.processTestResources + } + compileClasspath += sourceSets.main.output + sourceSets.test.output + runtimeClasspath += sourceSets.main.output + sourceSets.test.output + } + quarkusHrPanache { + java { + srcDirs = ['src/quarkusHrPanache/java'] + } + resources { + srcDirs tasks.processTestResources + } + compileClasspath += sourceSets.main.output + sourceSets.test.output + runtimeClasspath += sourceSets.main.output + sourceSets.test.output + } } dependencies { @@ -37,16 +55,26 @@ dependencies { xjc jakartaLibs.jaxb xjc rootProject.fileTree(dir: 'patched-libs/jaxb2-basics', include: '*.jar') - quarkusOrmPanache "io.quarkus:quarkus-hibernate-orm-panache:3.6.2" - quarkusHrPanache "io.quarkus:quarkus-hibernate-reactive-panache:3.6.2" + quarkusOrmPanacheImplementation "io.quarkus:quarkus-hibernate-orm-panache:3.6.2" + quarkusHrPanacheImplementation "io.quarkus:quarkus-hibernate-reactive-panache:3.6.2" +} + +// The source set gets a custom configuration which extends the normal test implementation config +configurations { + quarkusOrmPanacheImplementation.extendsFrom(testImplementation) + quarkusOrmPanacheRuntimeOnly.extendsFrom(testRuntimeOnly) + quarkusOrmPanacheCompileOnly.extendsFrom(testCompileOnly) + quarkusHrPanacheImplementation.extendsFrom(testImplementation) + quarkusHrPanacheRuntimeOnly.extendsFrom(testRuntimeOnly) + quarkusHrPanacheCompileOnly.extendsFrom(testCompileOnly) } def quarkusOrmPanacheTestTask = tasks.register( 'quarkusOrmPanacheTest', Test ) { description = 'Runs the Quarkus ORM Panache tests.' group = 'verification' - testClassesDirs = sourceSets.test.output.classesDirs - classpath = sourceSets.test.runtimeClasspath + configurations.quarkusOrmPanache + testClassesDirs = sourceSets.quarkusOrmPanache.output.classesDirs + classpath = sourceSets.quarkusOrmPanache.runtimeClasspath shouldRunAfter test dependsOn test } @@ -55,8 +83,8 @@ def quarkusHrPanacheTestTask = tasks.register( 'quarkusHrPanacheTest', Test ) { description = 'Runs the Quarkus HR Panache tests.' group = 'verification' - testClassesDirs = sourceSets.test.output.classesDirs - classpath = sourceSets.test.runtimeClasspath + configurations.quarkusHrPanache + testClassesDirs = sourceSets.quarkusHrPanache.output.classesDirs + classpath = sourceSets.quarkusHrPanache.runtimeClasspath shouldRunAfter test dependsOn test } diff --git a/tooling/metamodel-generator/src/quarkusHrPanache/java/org/hibernate/jpamodelgen/test/hrPanache/BookRepositoryWithSession.java b/tooling/metamodel-generator/src/quarkusHrPanache/java/org/hibernate/jpamodelgen/test/hrPanache/BookRepositoryWithSession.java new file mode 100644 index 0000000000..108e3de615 --- /dev/null +++ b/tooling/metamodel-generator/src/quarkusHrPanache/java/org/hibernate/jpamodelgen/test/hrPanache/BookRepositoryWithSession.java @@ -0,0 +1,19 @@ +package org.hibernate.jpamodelgen.test.hrPanache; + +import java.util.List; + +import org.hibernate.annotations.processing.Find; +import org.hibernate.reactive.mutiny.Mutiny; + +import io.quarkus.hibernate.reactive.panache.common.runtime.SessionOperations; +import io.smallrye.mutiny.Uni; + +public interface BookRepositoryWithSession { + + public default Uni mySession() { + return SessionOperations.getSession(); + } + + @Find + public Uni> findBook(String isbn); +} diff --git a/tooling/metamodel-generator/src/quarkusHrPanache/java/org/hibernate/jpamodelgen/test/hrPanache/PanacheBook.java b/tooling/metamodel-generator/src/quarkusHrPanache/java/org/hibernate/jpamodelgen/test/hrPanache/PanacheBook.java new file mode 100644 index 0000000000..a9ee6efe9d --- /dev/null +++ b/tooling/metamodel-generator/src/quarkusHrPanache/java/org/hibernate/jpamodelgen/test/hrPanache/PanacheBook.java @@ -0,0 +1,28 @@ +package org.hibernate.jpamodelgen.test.hrPanache; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; + +import java.util.List; + +import org.hibernate.annotations.NaturalId; +import org.hibernate.annotations.processing.Find; +import org.hibernate.annotations.processing.HQL; + +import io.quarkus.hibernate.reactive.panache.PanacheEntity; +import io.smallrye.mutiny.Uni; + +@Entity +public class PanacheBook extends PanacheEntity { + public @Id String isbn; + public @NaturalId String title; + public @NaturalId String author; + public String text; + public int pages; + + @Find + public static native Uni> findBook(String isbn); + + @HQL("WHERE isbn = :isbn") + public static native Uni> hqlBook(String isbn); +} diff --git a/tooling/metamodel-generator/src/quarkusHrPanache/java/org/hibernate/jpamodelgen/test/hrPanache/PanacheBookRepository.java b/tooling/metamodel-generator/src/quarkusHrPanache/java/org/hibernate/jpamodelgen/test/hrPanache/PanacheBookRepository.java new file mode 100644 index 0000000000..80e0b426f4 --- /dev/null +++ b/tooling/metamodel-generator/src/quarkusHrPanache/java/org/hibernate/jpamodelgen/test/hrPanache/PanacheBookRepository.java @@ -0,0 +1,19 @@ +package org.hibernate.jpamodelgen.test.hrPanache; + +import java.util.List; + +import org.hibernate.annotations.processing.Find; +import org.hibernate.annotations.processing.HQL; + +import io.quarkus.hibernate.reactive.panache.PanacheRepository; +import io.smallrye.mutiny.Uni; +import jakarta.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class PanacheBookRepository implements PanacheRepository { + @Find + public native Uni> findBook(String isbn); + + @HQL("WHERE isbn = :isbn") + public native Uni> hqlBook(String isbn); +} diff --git a/tooling/metamodel-generator/src/quarkusHrPanache/java/org/hibernate/jpamodelgen/test/hrPanache/QuarkusBookRepository.java b/tooling/metamodel-generator/src/quarkusHrPanache/java/org/hibernate/jpamodelgen/test/hrPanache/QuarkusBookRepository.java new file mode 100644 index 0000000000..5130ef03ce --- /dev/null +++ b/tooling/metamodel-generator/src/quarkusHrPanache/java/org/hibernate/jpamodelgen/test/hrPanache/QuarkusBookRepository.java @@ -0,0 +1,22 @@ +package org.hibernate.jpamodelgen.test.hrPanache; + +import java.util.List; + +import org.hibernate.annotations.processing.Find; +import org.hibernate.annotations.processing.HQL; + +import io.smallrye.mutiny.Uni; + +public interface QuarkusBookRepository { + @Find + public Uni> findBook(String isbn); + + @HQL("WHERE isbn = :isbn") + public Uni> hqlBook(String isbn); + + @HQL("DELETE FROM PanacheBook") + public Uni deleteAllBooksVoid(); + + @HQL("DELETE FROM PanacheBook") + public Uni deleteAllBooksInt(); +} diff --git a/tooling/metamodel-generator/src/quarkusHrPanache/java/org/hibernate/jpamodelgen/test/hrPanache/QuarkusHrPanacheTest.java b/tooling/metamodel-generator/src/quarkusHrPanache/java/org/hibernate/jpamodelgen/test/hrPanache/QuarkusHrPanacheTest.java new file mode 100644 index 0000000000..6ed1025da8 --- /dev/null +++ b/tooling/metamodel-generator/src/quarkusHrPanache/java/org/hibernate/jpamodelgen/test/hrPanache/QuarkusHrPanacheTest.java @@ -0,0 +1,151 @@ +/* + * 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 . + */ +package org.hibernate.jpamodelgen.test.hrPanache; + +import org.hibernate.jpamodelgen.test.util.CompilationTest; +import org.hibernate.jpamodelgen.test.util.TestUtil; +import org.hibernate.jpamodelgen.test.util.WithClasses; +import org.junit.Test; +import org.junit.jupiter.api.Assertions; + +import io.smallrye.mutiny.Uni; +import jakarta.inject.Inject; +import jakarta.persistence.EntityManager; + +import static org.hibernate.jpamodelgen.test.util.TestUtil.getMetamodelClassFor; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +/** + * @author Gavin King + */ +public class QuarkusHrPanacheTest extends CompilationTest { + @Test + @WithClasses({ PanacheBook.class }) + public void testPanacheEntityMetamodel() throws Exception { + // Panache entity + System.out.println( TestUtil.getMetaModelSourceAsString( PanacheBook.class ) ); + Class entityClass = getMetamodelClassFor( PanacheBook.class ); + Assertions.assertNotNull( entityClass ); + + // Make sure it has the proper supertype + Class superclass = entityClass.getSuperclass(); + if ( superclass != null ) { + Assertions.assertEquals( "io.quarkus.hibernate.reactive.panache.PanacheEntity_", superclass.getName() ); + } + + // Panache static native method generates a static method + Method method = entityClass.getDeclaredMethod( "hqlBook", Uni.class, String.class ); + Assertions.assertNotNull( method ); + checkUni(method); + Assertions.assertTrue( Modifier.isStatic( method.getModifiers()) ); + + // Panache static native method generates a static method + method = entityClass.getDeclaredMethod( "findBook", Uni.class, String.class ); + Assertions.assertNotNull( method ); + checkUni(method); + Assertions.assertTrue( Modifier.isStatic( method.getModifiers() ) ); + } + + @Test + @WithClasses({ PanacheBook.class, PanacheBookRepository.class }) + public void testPanacheRepositoryMetamodel() throws Exception { + // Panache repository + System.out.println( TestUtil.getMetaModelSourceAsString( PanacheBookRepository.class ) ); + Class repositoryClass = getMetamodelClassFor( PanacheBookRepository.class ); + Assertions.assertNotNull( repositoryClass ); + + // Make sure it has the proper supertype + Class superclass = repositoryClass.getSuperclass(); + if ( superclass != null ) { + Assertions.assertEquals( "java.lang.Object", superclass.getName() ); + } + + // Panache native method generates a static method + Method method = repositoryClass.getDeclaredMethod( "hqlBook", Uni.class, String.class ); + Assertions.assertNotNull( method ); + checkUni(method); + Assertions.assertTrue( Modifier.isStatic(method.getModifiers()) ); + + // Panache native method generates a static method + method = repositoryClass.getDeclaredMethod( "findBook", Uni.class, String.class ); + Assertions.assertNotNull( method ); + checkUni(method); + Assertions.assertTrue( Modifier.isStatic( method.getModifiers() ) ); + } + + private void checkUni(Method method) { + Assertions.assertEquals("io.smallrye.mutiny.Uni", method.getGenericParameterTypes()[0].toString()); + } + + @Test + @WithClasses({ PanacheBook.class, QuarkusBookRepository.class }) + public void testQuarkusRepositoryMetamodel() throws Exception { + // Regular repository + System.out.println( TestUtil.getMetaModelSourceAsString( QuarkusBookRepository.class ) ); + Class repositoryClass = getMetamodelClassFor( QuarkusBookRepository.class ); + Assertions.assertNotNull( repositoryClass ); + + // Make sure it has the proper supertype + Class superclass = repositoryClass.getSuperclass(); + if ( superclass != null ) { + Assertions.assertEquals( "java.lang.Object", superclass.getName() ); + } + Class[] interfaces = repositoryClass.getInterfaces(); + Assertions.assertEquals( 1, interfaces.length ); + Assertions.assertEquals( QuarkusBookRepository.class.getName(), interfaces[0].getName() ); + + // Annotated method generates an instance method + Method method = repositoryClass.getDeclaredMethod( "hqlBook", String.class ); + Assertions.assertNotNull( method ); + Assertions.assertFalse( Modifier.isStatic( method.getModifiers() ) ); + + // Annotated method generates an instance method + method = repositoryClass.getDeclaredMethod( "findBook", String.class ); + Assertions.assertNotNull( method ); + Assertions.assertFalse( Modifier.isStatic( method.getModifiers() ) ); + + // Make sure we have only the default constructor + Constructor[] constructors = repositoryClass.getDeclaredConstructors(); + Assertions.assertNotNull( constructors ); + Assertions.assertEquals( 1, constructors.length ); + Assertions.assertNotNull( repositoryClass.getDeclaredConstructor() ); + + // Proper return type + method = repositoryClass.getDeclaredMethod( "deleteAllBooksVoid" ); + Assertions.assertNotNull( method ); + Assertions.assertEquals("io.smallrye.mutiny.Uni", method.getGenericReturnType().toString()); + Assertions.assertFalse( Modifier.isStatic( method.getModifiers() ) ); + + // Proper return type + method = repositoryClass.getDeclaredMethod( "deleteAllBooksInt" ); + Assertions.assertNotNull( method ); + Assertions.assertEquals("io.smallrye.mutiny.Uni", method.getGenericReturnType().toString()); + Assertions.assertFalse( Modifier.isStatic( method.getModifiers() ) ); + } + + @Test + @WithClasses({ PanacheBook.class, BookRepositoryWithSession.class }) + public void testBookRepositoryWithSessionMetamodel() throws Exception { + // Regular repository with default session method + System.out.println( TestUtil.getMetaModelSourceAsString( BookRepositoryWithSession.class ) ); + Class repositoryClass = getMetamodelClassFor( BookRepositoryWithSession.class ); + Assertions.assertNotNull( repositoryClass ); + + // Make sure we have only the default constructor + Constructor[] constructors = repositoryClass.getDeclaredConstructors(); + Assertions.assertNotNull( constructors ); + Assertions.assertEquals( 1, constructors.length ); + Assertions.assertNotNull( repositoryClass.getDeclaredConstructor() ); + + // Make sure we do not override the default session method + Assertions.assertThrows( NoSuchMethodException.class, () -> repositoryClass.getDeclaredMethod( "mySession" ) ); + } +} + diff --git a/tooling/metamodel-generator/src/quarkusOrmPanache/java/org/hibernate/jpamodelgen/test/ormPanache/QuarkusBookRepository.java b/tooling/metamodel-generator/src/quarkusOrmPanache/java/org/hibernate/jpamodelgen/test/ormPanache/QuarkusBookRepository.java new file mode 100644 index 0000000000..7ee1ee93af --- /dev/null +++ b/tooling/metamodel-generator/src/quarkusOrmPanache/java/org/hibernate/jpamodelgen/test/ormPanache/QuarkusBookRepository.java @@ -0,0 +1,14 @@ +package org.hibernate.jpamodelgen.test.ormPanache; + +import java.util.List; + +import org.hibernate.annotations.processing.Find; +import org.hibernate.annotations.processing.HQL; + +public interface QuarkusBookRepository { + @Find + public List findBook(String isbn); + + @HQL("WHERE isbn = :isbn") + public List hqlBook(String isbn); +} diff --git a/tooling/metamodel-generator/src/quarkusOrmPanache/java/org/hibernate/jpamodelgen/test/ormPanache/QuarkusOrmPanacheTest.java b/tooling/metamodel-generator/src/quarkusOrmPanache/java/org/hibernate/jpamodelgen/test/ormPanache/QuarkusOrmPanacheTest.java index 4e86cd0838..7894c069de 100644 --- a/tooling/metamodel-generator/src/quarkusOrmPanache/java/org/hibernate/jpamodelgen/test/ormPanache/QuarkusOrmPanacheTest.java +++ b/tooling/metamodel-generator/src/quarkusOrmPanache/java/org/hibernate/jpamodelgen/test/ormPanache/QuarkusOrmPanacheTest.java @@ -12,10 +12,12 @@ import org.hibernate.jpamodelgen.test.util.WithClasses; import org.junit.Test; import org.junit.jupiter.api.Assertions; +import jakarta.inject.Inject; import jakarta.persistence.EntityManager; import static org.hibernate.jpamodelgen.test.util.TestUtil.getMetamodelClassFor; +import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -29,23 +31,23 @@ public class QuarkusOrmPanacheTest extends CompilationTest { // Panache entity System.out.println( TestUtil.getMetaModelSourceAsString( PanacheBook.class ) ); Class entityClass = getMetamodelClassFor( PanacheBook.class ); - Assertions.assertNotNull(entityClass); + Assertions.assertNotNull( entityClass ); // Make sure it has the proper supertype Class superclass = entityClass.getSuperclass(); - if(superclass != null) { - Assertions.assertEquals("io.quarkus.hibernate.orm.panache.PanacheEntity_", superclass.getName()); + if ( superclass != null ) { + Assertions.assertEquals( "io.quarkus.hibernate.orm.panache.PanacheEntity_", superclass.getName() ); } // Panache static native method generates a static method - Method method = entityClass.getDeclaredMethod("hqlBook", EntityManager.class, String.class); - Assertions.assertNotNull(method); - Assertions.assertTrue(Modifier.isStatic(method.getModifiers())); + Method method = entityClass.getDeclaredMethod( "hqlBook", EntityManager.class, String.class ); + Assertions.assertNotNull( method ); + Assertions.assertTrue( Modifier.isStatic( method.getModifiers()) ); // Panache static native method generates a static method - method = entityClass.getDeclaredMethod("findBook", EntityManager.class, String.class); - Assertions.assertNotNull(method); - Assertions.assertTrue(Modifier.isStatic(method.getModifiers())); + method = entityClass.getDeclaredMethod( "findBook", EntityManager.class, String.class ); + Assertions.assertNotNull( method ); + Assertions.assertTrue( Modifier.isStatic( method.getModifiers() ) ); } @Test @@ -54,22 +56,55 @@ public class QuarkusOrmPanacheTest extends CompilationTest { // Panache repository System.out.println( TestUtil.getMetaModelSourceAsString( PanacheBookRepository.class ) ); Class repositoryClass = getMetamodelClassFor( PanacheBookRepository.class ); - Assertions.assertNotNull(repositoryClass); + Assertions.assertNotNull( repositoryClass ); // Make sure it has the proper supertype Class superclass = repositoryClass.getSuperclass(); - if(superclass != null) { - Assertions.assertEquals("java.lang.Object", superclass.getName()); + if ( superclass != null ) { + Assertions.assertEquals( "java.lang.Object", superclass.getName() ); } // Panache native method generates a static method - Method method = repositoryClass.getDeclaredMethod("hqlBook", EntityManager.class, String.class); - Assertions.assertNotNull(method); - Assertions.assertTrue(Modifier.isStatic(method.getModifiers())); + Method method = repositoryClass.getDeclaredMethod( "hqlBook", EntityManager.class, String.class ); + Assertions.assertNotNull( method ); + Assertions.assertTrue( Modifier.isStatic(method.getModifiers()) ); // Panache native method generates a static method - method = repositoryClass.getDeclaredMethod("findBook", EntityManager.class, String.class); - Assertions.assertNotNull(method); - Assertions.assertTrue(Modifier.isStatic(method.getModifiers())); + method = repositoryClass.getDeclaredMethod( "findBook", EntityManager.class, String.class ); + Assertions.assertNotNull( method ); + Assertions.assertTrue( Modifier.isStatic( method.getModifiers() ) ); + } + + @Test + @WithClasses({ PanacheBook.class, QuarkusBookRepository.class }) + public void testQuarkusRepositoryMetamodel() throws Exception { + // Panache repository + System.out.println( TestUtil.getMetaModelSourceAsString( QuarkusBookRepository.class ) ); + Class repositoryClass = getMetamodelClassFor( QuarkusBookRepository.class ); + Assertions.assertNotNull( repositoryClass ); + + // Make sure it has the proper supertype + Class superclass = repositoryClass.getSuperclass(); + if ( superclass != null ) { + Assertions.assertEquals( "java.lang.Object", superclass.getName() ); + } + Class[] interfaces = repositoryClass.getInterfaces(); + Assertions.assertEquals( 1, interfaces.length ); + Assertions.assertEquals( QuarkusBookRepository.class.getName(), interfaces[0].getName() ); + + // Annotated method generates an instance method + Method method = repositoryClass.getDeclaredMethod( "hqlBook", String.class ); + Assertions.assertNotNull( method ); + Assertions.assertFalse( Modifier.isStatic( method.getModifiers() ) ); + + // Annotated method generates an instance method + method = repositoryClass.getDeclaredMethod( "findBook", String.class ); + Assertions.assertNotNull( method ); + Assertions.assertFalse( Modifier.isStatic( method.getModifiers() ) ); + + // Make sure we have the proper constructor + Constructor constructor = repositoryClass.getDeclaredConstructor( EntityManager.class ); + Assertions.assertNotNull( constructor ); + Assertions.assertTrue( constructor.isAnnotationPresent( Inject.class ) ); } } diff --git a/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/util/CompilationRunner.java b/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/util/CompilationRunner.java index 3a6bc51300..e8a30fa561 100644 --- a/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/util/CompilationRunner.java +++ b/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/util/CompilationRunner.java @@ -61,6 +61,7 @@ public class CompilationRunner extends BlockJUnit4ClassRunner { return new CompilationStatement( statement, + getTestClass().getJavaClass(), testEntities, preCompileEntities, mappingFiles, diff --git a/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/util/CompilationStatement.java b/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/util/CompilationStatement.java index 9d3566ffe5..1bff40b304 100644 --- a/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/util/CompilationStatement.java +++ b/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/util/CompilationStatement.java @@ -37,34 +37,9 @@ public class CompilationStatement extends Statement { private static final Logger log = Logger.getLogger( CompilationStatement.class ); private static final String PACKAGE_SEPARATOR = "."; private static final String ANNOTATION_PROCESSOR_OPTION_PREFIX = "-A"; - private static final String SOURCE_BASE_DIR_PROPERTY = "sourceBaseDir"; - private static final String SOURCE_BASE_DIR; - - static { - // first we try to guess the target directory. - File potentialSourceDirectory = new File(System.getProperty( "user.dir" ), "tooling/metamodel-generator/src/test/java"); - - // the command line build sets the user.dir to sub project directory - if ( !potentialSourceDirectory.exists() ) { - potentialSourceDirectory = new File(System.getProperty( "user.dir" ), "src/test/java"); - } - - if ( potentialSourceDirectory.exists() ) { - SOURCE_BASE_DIR = potentialSourceDirectory.getAbsolutePath(); - } - else { - String tmp = System.getProperty( SOURCE_BASE_DIR_PROPERTY ); - if ( tmp == null ) { - fail( - "Unable to guess determine the source directory. Specify the system property 'sourceBaseDir'" + - " pointing to the base directory of the test java sources." - ); - } - SOURCE_BASE_DIR = tmp; - } - } private final Statement originalStatement; + private final Class testClass; private final List> testEntities; private final List> preCompileEntities; private final List xmlMappingFiles; @@ -73,12 +48,14 @@ public class CompilationStatement extends Statement { private final List> compilationDiagnostics; public CompilationStatement(Statement originalStatement, + Class testClass, List> testEntities, List> proCompileEntities, List xmlMappingFiles, Map processorOptions, boolean ignoreCompilationErrors) { this.originalStatement = originalStatement; + this.testClass = testClass; this.testEntities = testEntities; this.preCompileEntities = proCompileEntities; this.xmlMappingFiles = xmlMappingFiles; @@ -114,7 +91,7 @@ public class CompilationStatement extends Statement { } private String getPathToSource(Class testClass) { - return SOURCE_BASE_DIR + File.separator + testClass.getName() + return TestUtil.getSourceBaseDir( testClass ).getAbsolutePath() + File.separator + testClass.getName() .replace( PACKAGE_SEPARATOR, File.separator ) + ".java"; } @@ -136,7 +113,7 @@ public class CompilationStatement extends Statement { private List createJavaOptions() { List options = new ArrayList(); options.add( "-d" ); - options.add( TestUtil.getOutBaseDir().getAbsolutePath() ); + options.add( TestUtil.getOutBaseDir( testClass ).getAbsolutePath() ); options.add( "-processor" ); options.add( JPAMetaModelEntityProcessor.class.getName() ); diff --git a/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/util/CompilationTest.java b/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/util/CompilationTest.java index a02c8d0e7e..0ef4588dac 100644 --- a/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/util/CompilationTest.java +++ b/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/util/CompilationTest.java @@ -22,7 +22,7 @@ public abstract class CompilationTest { @After public void cleanup() throws Exception { - TestUtil.deleteProcessorGeneratedFiles(); + TestUtil.deleteProcessorGeneratedFiles(getClass()); } } diff --git a/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/util/TestUtil.java b/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/util/TestUtil.java index 9f2f494965..895bb1e15c 100644 --- a/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/util/TestUtil.java +++ b/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/util/TestUtil.java @@ -45,17 +45,6 @@ public class TestUtil { public static final String RESOURCE_SEPARATOR = "/"; private static final String PACKAGE_SEPARATOR = "."; private static final String META_MODEL_CLASS_POSTFIX = "_"; - private static final File OUT_BASE_DIR; - - static { - File targetDir = getTargetDir(); - OUT_BASE_DIR = new File( targetDir, "processor-generated-test-classes" ); - if ( !OUT_BASE_DIR.exists() ) { - if ( !OUT_BASE_DIR.mkdirs() ) { - fail( "Unable to create test output directory " + OUT_BASE_DIR.toString() ); - } - } - } private TestUtil() { } @@ -206,9 +195,10 @@ public class TestUtil { /** * Deletes recursively all files found in the output directory for the annotation processor. + * @return the output directory for the generated source and class files. */ - public static void deleteProcessorGeneratedFiles() { - for ( File file : OUT_BASE_DIR.listFiles() ) { + public static void deleteProcessorGeneratedFiles(Class testClass) { + for ( File file : getOutBaseDir(testClass).listFiles() ) { deleteFilesRecursive( file ); } } @@ -216,8 +206,36 @@ public class TestUtil { /** * @return the output directory for the generated source and class files. */ - public static File getOutBaseDir() { - return OUT_BASE_DIR; + public static File getOutBaseDir(Class testClass) { + File targetDir = getTargetDir( testClass ); + File outBaseDir = new File( targetDir, "processor-generated-test-classes" ); + if ( !outBaseDir.exists() ) { + if ( !outBaseDir.mkdirs() ) { + fail( "Unable to create test output directory " + outBaseDir ); + } + } + return outBaseDir; + } + + public static File getSourceBaseDir(Class testClass) { + ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + String currentTestClassName = testClass.getName(); + int hopsToCompileDirectory = currentTestClassName.split( "\\." ).length; + URL classURL = contextClassLoader.getResource( currentTestClassName.replace( '.', '/' ) + ".class" ); + File targetDir = new File( classURL.getFile() ); + // navigate back to '/target' + for ( int i = 0; i < hopsToCompileDirectory; i++ ) { + targetDir = targetDir.getParentFile(); + } + final String configurationDirectory = targetDir.getName(); + final File baseDir = targetDir.getParentFile().getParentFile().getParentFile().getParentFile(); + final File outBaseDir = new File( baseDir, "src/" + configurationDirectory + "/java" ); + if ( !outBaseDir.exists() ) { + if ( !outBaseDir.mkdirs() ) { + fail( "Unable to create test output directory " + outBaseDir ); + } + } + return outBaseDir; } /** @@ -231,7 +249,7 @@ public class TestUtil { assertNotNull( "Class parameter cannot be null", entityClass ); String metaModelClassName = entityClass.getName() + META_MODEL_CLASS_POSTFIX; try { - URL outDirUrl = OUT_BASE_DIR.toURI().toURL(); + URL outDirUrl = getOutBaseDir( entityClass ).toURI().toURL(); URL[] urls = new URL[1]; urls[0] = outDirUrl; URLClassLoader classLoader = new URLClassLoader( urls, TestUtil.class.getClassLoader() ); @@ -249,7 +267,7 @@ public class TestUtil { // generate the file name String fileName = metaModelClassName.replace( PACKAGE_SEPARATOR, PATH_SEPARATOR ); fileName = fileName.concat( ".java" ); - return new File( OUT_BASE_DIR + PATH_SEPARATOR + fileName ); + return new File( getOutBaseDir( clazz ), fileName ); } public static String getMetaModelSourceAsString(Class clazz) { @@ -390,13 +408,12 @@ public class TestUtil { * * @return the target directory of the build */ - public static File getTargetDir() { + public static File getTargetDir(Class currentTestClass) { ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); - // get a URL reference to something we now is part of the classpath (our own classes) - String currentTestClass = TestUtil.class.getName(); - int hopsToCompileDirectory = currentTestClass.split( "\\." ).length; + String currentTestClassName = currentTestClass.getName(); + int hopsToCompileDirectory = currentTestClassName.split( "\\." ).length; int hopsToTargetDirectory = hopsToCompileDirectory + 2; - URL classURL = contextClassLoader.getResource( currentTestClass.replace( '.', '/' ) + ".class" ); + URL classURL = contextClassLoader.getResource( currentTestClassName.replace( '.', '/' ) + ".class" ); // navigate back to '/target' File targetDir = new File( classURL.getFile() ); // navigate back to '/target'