package org.jblooming.persistence.hibernate;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.engine.Mapping;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.factory.DefaultIdentifierGeneratorFactory;
import org.hibernate.mapping.*;
import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
import org.hibernate.tool.hbm2ddl.ForeignKeyMetadata;
import org.hibernate.tool.hbm2ddl.IndexMetadata;
import org.hibernate.tool.hbm2ddl.TableMetadata;
import org.hibernate.util.ArrayHelper;
import org.jblooming.waf.settings.PersistenceConfiguration;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.TreeMap;
/**
* (c) Open Lab - www.open-lab.com
* Date: Jan 2, 2007
* Time: 4:31:50 PM
*/
public class PlatformAnnotationConfiguration extends Configuration {
private PersistenceConfiguration persistenceConfiguration;
public PlatformAnnotationConfiguration(PersistenceConfiguration persistenceConfiguration){
this.persistenceConfiguration=persistenceConfiguration;
}
public String[] generateSchemaUpdateScript(Dialect dialect, DatabaseMetadata databaseMetadata) throws HibernateException {
Mapping mapping = buildMapping();
secondPassCompile();
String defaultCatalog = getProperty(Environment.DEFAULT_CATALOG);
//String defaultSchema = getProperty(Environment.DEFAULT_SCHEMA);
ArrayList script = new ArrayList(50);
Iterator iter = getTableMappings();
while (iter.hasNext()) {
Table table = (Table) iter.next();
if (table.isPhysicalTable()) {
String schemaForTable = (persistenceConfiguration.schemaName != null ? persistenceConfiguration.schemaName : table.getSchema());
TableMetadata tableInfo = databaseMetadata.getTableMetadata(table.getName(), schemaForTable, table.getCatalog(), false);
if (tableInfo == null) {
script.add(table.sqlCreateString(dialect, mapping, defaultCatalog, schemaForTable));
} else {
Iterator subiter = table.sqlAlterStrings(dialect, mapping, tableInfo, defaultCatalog, schemaForTable);
while (subiter.hasNext()) script.add(subiter.next());
}
Iterator comments = table.sqlCommentStrings(dialect, defaultCatalog, schemaForTable);
while (comments.hasNext()) {
script.add(comments.next());
}
}
}
iter = getTableMappings();
while (iter.hasNext()) {
Table table = (Table) iter.next();
if (table.isPhysicalTable()) {
String schemaForTable = (persistenceConfiguration.schemaName != null ? persistenceConfiguration.schemaName : table.getSchema());
TableMetadata tableInfo = databaseMetadata.getTableMetadata(table.getName(), (persistenceConfiguration.schemaName != null ? persistenceConfiguration.schemaName : table.getSchema()), table.getCatalog(), false);
// Hack that generates indexes that are omitted when using
// hibernate.hbm2ddl.auto=update. See commented-out code below.
Iterator idxIter = table.getIndexIterator();
while (idxIter.hasNext()) {
Index index = (Index) idxIter.next();
// Skip if index already exists
if (tableInfo != null) {
IndexMetadata meta = tableInfo.getIndexMetadata(index.getName());
if (meta != null) {
continue;
}
}
script.add(index.sqlCreateString(dialect,
mapping,
defaultCatalog,
schemaForTable));
}
if (dialect.hasAlterTable()) {
Iterator subIter = table.getForeignKeyIterator();
while (subIter.hasNext()) {
ForeignKey fk = (ForeignKey) subIter.next();
if (fk.isPhysicalConstraint()) {
boolean create = false;
if (tableInfo != null) {
ForeignKeyMetadata foreignKeyMetadata = tableInfo.getForeignKeyMetadata(fk.getName());
IndexMetadata indexMetadata = tableInfo.getIndexMetadata(fk.getName());
create = (foreignKeyMetadata == null && (
//Icky workaround for MySQL bug:
!(dialect instanceof MySQLDialect) ||
indexMetadata == null
)
);
} else
create = true;
if (create) {
script.add(fk.sqlCreateString(dialect, mapping, defaultCatalog, schemaForTable));
}
}
}
}
}
}
iter = iterateGenerators(dialect);
while (iter.hasNext()) {
PersistentIdentifierGenerator generator = (PersistentIdentifierGenerator) iter.next();
Object key = generator.generatorKey();
if (!databaseMetadata.isSequence(key) && !databaseMetadata.isTable(key)) {
String[] lines = generator.sqlCreateStrings(dialect);
for (int i = 0; i < lines.length; i++) {
script.add(lines[i]);
}
}
}
return ArrayHelper.toStringArray(script);
}
private Iterator iterateGenerators(Dialect
dialect) throws MappingException {
TreeMap generators = new TreeMap();
String defaultCatalog = getProperty(Environment.DEFAULT_CATALOG);
String defaultSchema = getProperty(Environment.DEFAULT_SCHEMA);
Iterator iter = classes.values().iterator();
while (iter.hasNext()) {
PersistentClass pc = (PersistentClass) iter.next();
if (!pc.isInherited()) {
IdentifierGenerator ig = pc.getIdentifier().createIdentifierGenerator(new DefaultIdentifierGeneratorFactory(), dialect, defaultCatalog, defaultSchema, (RootClass) pc);
if (ig instanceof PersistentIdentifierGenerator) {
generators.put(((PersistentIdentifierGenerator) ig).generatorKey(), ig);
}
}
}
iter = collections.values().iterator();
while (iter.hasNext()) {
Collection collection = (Collection) iter.next();
if (collection.isIdentified()) {
IdentifierGenerator ig = ((IdentifierCollection) collection).getIdentifier().createIdentifierGenerator(new DefaultIdentifierGeneratorFactory(),dialect, defaultCatalog, defaultSchema, null);
if (ig instanceof PersistentIdentifierGenerator) {
generators.put(((PersistentIdentifierGenerator) ig).generatorKey(), ig);
}
}
}
return generators.values().iterator();
}
}