Skip to content

Commit b61a115

Browse files
committed
HHH-19879: Move Hibernate Tools' reveng module to Hibernate ORM and merge the relevant ant/gradle/maven plugins
- Add the Reverse Engineering module Signed-off-by: Koen Aers <koen.aers@gmail.com>
1 parent cb5263c commit b61a115

File tree

231 files changed

+23814
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

231 files changed

+23814
-0
lines changed

settings.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,9 @@ project(':hibernate-maven-plugin').projectDir = new File(rootProject.projectDir,
359359
include 'hibernate-ant'
360360
project(':hibernate-ant').projectDir = new File(rootProject.projectDir, "tooling/hibernate-ant")
361361

362+
include 'hibernate-reveng'
363+
project(':hibernate-reveng').projectDir = new File(rootProject.projectDir, "tooling/hibernate-reveng")
364+
362365
rootProject.children.each { project ->
363366
project.buildFileName = "${project.name}.gradle"
364367
assert project.projectDir.isDirectory()
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
plugins {
2+
id "local.publishing-java-module"
3+
}
4+
5+
description = "Library providing functionality to perform reverse engineering Hibernate related artefacts from an existing database"
6+
7+
dependencies {
8+
implementation project( ':hibernate-core' )
9+
implementation project( ':hibernate-ant' )
10+
implementation "org.apache.commons:commons-collections4:4.5.0"
11+
implementation "com.google.googlejavaformat:google-java-format:1.27.0"
12+
implementation "org.freemarker:freemarker:2.3.34"
13+
implementation "org.antlr:antlr4-runtime:4.13.2"
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.tool.reveng.api.core;
6+
7+
public interface AssociationInfo {
8+
9+
String getCascade();
10+
String getFetch();
11+
Boolean getUpdate();
12+
Boolean getInsert();
13+
14+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.tool.reveng.api.core;
6+
7+
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
8+
9+
import java.util.Iterator;
10+
import java.util.Map;
11+
12+
/**
13+
* Interface for fetching metadata from databases.
14+
* The dialect is configured with a ConnectionProvider but is not
15+
* required to actually use any connections.
16+
*
17+
* The metadata methods all returns Iterator and allows for more efficient and partial reads
18+
* for those databases that has "flakey" JDBC metadata implementions.
19+
*
20+
* @author Max Rydahl Andersen
21+
*
22+
*/
23+
public interface RevengDialect {
24+
25+
/**
26+
* Configure the metadatadialect.
27+
* @param connectionProvider a {@link ConnectionProvider}
28+
*/
29+
public void configure(ConnectionProvider connectionProvider);
30+
31+
/**
32+
* Return iterator over the tables that mathces catalog, schema and table
33+
*
34+
* @param catalog name or null
35+
* @param schema name or null
36+
* @param table name or null
37+
* @return iterator with map elements that has "TABLE_NAME", "TABLE_SCHEMA", "TABLE_CAT", "TABLE_TYPE" keys.
38+
*/
39+
Iterator<Map<String,Object>> getTables(String catalog, String schema, String table);
40+
41+
/**
42+
* Close the iterator.
43+
* @param iterator an iterator returned from one of methods on this dialect
44+
*/
45+
void close(Iterator<?> iterator);
46+
47+
/**
48+
* Return iterator over the indexes that mathces catalog, schema and table
49+
*
50+
* @param catalog name or null
51+
* @param schema name or null
52+
* @param table name or null
53+
* @return iterator with map elements that has "TABLE_NAME", "TABLE_SCHEMA", "TABLE_CAT", "INDEX_NAME", "COLUMN_NAME", "NON_UNIQUE", "TYPE" keys.
54+
*/
55+
Iterator<Map<String, Object>> getIndexInfo(String catalog, String schema, String table);
56+
57+
/**
58+
* Return iterator over the columns that mathces catalog, schema and table
59+
*
60+
* @param catalog name or null
61+
* @param schema name or null
62+
* @param table name or null
63+
* @param column name or null
64+
* @return iterator with map elements that has "TABLE_NAME", "TABLE_SCHEMA", "TABLE_CAT", "DATA_TYPE", "TYPE_NAME", "COLUMN_NAME", "NULLABLE", "COLUMN_SIZE", "DECIMAL_DIGITS"
65+
*/
66+
Iterator<Map<String, Object>> getColumns(String catalog, String schema, String table, String column);
67+
68+
/**
69+
* Return iterator over the columns that mathces catalog, schema and table
70+
*
71+
* @param catalog name or null
72+
* @param schema name or null
73+
* @param table name or null
74+
* @return iterator with map elements that has "TABLE_NAME", "TABLE_SCHEMA", "TABLE_CAT", "COLUMN_NAME", "KEY_SEQ", "PK_NAME",
75+
*/
76+
Iterator<Map<String, Object>> getPrimaryKeys(String catalog, String schema, String name);
77+
78+
79+
/**
80+
* Return iterator over the exported foreign keys that mathces catalog, schema and table
81+
*
82+
* @param catalog name or null
83+
* @param schema name or null
84+
* @param table name or null
85+
* @return iterator with map elements that has "TABLE_NAME", "TABLE_SCHEMA", "TABLE_CAT", "FKTABLE_CAT", "FKTABLE_SCHEM", "FKTABLE_NAME", "FK_NAME", "KEY_SEQ"
86+
*/
87+
Iterator<Map<String, Object>> getExportedKeys(String catalog, String schema, String table);
88+
89+
/**
90+
* Does this name need quoting
91+
*
92+
* @param name
93+
* @return
94+
*/
95+
boolean needQuote(String name);
96+
97+
/**
98+
* Close any resources this dialect might have used.
99+
*/
100+
void close();
101+
102+
/**
103+
* Use database (possible native) metadata to suggest identifier strategy.
104+
*
105+
* @param catalog
106+
* @param schema
107+
* @param name
108+
* @return iterator with map elements that has "TABLE_NAME", "TABLE_SCHEMA", "TABLE_CAT", "HIBERNATE_STRATEGY" (null if no possible to determine strategy, otherwise return hibernate identifier strategy name/classname)
109+
*/
110+
public Iterator<Map<String, Object>> getSuggestedPrimaryKeyStrategyName(String catalog, String schema, String table);
111+
112+
113+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.tool.reveng.api.core;
6+
7+
import org.hibernate.dialect.Dialect;
8+
import org.hibernate.dialect.H2Dialect;
9+
import org.hibernate.dialect.HSQLDialect;
10+
import org.hibernate.dialect.MySQLDialect;
11+
import org.hibernate.dialect.OracleDialect;
12+
import org.hibernate.dialect.SQLServerDialect;
13+
import org.hibernate.internal.util.ReflectHelper;
14+
import org.hibernate.tool.reveng.internal.core.dialect.H2MetaDataDialect;
15+
import org.hibernate.tool.reveng.internal.core.dialect.HSQLMetaDataDialect;
16+
import org.hibernate.tool.reveng.internal.core.dialect.JDBCMetaDataDialect;
17+
import org.hibernate.tool.reveng.internal.core.dialect.MySQLMetaDataDialect;
18+
import org.hibernate.tool.reveng.internal.core.dialect.OracleMetaDataDialect;
19+
import org.hibernate.tool.reveng.internal.core.dialect.SQLServerMetaDataDialect;
20+
21+
import java.lang.reflect.Constructor;
22+
import java.util.Properties;
23+
24+
public class RevengDialectFactory {
25+
26+
private RevengDialectFactory() {}
27+
28+
public static RevengDialect createMetaDataDialect(Dialect dialect, Properties cfg) {
29+
String property = cfg.getProperty( "hibernatetool.metadatadialect" );
30+
RevengDialect mdd = fromClassName(property);
31+
if(mdd==null) {
32+
mdd = fromDialect(dialect);
33+
}
34+
if(mdd==null) {
35+
mdd = fromDialectName(dialect.getClass().getName());
36+
}
37+
if(mdd==null) {
38+
mdd = new JDBCMetaDataDialect();
39+
}
40+
return mdd;
41+
}
42+
43+
public static RevengDialect fromClassName(String property) {
44+
if ( property != null ) {
45+
try {
46+
Class<?> revengDialectClass = ReflectHelper.classForName(
47+
property,
48+
RevengDialectFactory.class );
49+
Constructor<?> revengDialectConstructor = revengDialectClass.getConstructor();
50+
return (RevengDialect)revengDialectConstructor.newInstance();
51+
}
52+
catch (Throwable e) {
53+
throw new RuntimeException(
54+
"Could not load MetaDataDialect: " + property, e );
55+
}
56+
}
57+
else {
58+
return null;
59+
}
60+
}
61+
62+
public static RevengDialect fromDialect(Dialect dialect) {
63+
if(dialect!=null) {
64+
if(dialect instanceof OracleDialect) {
65+
return new OracleMetaDataDialect();
66+
}
67+
else if (dialect instanceof H2Dialect) {
68+
return new H2MetaDataDialect();
69+
}
70+
else if (dialect instanceof MySQLDialect) {
71+
return new MySQLMetaDataDialect();
72+
}
73+
else if (dialect instanceof HSQLDialect) {
74+
return new HSQLMetaDataDialect();
75+
}
76+
else if (dialect instanceof SQLServerDialect) {
77+
return new SQLServerMetaDataDialect();
78+
}
79+
}
80+
return null;
81+
}
82+
83+
public static RevengDialect fromDialectName(String dialect) {
84+
if (dialect.toLowerCase().contains("oracle")) {
85+
return new OracleMetaDataDialect();
86+
}
87+
if (dialect.toLowerCase().contains("mysql")) {
88+
return new MySQLMetaDataDialect();
89+
}
90+
if (dialect.toLowerCase().contains("h2")) {
91+
return new H2MetaDataDialect();
92+
}
93+
if (dialect.toLowerCase().contains("hsql")) {
94+
return new HSQLMetaDataDialect();
95+
}
96+
if (dialect.toLowerCase().contains("sqlserver")) {
97+
return new SQLServerMetaDataDialect();
98+
}
99+
return null;
100+
}
101+
102+
103+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.tool.reveng.api.core;
6+
7+
public class RevengSettings {
8+
9+
10+
final RevengStrategy rootStrategy;
11+
12+
private String defaultPackageName = "";
13+
private boolean detectOptimisticLock = true;
14+
private boolean createCollectionForForeignKey = true;
15+
private boolean createManyToOneForForeignKey = true;
16+
private boolean detectManyToMany = true;
17+
private boolean detectOneToOne = true;
18+
19+
20+
public RevengSettings(RevengStrategy rootStrategy) {
21+
this.rootStrategy = rootStrategy;
22+
}
23+
24+
public RevengSettings setDefaultPackageName(String defaultPackageName) {
25+
if(defaultPackageName==null) {
26+
this.defaultPackageName = "";
27+
}
28+
else {
29+
this.defaultPackageName= defaultPackageName.trim();
30+
}
31+
return this;
32+
}
33+
34+
/** return the default packageName. Never null, at least the empty string */
35+
public String getDefaultPackageName() {
36+
return defaultPackageName;
37+
}
38+
39+
/** If true, reverse engineering strategy will try and autodetect columns for optimistc locking, e.g. VERSION and TIMESTAMP */
40+
public boolean getDetectOptimsticLock() {
41+
return detectOptimisticLock ;
42+
}
43+
44+
public RevengSettings setDetectOptimisticLock(
45+
boolean optimisticLockSupportEnabled) {
46+
this.detectOptimisticLock = optimisticLockSupportEnabled;
47+
return this;
48+
}
49+
50+
/** if true, a collection will be mapped for each foreignkey */
51+
public boolean createCollectionForForeignKey() {
52+
return createCollectionForForeignKey;
53+
}
54+
55+
56+
public RevengSettings setCreateCollectionForForeignKey(
57+
boolean createCollectionForForeignKey) {
58+
this.createCollectionForForeignKey = createCollectionForForeignKey;
59+
return this;
60+
}
61+
62+
/** if true, a many-to-one association will be created for each foreignkey found */
63+
public boolean createManyToOneForForeignKey() {
64+
return createManyToOneForForeignKey;
65+
}
66+
67+
public RevengSettings setCreateManyToOneForForeignKey(
68+
boolean createManyToOneForForeignKey) {
69+
this.createManyToOneForForeignKey = createManyToOneForForeignKey;
70+
return this;
71+
}
72+
73+
public RevengSettings setDetectManyToMany(boolean b) {
74+
this.detectManyToMany = b;
75+
return this;
76+
}
77+
78+
public boolean getDetectManyToMany() {
79+
return detectManyToMany;
80+
}
81+
82+
public RevengSettings setDetectOneToOne(boolean b) {
83+
this.detectOneToOne = b;
84+
return this;
85+
}
86+
87+
public boolean getDetectOneToOne() {
88+
return detectOneToOne;
89+
}
90+
91+
/** return the top/root strategy. Allows a lower strategy to ask another question. Be aware of possible recursive loops; e.g. do not call the root.tableToClassName in tableToClassName of a custom reversengineeringstrategy. */
92+
public RevengStrategy getRootStrategy() {
93+
return rootStrategy;
94+
}
95+
96+
97+
98+
}

0 commit comments

Comments
 (0)