Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.hibernate.cfg.reveng.OverrideRepository Maven / Gradle / Ivy
package org.hibernate.cfg.reveng;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.apache.commons.collections4.MapIterator;
import org.apache.commons.collections4.MultiValuedMap;
import org.dom4j.Document;
import org.hibernate.MappingException;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.xml.ErrorLogger;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.ForeignKey;
import org.hibernate.mapping.MetaAttribute;
import org.hibernate.mapping.Table;
import org.hibernate.tool.util.TableNameQualifier;
import org.hibernate.tool.xml.XMLHelper;
import org.jboss.logging.Logger;
import org.xml.sax.InputSource;
public class OverrideRepository {
final private static Logger log = Logger.getLogger( OverrideRepository.class );
final private Map> typeMappings; // from sqltypes to list of SQLTypeMapping
final private List tableFilters;
final private List tables;
final private Map> foreignKeys; // key: TableIdentifier element: List of foreignkeys that references the Table
final private Map typeForColumn;
final private Map propertyNameForColumn;
final private Map identifierStrategyForTable;
final private Map identifierPropertiesForTable;
final private Map> primaryKeyColumnsForTable;
final private Set excludedColumns;
final private Map tableToClassName;
final private List schemaSelections;
final private Map propertyNameForPrimaryKey;
final private Map compositeIdNameForTable;
final private Map foreignKeyToOneName;
final private Map foreignKeyToInverseName;
final private Map foreignKeyInverseExclude;
final private Map foreignKeyToOneExclude;
final private Map foreignKeyToEntityInfo;
final private Map foreignKeyToInverseEntityInfo;
final private Map> tableMetaAttributes; // TI -> MultiMap of SimpleMetaAttributes
final private Map> columnMetaAttributes;
//private String defaultCatalog;
//private String defaultSchema;
public OverrideRepository() {
//this.defaultCatalog = null;
//this.defaultSchema = null;
typeMappings = new HashMap>();
tableFilters = new ArrayList();
tables = new ArrayList();
foreignKeys = new HashMap>();
typeForColumn = new HashMap();
propertyNameForColumn = new HashMap();
identifierStrategyForTable = new HashMap();
identifierPropertiesForTable = new HashMap();
primaryKeyColumnsForTable = new HashMap>();
propertyNameForPrimaryKey = new HashMap();
tableToClassName = new HashMap();
excludedColumns = new HashSet();
schemaSelections = new ArrayList();
compositeIdNameForTable = new HashMap();
foreignKeyToOneName = new HashMap();
foreignKeyToInverseName = new HashMap();
foreignKeyInverseExclude = new HashMap();
foreignKeyToOneExclude = new HashMap();
tableMetaAttributes = new HashMap>();
columnMetaAttributes = new HashMap>();
foreignKeyToEntityInfo = new HashMap();
foreignKeyToInverseEntityInfo = new HashMap();
}
public OverrideRepository addFile(File xmlFile) {
log.info( "Override file: " + xmlFile.getPath() );
try {
addInputStream( new FileInputStream( xmlFile ) );
}
catch ( Exception e ) {
log.error( "Could not configure overrides from file: " + xmlFile.getPath(), e );
throw new MappingException( "Could not configure overrides from file: " + xmlFile.getPath(), e );
}
return this;
}
/**
* Read override from an application resource trying different classloaders.
* This method will try to load the resource first from the thread context
* classloader and then from the classloader that loaded Hibernate.
*/
public OverrideRepository addResource(String path) throws MappingException {
log.info( "Mapping resource: " + path );
InputStream rsrc = Thread.currentThread().getContextClassLoader().getResourceAsStream( path );
if ( rsrc == null ) rsrc = OverrideRepository.class.getClassLoader().getResourceAsStream( path );
if ( rsrc == null ) throw new MappingException( "Resource: " + path + " not found" );
try {
return addInputStream( rsrc );
}
catch ( MappingException me ) {
throw new MappingException( "Error reading resource: " + path, me );
}
}
public OverrideRepository addInputStream(InputStream xmlInputStream) throws MappingException {
try {
ErrorLogger errorLogger = new ErrorLogger( "XML InputStream" );
org.dom4j.Document doc = XMLHelper.createSAXReader( errorLogger).read( new InputSource( xmlInputStream ) );
if ( errorLogger.hasErrors() ) throw new MappingException( "invalid override definition", ( Throwable ) errorLogger.getErrors().get( 0 ) );
add( doc );
return this;
}
catch ( MappingException me ) {
throw me;
}
catch ( Exception e ) {
log.error( "Could not configure overrides from input stream", e );
throw new MappingException( e );
}
finally {
try {
xmlInputStream.close();
}
catch ( IOException ioe ) {
log.error( "could not close input stream", ioe );
}
}
}
private OverrideRepository add(Document doc) {
OverrideBinder.bindRoot(this, doc);
return this;
}
private String getPreferredHibernateType(int sqlType, int length, int precision, int scale, boolean nullable) {
List l = typeMappings.get(new TypeMappingKey(sqlType,length) );
if(l == null) { // if no precise length match found, then try to find matching unknown length matches
l = typeMappings.get(new TypeMappingKey(sqlType,SQLTypeMapping.UNKNOWN_LENGTH) );
}
return scanForMatch( sqlType, length, precision, scale, nullable, l );
}
private String scanForMatch(int sqlType, int length, int precision, int scale, boolean nullable, List l) {
if(l!=null) {
Iterator iterator = l.iterator();
while (iterator.hasNext() ) {
SQLTypeMapping element = iterator.next();
if(element.getJDBCType()!=sqlType) return null;
if(element.match(sqlType, length, precision, scale, nullable) ) {
return element.getHibernateType();
}
}
}
return null;
}
public OverrideRepository addTypeMapping(SQLTypeMapping sqltype) {
TypeMappingKey key = new TypeMappingKey(sqltype);
List list = typeMappings.get(key);
if(list==null) {
list = new ArrayList();
typeMappings.put(key, list);
}
list.add(sqltype);
return this;
}
static class TypeMappingKey {
int type;
int length;
TypeMappingKey(SQLTypeMapping mpa) {
type = mpa.getJDBCType();
length = mpa.getLength();
}
public TypeMappingKey(int sqlType, int length) {
this.type = sqlType;
this.length = length;
}
public boolean equals(Object obj) {
if(obj==null) return false;
if(!(obj instanceof TypeMappingKey)) return false;
TypeMappingKey other = (TypeMappingKey) obj;
return type==other.type && length==other.length;
}
public int hashCode() {
return (type + length) % 17;
}
public String toString() {
return this.getClass() + "(type:" + type + ", length:" + length + ")";
}
}
protected String getPackageName(TableIdentifier identifier) {
Iterator iterator = tableFilters.iterator();
while(iterator.hasNext() ) {
TableFilter tf = iterator.next();
String value = tf.getPackage(identifier);
if(value!=null) {
return value;
}
}
return null;
}
protected boolean excludeTable(TableIdentifier identifier) {
Iterator iterator = tableFilters.iterator();
boolean hasInclude = false;
while(iterator.hasNext() ) {
TableFilter tf = iterator.next();
Boolean value = tf.exclude(identifier);
if(value!=null) {
return value.booleanValue();
}
if(!tf.getExclude().booleanValue()) {
hasInclude = true;
}
}
// can probably be simplified - but like this to be very explicit ;)
if(hasInclude) {
return true; // exclude all by default when at least one include specified
} else {
return false; // if nothing specified or just excludes we include everything
}
}
public void addTableFilter(TableFilter filter) {
tableFilters.add(filter);
}
public ReverseEngineeringStrategy getReverseEngineeringStrategy(ReverseEngineeringStrategy delegate) {
return new DelegatingReverseEngineeringStrategy(delegate) {
public boolean excludeTable(TableIdentifier ti) {
return OverrideRepository.this.excludeTable(ti);
}
public Map tableToMetaAttributes(TableIdentifier tableIdentifier) {
return OverrideRepository.this.tableToMetaAttributes(tableIdentifier);
}
public Map columnToMetaAttributes(TableIdentifier tableIdentifier, String column) {
return OverrideRepository.this.columnToMetaAttributes(tableIdentifier, column);
}
public boolean excludeColumn(TableIdentifier identifier, String columnName) {
return excludedColumns.contains(new TableColumnKey(identifier, columnName));
}
public String tableToCompositeIdName(TableIdentifier identifier) {
String result = compositeIdNameForTable.get(identifier);
if(result==null) {
return super.tableToCompositeIdName(identifier);
} else {
return result;
}
}
public List getSchemaSelections() {
if(schemaSelections.isEmpty()) {
return super.getSchemaSelections();
} else {
return schemaSelections;
}
}
public String columnToHibernateTypeName(TableIdentifier table, String columnName, int sqlType, int length, int precision, int scale, boolean nullable, boolean generatedIdentifier) {
String result = null;
String location = "";
String info = " t:" + JDBCToHibernateTypeHelper.getJDBCTypeName( sqlType ) + " l:" + length + " p:" + precision + " s:" + scale + " n:" + nullable + " id:" + generatedIdentifier;
if(table!=null) {
location = TableNameQualifier.qualify(table.getCatalog(), table.getSchema(), table.getName() ) + "." + columnName;
} else {
location += " Column: " + columnName + info;
}
if(table!=null && columnName!=null) {
result = typeForColumn.get(new TableColumnKey(table, columnName));
if(result!=null) {
log.debug("explicit column mapping found for [" + location + "] to [" + result + "]");
return result;
}
}
result = OverrideRepository.this.getPreferredHibernateType(sqlType, length, precision, scale, nullable);
if(result==null) {
return super.columnToHibernateTypeName(table, columnName, sqlType, length, precision, scale, nullable, generatedIdentifier);
}
else {
log.debug(" found for [" + location + info + "] to [" + result + "]");
return result;
}
}
public String tableToClassName(TableIdentifier tableIdentifier) {
String className = tableToClassName.get(tableIdentifier);
if(className!=null) {
if(className.indexOf( "." )>=0) {
return className;
} else {
String packageName = getPackageName(tableIdentifier);
if(packageName==null) {
return className;
} else {
return StringHelper.qualify(packageName, className);
}
}
}
String packageName = getPackageName(tableIdentifier);
if(packageName==null) {
return super.tableToClassName(tableIdentifier);
}
else {
String string = super.tableToClassName(tableIdentifier);
if(string==null) return null;
return StringHelper.qualify(packageName, StringHelper.unqualify(string));
}
}
public List getForeignKeys(TableIdentifier referencedTable) {
List list = foreignKeys.get(referencedTable);
if(list==null) {
return super.getForeignKeys(referencedTable);
} else {
return list;
}
}
public String columnToPropertyName(TableIdentifier table, String column) {
String result = propertyNameForColumn.get(new TableColumnKey(table, column));
if(result==null) {
return super.columnToPropertyName(table, column);
} else {
return result;
}
}
public String tableToIdentifierPropertyName(TableIdentifier tableIdentifier) {
String result = propertyNameForPrimaryKey.get(tableIdentifier);
if(result==null) {
return super.tableToIdentifierPropertyName(tableIdentifier);
} else {
return result;
}
}
public String getTableIdentifierStrategyName(TableIdentifier tableIdentifier) {
String result = identifierStrategyForTable.get(tableIdentifier);
if(result==null) {
return super.getTableIdentifierStrategyName( tableIdentifier );
} else {
log.debug("tableIdentifierStrategy for " + tableIdentifier + " -> '" + result + "'");
return result;
}
}
public Properties getTableIdentifierProperties(TableIdentifier tableIdentifier) {
Properties result = identifierPropertiesForTable.get(tableIdentifier);
if(result==null) {
return super.getTableIdentifierProperties( tableIdentifier );
} else {
return result;
}
}
public List getPrimaryKeyColumnNames(TableIdentifier tableIdentifier) {
List result = primaryKeyColumnsForTable.get(tableIdentifier);
if(result==null) {
return super.getPrimaryKeyColumnNames(tableIdentifier);
} else {
return result;
}
}
public String foreignKeyToEntityName(String keyname, TableIdentifier fromTable, List fromColumnNames, TableIdentifier referencedTable, List referencedColumnNames, boolean uniqueReference) {
String property = foreignKeyToOneName.get(keyname);
if(property==null) {
return super.foreignKeyToEntityName(keyname, fromTable, fromColumnNames, referencedTable, referencedColumnNames, uniqueReference);
} else {
return property;
}
}
public String foreignKeyToInverseEntityName(String keyname,
TableIdentifier fromTable, List fromColumnNames,
TableIdentifier referencedTable,
List referencedColumnNames, boolean uniqueReference) {
String property = foreignKeyToInverseName.get(keyname);
if(property==null) {
return super.foreignKeyToInverseEntityName(keyname, fromTable, fromColumnNames, referencedTable, referencedColumnNames, uniqueReference);
} else {
return property;
}
}
public String foreignKeyToCollectionName(String keyname, TableIdentifier fromTable, List fromColumns, TableIdentifier referencedTable, List referencedColumns, boolean uniqueReference) {
String property = foreignKeyToInverseName.get(keyname);
if(property==null) {
return super.foreignKeyToCollectionName(keyname, fromTable, fromColumns, referencedTable, referencedColumns, uniqueReference);
} else {
return property;
}
}
public boolean excludeForeignKeyAsCollection(
String keyname,
TableIdentifier fromTable,
List fromColumns,
TableIdentifier referencedTable,
List referencedColumns) {
Boolean bool = foreignKeyInverseExclude.get(keyname);
if(bool!=null) {
return bool.booleanValue();
} else {
return super.excludeForeignKeyAsCollection( keyname, fromTable, fromColumns,
referencedTable, referencedColumns );
}
}
public boolean excludeForeignKeyAsManytoOne(
String keyname,
TableIdentifier fromTable,
List fromColumns, TableIdentifier
referencedTable,
List referencedColumns) {
Boolean bool = (Boolean) foreignKeyToOneExclude.get(keyname);
if(bool!=null) {
return bool.booleanValue();
} else {
return super.excludeForeignKeyAsManytoOne( keyname, fromTable, fromColumns,
referencedTable, referencedColumns );
}
}
public AssociationInfo foreignKeyToInverseAssociationInfo(ForeignKey foreignKey) {
AssociationInfo fkei = foreignKeyToInverseEntityInfo.get(foreignKey.getName());
if(fkei!=null) {
return fkei;
} else {
return super.foreignKeyToInverseAssociationInfo(foreignKey);
}
}
public AssociationInfo foreignKeyToAssociationInfo(ForeignKey foreignKey) {
AssociationInfo fkei = foreignKeyToEntityInfo.get(foreignKey.getName());
if(fkei!=null) {
return fkei;
} else {
return super.foreignKeyToAssociationInfo(foreignKey);
}
}
};
}
protected Map columnToMetaAttributes(TableIdentifier tableIdentifier, String column) {
MultiValuedMap specific = columnMetaAttributes.get( new TableColumnKey(tableIdentifier, column) );
if(specific!=null && !specific.isEmpty()) {
return toMetaAttributes(specific);
}
return null;
}
// TODO: optimize
protected Map tableToMetaAttributes(TableIdentifier identifier) {
MultiValuedMap specific = tableMetaAttributes.get( identifier );
if(specific!=null && !specific.isEmpty()) {
return toMetaAttributes(specific);
}
MultiValuedMap general = findGeneralAttributes( identifier );
if(general!=null && !general.isEmpty()) {
return toMetaAttributes(general);
}
return null;
/* inheritance not defined yet
if(specific==null) { specific = Collections.EMPTY_MAP; }
if(general==null) { general = Collections.EMPTY_MAP; }
MultiMap map = MetaAttributeBinder.mergeMetaMaps( specific, general );
*/
/*
if(map!=null && !map.isEmpty()) {
return toMetaAttributes(null, map);
} else {
return null;
}
*/
}
private MultiValuedMap findGeneralAttributes(TableIdentifier identifier) {
Iterator iterator = tableFilters.iterator();
while(iterator.hasNext() ) {
TableFilter tf = iterator.next();
MultiValuedMap value = tf.getMetaAttributes(identifier);
if(value!=null) {
return value;
}
}
return null;
}
private Map toMetaAttributes(MultiValuedMap mvm) {
Map result = new HashMap();
for (MapIterator iter = mvm.mapIterator(); iter.hasNext();) {
String key = iter.next();
Collection values = mvm.get(key);
result.put(key, MetaAttributeBinder.toRealMetaAttribute(key, values));
}
return result;
}
public ReverseEngineeringStrategy getReverseEngineeringStrategy() {
return getReverseEngineeringStrategy(null);
}
public void addTable(Table table, String wantedClassName) {
Iterator fkIter = table.getForeignKeyIterator();
while ( fkIter.hasNext() ) {
ForeignKey fk = (ForeignKey) fkIter.next();
TableIdentifier identifier = TableIdentifier.create(fk.getReferencedTable());
List existing = foreignKeys.get(identifier);
if(existing==null) {
existing = new ArrayList();
foreignKeys.put(identifier, existing);
}
existing.add( fk );
}
tables.add(table);
if(StringHelper.isNotEmpty(wantedClassName)) {
tableToClassName.put(TableIdentifier.create(table), wantedClassName);
}
}
static class TableColumnKey {
private TableIdentifier query;
private String name;
TableColumnKey(TableIdentifier query, String name){
this.query = query;
this.name = name;
}
@Override
public int hashCode() {
final int prime = 29;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((query == null) ? 0 : query.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
TableColumnKey other = (TableColumnKey) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (query == null) {
if (other.query != null)
return false;
} else if (!query.equals(other.query))
return false;
return true;
}
}
public void setTypeNameForColumn(TableIdentifier identifier, String columnName, String type) {
if(StringHelper.isNotEmpty(type)) {
typeForColumn.put(new TableColumnKey(identifier, columnName), type);
}
}
public void setExcludedColumn(TableIdentifier tableIdentifier, String columnName) {
excludedColumns.add(new TableColumnKey(tableIdentifier, columnName));
}
public void setPropertyNameForColumn(TableIdentifier identifier, String columnName, String property) {
if(StringHelper.isNotEmpty(property)) {
propertyNameForColumn.put(new TableColumnKey(identifier, columnName), property);
}
}
public void addTableIdentifierStrategy(Table table, String identifierClass, Properties params) {
if(identifierClass!=null) {
final TableIdentifier tid = TableIdentifier.create(table);
identifierStrategyForTable.put(tid, identifierClass);
identifierPropertiesForTable.put(tid, params);
}
}
public void addPrimaryKeyNamesForTable(Table table, List boundColumnNames, String propertyName, String compositeIdName) {
TableIdentifier tableIdentifier = TableIdentifier.create(table);
if(boundColumnNames!=null && !boundColumnNames.isEmpty()) {
primaryKeyColumnsForTable.put(tableIdentifier, boundColumnNames);
}
if(StringHelper.isNotEmpty(propertyName)) {
propertyNameForPrimaryKey.put(tableIdentifier, propertyName);
}
if(StringHelper.isNotEmpty(compositeIdName)) {
compositeIdNameForTable.put(tableIdentifier, compositeIdName);
}
}
/*public String getCatalog(String string) {
return string==null?defaultCatalog:string;
}*/
/*public String getSchema(String string) {
return string==null?defaultSchema:string;
}*/
public void addSchemaSelection(SchemaSelection schemaSelection) {
schemaSelections.add(schemaSelection);
}
/**
* Both sides of the FK are important,
* the owning side can generate a toOne (ManyToOne or OneToOne), we call this side foreignKeyToOne
* the inverse side can generate a OneToMany OR a OneToOne (in case we have a pure bidirectional OneToOne, we call this side foreignKeyToInverse
*/
public void addForeignKeyInfo(String constraintName, String toOneProperty, Boolean excludeToOne, String inverseProperty, Boolean excludeInverse, AssociationInfo associationInfo, AssociationInfo inverseAssociationInfo) {
if(StringHelper.isNotEmpty(toOneProperty)) {
foreignKeyToOneName.put(constraintName, toOneProperty);
}
if(StringHelper.isNotEmpty(inverseProperty)) {
foreignKeyToInverseName.put(constraintName, inverseProperty);
}
if(excludeInverse!=null) {
foreignKeyInverseExclude.put(constraintName, excludeInverse);
}
if(excludeToOne!=null) {
foreignKeyToOneExclude.put(constraintName, excludeToOne);
}
if(associationInfo!=null) {
foreignKeyToEntityInfo.put(constraintName, associationInfo);
}
if(inverseAssociationInfo!=null) {
foreignKeyToInverseEntityInfo.put(constraintName, inverseAssociationInfo);
}
}
public void addMetaAttributeInfo(
Table table,
MultiValuedMap map) {
if(map!=null && !map.isEmpty()) {
tableMetaAttributes.put(TableIdentifier.create(table), map);
}
}
public void addMetaAttributeInfo(
TableIdentifier tableIdentifier,
String name,
MultiValuedMap map) {
if(map!=null && !map.isEmpty()) {
columnMetaAttributes.put(new TableColumnKey( tableIdentifier, name ), map);
}
}
}