Skip to content

Commit 30f9d6a

Browse files
committed
HSEARCH-3319 WIP: maven plugin to generate "metamodel classes" while compiling in the same module ...
1 parent 75911f7 commit 30f9d6a

File tree

4 files changed

+122
-11
lines changed

4 files changed

+122
-11
lines changed

Diff for: metamodel/generator-plugin/pom.xml

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
<deploy.skip>false</deploy.skip>
1919
<enforcer.dependencyconvergence.skip>true</enforcer.dependencyconvergence.skip>
2020
<java.module.name>org.hibernate.search.metamodel.generator.plugin</java.module.name>
21+
<forbiddenapis.skip>true</forbiddenapis.skip>
22+
<checkstyle.skip>true</checkstyle.skip>
2123
</properties>
2224

2325
<dependencies>

Diff for: metamodel/generator-plugin/src/main/java/org/hibernate/search/metamodel/generator/plugin/HibernateSearchMetamodelGeneratorMojo.java

+91-10
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,28 @@
66
*/
77
package org.hibernate.search.metamodel.generator.plugin;
88

9+
import java.io.File;
910
import java.io.FileOutputStream;
1011
import java.io.IOException;
12+
import java.net.URL;
13+
import java.net.URLClassLoader;
1114
import java.nio.charset.StandardCharsets;
15+
import java.nio.file.FileSystems;
1216
import java.nio.file.Files;
1317
import java.nio.file.Path;
18+
import java.util.ArrayList;
1419
import java.util.Collection;
1520
import java.util.List;
1621
import java.util.Objects;
1722
import java.util.Properties;
23+
import java.util.stream.Collectors;
24+
25+
import javax.tools.DiagnosticCollector;
26+
import javax.tools.JavaCompiler;
27+
import javax.tools.JavaFileObject;
28+
import javax.tools.StandardJavaFileManager;
29+
import javax.tools.StandardLocation;
30+
import javax.tools.ToolProvider;
1831

1932
import org.hibernate.SessionFactory;
2033
import org.hibernate.search.engine.backend.metamodel.IndexDescriptor;
@@ -25,6 +38,7 @@
2538
import org.hibernate.search.util.impl.integrationtest.backend.lucene.LuceneBackendConfiguration;
2639
import org.hibernate.search.util.impl.integrationtest.mapper.orm.OrmSetupHelper;
2740

