Skip to content

Commit 094c21a

Browse files
committed
Merge Hibernate Tools into ORM : Add the Reveng Gradle tasks
Signed-off-by: Koen Aers <koen.aers@gmail.com>
1 parent f86b89b commit 094c21a

File tree

9 files changed

+455
-0
lines changed

9 files changed

+455
-0
lines changed

tooling/hibernate-gradle-plugin/hibernate-gradle-plugin.gradle

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ description = "Gradle plugin for integrating Hibernate aspects into your build"
2020

2121
dependencies {
2222
implementation project(':hibernate-core')
23+
implementation project(':hibernate-reveng')
2324
implementation libs.byteBuddy
2425
implementation jakartaLibs.jaxbApi
2526

@@ -50,6 +51,13 @@ gradlePlugin {
5051
description = 'Applies Hibernate aspects into the build'
5152
tags = ['hibernate','orm','bytecode','enhancement','bytebuddy']
5253
}
54+
hibernate {
55+
id = 'org.hibernate.tool.hibernate-tools-gradle'
56+
implementationClass = 'org.hibernate.tool.gradle.Plugin'
57+
displayName = 'Hibernate Tools Gradle Plugin'
58+
description = project.description
59+
tags = ['hibernate','tools','reverse engineering','reveng','generation']
60+
}
5361
}
5462
}
5563

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.tool.gradle;
6+
7+
import org.gradle.api.Project;
8+
9+
public class Extension {
10+
11+
public String sqlToRun = "";
12+
public String hibernateProperties = "hibernate.properties";
13+
public String outputFolder = "generated-sources";
14+
public String packageName = "";
15+
public String revengStrategy = null;
16+
public String revengFile = null;
17+
public Boolean generateAnnotations = true;
18+
public Boolean useGenerics = true;
19+
public String templatePath = null;
20+
21+
public Extension(Project project) {}
22+
23+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.tool.gradle;
6+
7+
import java.util.Map;
8+
9+
import org.gradle.api.Project;
10+
import org.hibernate.tool.gradle.task.AbstractTask;
11+
import org.hibernate.tool.gradle.task.GenerateCfgTask;
12+
import org.hibernate.tool.gradle.task.GenerateDaoTask;
13+
import org.hibernate.tool.gradle.task.GenerateHbmTask;
14+
import org.hibernate.tool.gradle.task.GenerateJavaTask;
15+
import org.hibernate.tool.gradle.task.RunSqlTask;
16+
17+
public class Plugin implements org.gradle.api.Plugin<Project> {
18+
19+
private static Map<String, Class<?>> PLUGIN_TASK_MAP = Map.of(
20+
"runSql", RunSqlTask.class,
21+
"generateJava", GenerateJavaTask.class,
22+
"generateCfg", GenerateCfgTask.class,
23+
"generateHbm", GenerateHbmTask.class,
24+
"generateDao", GenerateDaoTask.class
25+
);
26+
27+
@SuppressWarnings("unchecked")
28+
public void apply(Project project) {
29+
Extension extension = project.getExtensions().create("hibernateTools", Extension.class, project);
30+
for (String key : PLUGIN_TASK_MAP.keySet()) {
31+
Class<?> taskClass = PLUGIN_TASK_MAP.get(key);
32+
project.getTasks().register(key, (Class<AbstractTask>)taskClass);
33+
AbstractTask task = (AbstractTask)project.getTasks().getByName(key);
34+
task.doFirst(w -> task.initialize(extension));
35+
}
36+
}
37+
38+
}
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.tool.gradle.task;
6+
7+
import java.io.File;
8+
import java.io.FileInputStream;
9+
import java.io.FileNotFoundException;
10+
import java.io.IOException;
11+
import java.net.MalformedURLException;
12+
import java.net.URL;
13+
import java.net.URLClassLoader;
14+
import java.util.Properties;
15+
import java.util.Set;
16+
17+
import org.apache.tools.ant.BuildException;
18+
import org.gradle.api.DefaultTask;
19+
import org.gradle.api.artifacts.Configuration;
20+
import org.gradle.api.artifacts.ConfigurationContainer;
21+
import org.gradle.api.artifacts.ResolvedArtifact;
22+
import org.gradle.api.artifacts.ResolvedConfiguration;
23+
import org.gradle.api.file.SourceDirectorySet;
24+
import org.gradle.api.tasks.Internal;
25+
import org.gradle.api.tasks.SourceSet;
26+
import org.gradle.api.tasks.SourceSetContainer;
27+
import org.hibernate.tool.reveng.api.metadata.MetadataConstants;
28+
import org.hibernate.tool.reveng.api.metadata.MetadataDescriptor;
29+
import org.hibernate.tool.reveng.api.metadata.MetadataDescriptorFactory;
30+
import org.hibernate.tool.reveng.api.core.RevengSettings;
31+
import org.hibernate.tool.reveng.api.core.RevengStrategy;
32+
import org.hibernate.tool.reveng.api.core.RevengStrategyFactory;
33+
import org.hibernate.tool.gradle.Extension;
34+
35+
public abstract class AbstractTask extends DefaultTask {
36+
37+
@Internal
38+
private Extension extension = null;
39+
40+
@Internal
41+
private Properties hibernateProperties = null;
42+
43+
public void initialize(Extension extension) {
44+
this.extension = extension;
45+
}
46+
47+
Extension getExtension() {
48+
return this.extension;
49+
}
50+
51+
void perform() {
52+
getLogger().lifecycle("Starting Task '" + getName() + "'");
53+
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
54+
try {
55+
Thread.currentThread().setContextClassLoader(
56+
new URLClassLoader(
57+
resolveProjectClassPath(),
58+
oldLoader));
59+
doWork();
60+
}
61+
finally {
62+
Thread.currentThread().setContextClassLoader(oldLoader);
63+
getLogger().lifecycle("Ending Task '" + getName() + "'");
64+
}
65+
}
66+
67+
URL[] resolveProjectClassPath() {
68+
try {
69+
ConfigurationContainer cc = getProject().getConfigurations();
70+
Configuration defaultConf = cc.getByName("compileClasspath");
71+
ResolvedConfiguration resolvedConf = defaultConf.getResolvedConfiguration();
72+
Set<ResolvedArtifact> ras = resolvedConf.getResolvedArtifacts();
73+
ResolvedArtifact[] resolvedArtifacts = ras.toArray(new ResolvedArtifact[ras.size()]);
74+
URL[] urls = new URL[ras.size()];
75+
for (int i = 0; i < ras.size(); i++) {
76+
urls[i] = resolvedArtifacts[i].getFile().toURI().toURL();
77+
}
78+
return urls;
79+
}
80+
catch (MalformedURLException e) {
81+
getLogger().error("MalformedURLException while compiling project classpath");
82+
throw new BuildException(e);
83+
}
84+
}
85+
86+
Properties getHibernateProperties() {
87+
if (hibernateProperties == null) {
88+
loadPropertiesFile(getPropertyFile());
89+
}
90+
return hibernateProperties;
91+
}
92+
93+
String getHibernateProperty(String name) {
94+
return getHibernateProperties().getProperty(name);
95+
}
96+
97+
MetadataDescriptor createJdbcDescriptor() {
98+
RevengStrategy strategy = setupReverseEngineeringStrategy();
99+
Properties hibernateProperties = getHibernateProperties();
100+
hibernateProperties.put(MetadataConstants.PREFER_BASIC_COMPOSITE_IDS, true);
101+
return MetadataDescriptorFactory.createReverseEngineeringDescriptor(strategy, hibernateProperties);
102+
}
103+
104+
@Internal
105+
File getOutputFolder() {
106+
return new File(getProject().getProjectDir(), getExtension().outputFolder);
107+
}
108+
109+
RevengStrategy setupReverseEngineeringStrategy() {
110+
File[] revengFiles = getRevengFiles();
111+
RevengStrategy result = RevengStrategyFactory
112+
.createReverseEngineeringStrategy(getExtension().revengStrategy, revengFiles);
113+
RevengSettings settings = new RevengSettings(result);
114+
settings.setDefaultPackageName(getExtension().packageName);
115+
result.setSettings(settings);
116+
return result;
117+
}
118+
119+
private File getFile(String filename) {
120+
SourceSetContainer ssc = getProject().getExtensions().getByType(SourceSetContainer.class);
121+
SourceSet ss = ssc.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
122+
SourceDirectorySet sds = ss.getResources();
123+
for (File f : sds.getFiles()) {
124+
if (filename.equals(f.getName())) {
125+
return f;
126+
}
127+
}
128+
throw new BuildException("File '" + filename + "' could not be found");
129+
}
130+
131+
private File getPropertyFile() {
132+
return getFile(getExtension().hibernateProperties);
133+
}
134+
135+
private File[] getRevengFiles() {
136+
String revengFile = getExtension().revengFile;
137+
if (revengFile == null) {
138+
return null;
139+
}
140+
141+
return new File[] { getFile(revengFile) };
142+
}
143+
144+
private void loadPropertiesFile(File propertyFile) {
145+
getLogger().lifecycle("Loading the properties file : " + propertyFile.getPath());
146+
try (FileInputStream is = new FileInputStream(propertyFile)) {
147+
hibernateProperties = new Properties();
148+
hibernateProperties.load(is);
149+
getLogger().lifecycle("Properties file is loaded");
150+
}
151+
catch (FileNotFoundException e) {
152+
throw new BuildException(propertyFile + " not found.", e);
153+
}
154+
catch (IOException e) {
155+
throw new BuildException("Problem while loading " + propertyFile, e);
156+
}
157+
}
158+
159+
abstract void doWork();
160+
161+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.tool.gradle.task;
6+
7+
import java.io.File;
8+
9+
import org.gradle.api.tasks.TaskAction;
10+
import org.hibernate.tool.reveng.api.export.Exporter;
11+
import org.hibernate.tool.reveng.api.export.ExporterConstants;
12+
import org.hibernate.tool.reveng.api.export.ExporterFactory;
13+
import org.hibernate.tool.reveng.api.export.ExporterType;
14+
15+
public class GenerateCfgTask extends AbstractTask {
16+
17+
@TaskAction
18+
public void performTask() {
19+
super.perform();
20+
}
21+
22+
void doWork() {
23+
getLogger().lifecycle("Creating CFG exporter");
24+
Exporter cfgExporter = ExporterFactory.createExporter(ExporterType.CFG);
25+
File outputFolder = getOutputFolder();
26+
cfgExporter.getProperties().put(ExporterConstants.METADATA_DESCRIPTOR, createJdbcDescriptor());
27+
cfgExporter.getProperties().put(ExporterConstants.DESTINATION_FOLDER, outputFolder);
28+
getLogger().lifecycle("Starting CFG export to directory: " + outputFolder + "...");
29+
cfgExporter.start();
30+
getLogger().lifecycle("CFG export finished");
31+
}
32+
33+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.tool.gradle.task;
6+
7+
import java.io.File;
8+
9+
import org.gradle.api.tasks.TaskAction;
10+
import org.hibernate.tool.reveng.api.export.Exporter;
11+
import org.hibernate.tool.reveng.api.export.ExporterConstants;
12+
import org.hibernate.tool.reveng.api.export.ExporterFactory;
13+
import org.hibernate.tool.reveng.api.export.ExporterType;
14+
15+
public class GenerateDaoTask extends AbstractTask {
16+
17+
@TaskAction
18+
public void performTask() {
19+
super.perform();
20+
}
21+
22+
void doWork() {
23+
getLogger().lifecycle("Creating DAO exporter");
24+
Exporter hbmExporter = ExporterFactory.createExporter(ExporterType.DAO);
25+
File outputFolder = getOutputFolder();
26+
hbmExporter.getProperties().put(ExporterConstants.METADATA_DESCRIPTOR, createJdbcDescriptor());
27+
hbmExporter.getProperties().put(ExporterConstants.DESTINATION_FOLDER, outputFolder);
28+
String templatePath = getExtension().templatePath;
29+
if (templatePath != null) {
30+
getLogger().lifecycle("Setting template path to: " + templatePath);
31+
hbmExporter.getProperties().put(ExporterConstants.TEMPLATE_PATH, new String[] { templatePath });
32+
}
33+
getLogger().lifecycle("Starting DAO export to directory: " + outputFolder + "...");
34+
hbmExporter.start();
35+
getLogger().lifecycle("DAO export finished");
36+
}
37+
38+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.tool.gradle.task;
6+
7+
import java.io.File;
8+
9+
import org.gradle.api.tasks.TaskAction;
10+
import org.hibernate.tool.reveng.api.export.Exporter;
11+
import org.hibernate.tool.reveng.api.export.ExporterConstants;
12+
import org.hibernate.tool.reveng.api.export.ExporterFactory;
13+
import org.hibernate.tool.reveng.api.export.ExporterType;
14+
15+
public class GenerateHbmTask extends AbstractTask {
16+
17+
@TaskAction
18+
public void performTask() {
19+
super.perform();
20+
}
21+
22+
void doWork() {
23+
getLogger().lifecycle("Creating HBM exporter");
24+
Exporter hbmExporter = ExporterFactory.createExporter(ExporterType.HBM);
25+
File outputFolder = getOutputFolder();
26+
hbmExporter.getProperties().put(ExporterConstants.METADATA_DESCRIPTOR, createJdbcDescriptor());
27+
hbmExporter.getProperties().put(ExporterConstants.DESTINATION_FOLDER, outputFolder);
28+
String templatePath = getExtension().templatePath;
29+
if (templatePath != null) {
30+
getLogger().lifecycle("Setting template path to: " + templatePath);
31+
hbmExporter.getProperties().put(ExporterConstants.TEMPLATE_PATH, new String[] { templatePath });
32+
}
33+
getLogger().lifecycle("Starting HBM export to directory: " + outputFolder + "...");
34+
hbmExporter.start();
35+
getLogger().lifecycle("HBM export finished");
36+
}
37+
38+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.tool.gradle.task;
6+
7+
import java.io.File;
8+
9+
import org.gradle.api.tasks.TaskAction;
10+
import org.hibernate.tool.reveng.api.export.Exporter;
11+
import org.hibernate.tool.reveng.api.export.ExporterConstants;
12+
import org.hibernate.tool.reveng.api.export.ExporterFactory;
13+
import org.hibernate.tool.reveng.api.export.ExporterType;
14+
15+
public class GenerateJavaTask extends AbstractTask {
16+
17+
@TaskAction
18+
public void performTask() {
19+
super.perform();
20+
}
21+
22+
void doWork() {
23+
getLogger().lifecycle("Creating Java exporter");
24+
Exporter pojoExporter = ExporterFactory.createExporter(ExporterType.JAVA);
25+
pojoExporter.getProperties().setProperty("ejb3", String.valueOf(getExtension().generateAnnotations));
26+
pojoExporter.getProperties().setProperty("jdk5", String.valueOf(getExtension().useGenerics));
27+
File outputFolder = getOutputFolder();
28+
pojoExporter.getProperties().put(ExporterConstants.METADATA_DESCRIPTOR, createJdbcDescriptor());
29+
pojoExporter.getProperties().put(ExporterConstants.DESTINATION_FOLDER, outputFolder);
30+
String templatePath = getExtension().templatePath;
31+
if (templatePath != null) {
32+
getLogger().lifecycle("Setting template path to: " + templatePath);
33+
pojoExporter.getProperties().put(ExporterConstants.TEMPLATE_PATH, new String[] { templatePath });
34+
}
35+
getLogger().lifecycle("Starting Java export to directory: " + outputFolder + "...");
36+
pojoExporter.start();
37+
getLogger().lifecycle("Java export finished");
38+
}
39+
40+
}

0 commit comments

Comments
 (0)