Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,9 @@ project(':hibernate-maven-plugin').projectDir = new File(rootProject.projectDir,
include 'hibernate-ant'
project(':hibernate-ant').projectDir = new File(rootProject.projectDir, "tooling/hibernate-ant")

include 'hibernate-reveng'
project(':hibernate-reveng').projectDir = new File(rootProject.projectDir, "tooling/hibernate-reveng")

rootProject.children.each { project ->
project.buildFileName = "${project.name}.gradle"
assert project.projectDir.isDirectory()
Expand Down
14 changes: 14 additions & 0 deletions tooling/hibernate-reveng/hibernate-reveng.gradle
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honest question: would this make sense to use in an application/framework as a library, and if so do we want to keep this module under tooling/?

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
plugins {
id "local.java-module"
}

description = "Library providing functionality to perform reverse engineering Hibernate related artefacts from an existing database"

dependencies {
implementation project( ':hibernate-core' )
implementation project( ':hibernate-ant' )
implementation "org.apache.commons:commons-collections4:4.5.0"
implementation "com.google.googlejavaformat:google-java-format:1.27.0"
implementation "org.freemarker:freemarker:2.3.34"
implementation "org.antlr:antlr4-runtime:4.13.2"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Hibernate Tools, Tooling for your Hibernate Projects
*
* Copyright 2010-2025 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hibernate.tool.reveng.api.core;

public interface AssociationInfo {

String getCascade();
String getFetch();
Boolean getUpdate();
Boolean getInsert();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* Hibernate Tools, Tooling for your Hibernate Projects
*
* Copyright 2010-2025 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hibernate.tool.reveng.api.core;

import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;

import java.util.Iterator;
import java.util.Map;

/**
* Interface for fetching metadata from databases.
* The dialect is configured with a ConnectionProvider but is not
* required to actually use any connections.
*
* The metadata methods all returns Iterator and allows for more efficient and partial reads
* for those databases that has "flakey" JDBC metadata implementions.
*
* @author Max Rydahl Andersen
*
*/
public interface RevengDialect {

/**
* Configure the metadatadialect.
* @param connectionProvider a {@link ConnectionProvider}
*/
public void configure(ConnectionProvider connectionProvider);

/**
* Return iterator over the tables that mathces catalog, schema and table
*
* @param catalog name or null
* @param schema name or null
* @param table name or null
* @return iterator with map elements that has "TABLE_NAME", "TABLE_SCHEMA", "TABLE_CAT", "TABLE_TYPE" keys.
*/
Iterator<Map<String,Object>> getTables(String catalog, String schema, String table);

/**
* Close the iterator.
* @param iterator an iterator returned from one of methods on this dialect
*/
void close(Iterator<?> iterator);

/**
* Return iterator over the indexes that mathces catalog, schema and table
*
* @param catalog name or null
* @param schema name or null
* @param table name or null
* @return iterator with map elements that has "TABLE_NAME", "TABLE_SCHEMA", "TABLE_CAT", "INDEX_NAME", "COLUMN_NAME", "NON_UNIQUE", "TYPE" keys.
*/
Iterator<Map<String, Object>> getIndexInfo(String catalog, String schema, String table);

/**
* Return iterator over the columns that mathces catalog, schema and table
*
* @param catalog name or null
* @param schema name or null
* @param table name or null
* @param column name or null
* @return iterator with map elements that has "TABLE_NAME", "TABLE_SCHEMA", "TABLE_CAT", "DATA_TYPE", "TYPE_NAME", "COLUMN_NAME", "NULLABLE", "COLUMN_SIZE", "DECIMAL_DIGITS"
*/
Iterator<Map<String, Object>> getColumns(String catalog, String schema, String table, String column);

/**
* Return iterator over the columns that mathces catalog, schema and table
*
* @param catalog name or null
* @param schema name or null
* @param table name or null
* @return iterator with map elements that has "TABLE_NAME", "TABLE_SCHEMA", "TABLE_CAT", "COLUMN_NAME", "KEY_SEQ", "PK_NAME",
*/
Iterator<Map<String, Object>> getPrimaryKeys(String catalog, String schema, String name);


/**
* Return iterator over the exported foreign keys that mathces catalog, schema and table
*
* @param catalog name or null
* @param schema name or null
* @param table name or null
* @return iterator with map elements that has "TABLE_NAME", "TABLE_SCHEMA", "TABLE_CAT", "FKTABLE_CAT", "FKTABLE_SCHEM", "FKTABLE_NAME", "FK_NAME", "KEY_SEQ"
*/
Iterator<Map<String, Object>> getExportedKeys(String catalog, String schema, String table);

/**
* Does this name need quoting
*
* @param name
* @return
*/
boolean needQuote(String name);

/**
* Close any resources this dialect might have used.
*/
void close();

/**
* Use database (possible native) metadata to suggest identifier strategy.
*
* @param catalog
* @param schema
* @param name
* @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)
*/
public Iterator<Map<String, Object>> getSuggestedPrimaryKeyStrategyName(String catalog, String schema, String table);


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* Hibernate Tools, Tooling for your Hibernate Projects
*
* Copyright 2010-2025 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hibernate.tool.reveng.api.core;

import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.HSQLDialect;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.OracleDialect;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.tool.reveng.internal.core.dialect.H2MetaDataDialect;
import org.hibernate.tool.reveng.internal.core.dialect.HSQLMetaDataDialect;
import org.hibernate.tool.reveng.internal.core.dialect.JDBCMetaDataDialect;
import org.hibernate.tool.reveng.internal.core.dialect.MySQLMetaDataDialect;
import org.hibernate.tool.reveng.internal.core.dialect.OracleMetaDataDialect;
import org.hibernate.tool.reveng.internal.core.dialect.SQLServerMetaDataDialect;

import java.lang.reflect.Constructor;
import java.util.Properties;

public class RevengDialectFactory {

private RevengDialectFactory() {}

public static RevengDialect createMetaDataDialect(Dialect dialect, Properties cfg) {
String property = cfg.getProperty( "hibernatetool.metadatadialect" );
RevengDialect mdd = fromClassName(property);
if(mdd==null) {
mdd = fromDialect(dialect);
}
if(mdd==null) {
mdd = fromDialectName(dialect.getClass().getName());
}
if(mdd==null) {
mdd = new JDBCMetaDataDialect();
}
return mdd;
}

public static RevengDialect fromClassName(String property) {
if ( property != null ) {
try {
Class<?> revengDialectClass = ReflectHelper.classForName(
property,
RevengDialectFactory.class );
Constructor<?> revengDialectConstructor = revengDialectClass.getConstructor(
new Class[] {});
return (RevengDialect)revengDialectConstructor.newInstance();
}
catch (Throwable e) {
throw new RuntimeException(
"Could not load MetaDataDialect: " + property, e );
}
} else {
return null;
}
}

public static RevengDialect fromDialect(Dialect dialect) {
if(dialect!=null) {
if(dialect instanceof OracleDialect) {
return new OracleMetaDataDialect();
} else if (dialect instanceof H2Dialect) {
return new H2MetaDataDialect();
} else if (dialect instanceof MySQLDialect) {
return new MySQLMetaDataDialect();
} else if (dialect instanceof HSQLDialect) {
return new HSQLMetaDataDialect();
}else if (dialect instanceof SQLServerDialect) {
return new SQLServerMetaDataDialect();
}
}
return null;
}

public static RevengDialect fromDialectName(String dialect) {
if (dialect.toLowerCase().contains("oracle")) {
return new OracleMetaDataDialect();
}
if (dialect.toLowerCase().contains("mysql")) {
return new MySQLMetaDataDialect();
}
if (dialect.toLowerCase().contains("h2")) {
return new H2MetaDataDialect();
}
if (dialect.toLowerCase().contains("hsql")) {
return new HSQLMetaDataDialect();
}
if (dialect.toLowerCase().contains("sqlserver")) {
return new SQLServerMetaDataDialect();
}
return null;
}


}
Loading
Loading