41+
import org.apache.maven.artifact.Artifact;
2842
import org.apache.maven.model.Dependency;
2943
import org.apache.maven.plugin.AbstractMojo;
3044
import org.apache.maven.plugin.MojoExecutionException;
@@ -43,9 +57,17 @@ public class HibernateSearchMetamodelGeneratorMojo extends AbstractMojo {
4357
@Parameter(property = "annotatedTypes")
4458
List<String> annotatedTypes;
4559

60+
@Parameter(property = "packagesToCompile")
61+
List<String> packagesToCompile;
62+
4663
@Parameter(property = "properties")
4764
Properties properties;
4865

66+
@Parameter(property = "sameModuleCompile", defaultValue = "false")
67+
boolean sameModuleCompile;
68+
69+
private URLClassLoader classLoader;
70+
4971
@Override
5072
public void execute() throws MojoExecutionException, MojoFailureException {
5173
getLog().info( "Hibernate Search Metamodel Generator" );
@@ -60,8 +82,6 @@ public void execute() throws MojoExecutionException, MojoFailureException {
6082

6183
Path generatedMetamodelLocation =
6284
Path.of( project.getBuild().getOutputDirectory() ).resolveSibling( "generated-metamodel-sources" );
63-
project.addCompileSourceRoot( generatedMetamodelLocation.toString() );
64-
6585

6686
try ( SessionFactory sessionFactory = setupContext.setup( annotatedTypes() ) ) {
6787
SearchMapping mapping = Search.mapping( sessionFactory );
@@ -75,7 +95,7 @@ public void execute() throws MojoExecutionException, MojoFailureException {
7595
getLog().info( "Indexed entities: " + indexedEntities );
7696

7797
}
78-
98+
project.addCompileSourceRoot( generatedMetamodelLocation.toString() );
7999
}
80100
}
81101

@@ -112,18 +132,79 @@ private void createClass(SearchIndexedEntity<?> indexedEntity, Path root) {
112132
}
113133

114134
private Class<?>[] annotatedTypes() {
115-
try {
116-
Class<?>[] types = new Class<?>[annotatedTypes.size()];
117-
for ( int i = 0; i < annotatedTypes.size(); i++ ) {
118-
types[i] = Class.forName( annotatedTypes.get( i ) );
135+
if ( sameModuleCompile ) {
136+
try {
137+
List<Path> roots = new ArrayList<>();
138+
List<Path> classes = new ArrayList<>();
139+
for ( String compileSourceRoot : this.project.getCompileSourceRoots() ) {
140+
Path root = Path.of( compileSourceRoot );
141+
roots.add( root );
142+
143+
for ( String pkg : packagesToCompile ) {
144+
Path path = root.resolve( Path.of( pkg.replace( ".", FileSystems.getDefault().getSeparator() ) ) );
145+
if ( Files.exists( path ) ) {
146+
Files.list( path ).filter( f -> f.getFileName().toString().endsWith( ".java" ) )
147+
.forEach( classes::add );
148+
}
149+
}
150+
}
151+
152+
Path output = Path.of( project.getBuild().getOutputDirectory() )
153+
.resolveSibling( "generated-metamodel-pre-compiled-classes" );
154+
Files.createDirectories( output );
155+
156+
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
157+
StandardJavaFileManager fileManager = compiler.getStandardFileManager( null, null, null );
158+
fileManager.setLocationFromPaths( StandardLocation.SOURCE_PATH, roots );
159+
fileManager.setLocation( StandardLocation.CLASS_PATH, getDependenciesAsFiles() );
160+
fileManager.setLocationFromPaths( StandardLocation.CLASS_OUTPUT, List.of( output ) );
161+
162+
Iterable<? extends JavaFileObject> toCompile = fileManager.getJavaFileObjectsFromPaths( classes );
163+
164+
DiagnosticCollector<JavaFileObject> diagnostic = new DiagnosticCollector<>();
165+
JavaCompiler.CompilationTask task =
166+
compiler.getTask( null, fileManager, diagnostic, List.of(), null, toCompile );
167+
168+
task.call();
169+
170+
classLoader = new URLClassLoader( "hibernate-search-generator",
171+
new URL[] { output.toUri().toURL() }, this.getClass().getClassLoader() );
172+
Thread.currentThread().setContextClassLoader( classLoader );
173+
174+
Class<?>[] types = new Class<?>[annotatedTypes.size()];
175+
for ( int i = 0; i < annotatedTypes.size(); i++ ) {
176+
types[i] = classLoader.loadClass( annotatedTypes.get( i ) );
177+
}
178+
return types;
179+
180+
}
181+
catch (IOException | ClassNotFoundException e) {
182+
throw new RuntimeException( e );
119183
}
120-
return types;
121184
}
122-
catch (ClassNotFoundException e) {
123-
throw new RuntimeException( e );
185+
else {
186+
try {
187+
Class<?>[] types = new Class<?>[annotatedTypes.size()];
188+
for ( int i = 0; i < annotatedTypes.size(); i++ ) {
189+
types[i] = Class.forName( annotatedTypes.get( i ) );
190+
}
191+
return types;
192+
}
193+
catch (ClassNotFoundException e) {
194+
throw new RuntimeException( e );
195+
}
124196
}
125197
}
126198

199+
private Collection<File> getDependenciesAsFiles() {
200+
project.setArtifactFilter( artifact -> true );
201+
project.setArtifacts( null );
202+
return project.getArtifacts()
203+
.stream()
204+
.map( Artifact::getFile )
205+
.collect( Collectors.toList() );
206+
}
207+
127208
private boolean hasOrmMapper(List<Dependency> dependencies) {
128209
for ( Dependency dependency : dependencies ) {
129210
if ( "hibernate-search-mapper-orm".equals( dependency.getArtifactId() ) ) {

Diff for: metamodel/generator-test/generation/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<!-- This is a publicly distributed module that should be published: -->
1616
<deploy.skip>false</deploy.skip>
1717
<java.module.name>org.hibernate.search.metamodel.generator.test</java.module.name>
18-
<org.hibernate.search.integrationtest.orm.database.kind>h2</org.hibernate.search.integrationtest.orm.database.kind>
18+
<checkstyle.skip>true</checkstyle.skip>
1919
</properties>
2020

2121
<dependencies>

Diff for: metamodel/generator-test/model/pom.xml

+28
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<!-- This is a publicly distributed module that should be published: -->
1616
<deploy.skip>false</deploy.skip>
1717
<java.module.name>org.hibernate.search.metamodel.generator</java.module.name>
18+
<checkstyle.skip>true</checkstyle.skip>
1819
</properties>
1920

2021
<dependencies>
@@ -65,6 +66,33 @@
6566
</execution>
6667
</executions>
6768
</plugin>
69+
<plugin>
70+
<groupId>org.hibernate.search</groupId>
71+
<artifactId>hibernate-search-metamodel-generator-plugin</artifactId>
72+
<version>${project.version}</version>
73+
<executions>
74+
<execution>
75+
<id>generate</id>
76+
<goals>
77+
<goal>generate-metamodel</goal>
78+
</goals>
79+
<phase>generate-sources</phase>
80+
<configuration>
81+
<sameModuleCompile>true</sameModuleCompile>
82+
<annotatedTypes>
83+
<type>org.hibernate.search.metamodel.generator.model.MyEntity</type>
84+
<type>org.hibernate.search.metamodel.generator.model.MyProgrammaticEntity</type>
85+
</annotatedTypes>
86+
<packagesToCompile>
87+
<package>org.hibernate.search.metamodel.generator.model</package>
88+
</packagesToCompile>
89+
<properties>
90+
<hibernate.search.mapping.configurer>org.hibernate.search.metamodel.generator.model.MyConfigurer</hibernate.search.mapping.configurer>
91+
</properties>
92+
</configuration>
93+
</execution>
94+
</executions>
95+
</plugin>
6896
</plugins>
6997
</build>
7098
</project>

0 commit comments

Comments
 (0)