All Downloads are FREE. Search and download functionalities are using the official Maven repository.

liquibase.ext.hibernate.database.HibernateDatabase Maven / Gradle / Ivy

Go to download

Liquibase extension for hibernate integration including generating changesets based on changed hibernate mapping files

The newest version!
package liquibase.ext.hibernate.database;

import liquibase.change.Change;
import liquibase.changelog.ChangeSet;
import liquibase.changelog.DatabaseChangeLog;
import liquibase.changelog.RanChangeSet;
import liquibase.database.Database;
import liquibase.database.DatabaseConnection;
import liquibase.database.structure.DatabaseObject;
import liquibase.exception.*;
import liquibase.sql.visitor.SqlVisitor;
import liquibase.statement.DatabaseFunction;
import liquibase.statement.SqlStatement;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.hibernate.ejb.Ejb3Configuration;
import org.hibernate.ejb.event.EJB3PostInsertEventListener;
import org.hibernate.envers.configuration.AuditConfiguration;
import org.hibernate.event.PostInsertEventListener;
import org.hibernate.util.ReflectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.TypedStringValue;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.ManagedProperties;
import org.springframework.beans.factory.support.SimpleBeanDefinitionRegistry;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.core.io.FileSystemResource;
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;

import java.io.IOException;
import java.io.Writer;
import java.math.BigInteger;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.*;

public class HibernateDatabase implements Database {

    private static final Logger LOG = LoggerFactory.getLogger(HibernateDatabase.class);

    private static final Class FACTORY_BEAN_CLASS = LocalSessionFactoryBean.class;
    public static final String SPRING_BEAN = "bean";
    public static final String SPRING_BEAN_CLASS = "beanClass";

    private String defaultSchema;
    private DatabaseConnection conn;
    private ConfigLocator locator;

    public HibernateDatabase() {
    }

    public ConfigType getConfigType() {
        return locator.getType();
    }

    public String getConfigFile() {
        return locator.getPath();
    }

    public boolean requiresPassword() {
        return false;
    }

    public boolean requiresUsername() {
        return false;
    }

    public DatabaseObject[] getContainingObjects() {
        return null;
    }

    public boolean isCorrectDatabaseImplementation(DatabaseConnection conn) throws DatabaseException {
        return ConfigType.forUrl(conn.getURL()) != null;
    }

    public String getDefaultDriver(String url) {
        return "liquibase.ext.hibernate.database.HibernateDriver";
    }

    public DatabaseConnection getConnection() {
        return conn;
    }

    public void setConnection(DatabaseConnection conn) {
        this.conn = conn;
        this.locator = new ConfigLocator(conn.getURL());

        LOG.info("Conn: " + conn );
        LOG.info("Locator: " + locator);
    }

    public void checkDatabaseChangeLogTable(boolean b, DatabaseChangeLog databaseChangeLog) throws DatabaseException {

    }

    public List getDatabaseFunctions() {
        return new ArrayList();
    }

    public void reset() {
    }

    public boolean supportsForeignKeyDisable() {
        return false;
    }

    public boolean disableForeignKeyChecks() throws DatabaseException {
        return false;
    }

    public void enableForeignKeyChecks() throws DatabaseException {
    }

    public int getPriority() {
        return PRIORITY_DEFAULT;
    }

    public boolean getAutoCommitMode() {
        return false;
    }

    public boolean isAutoCommit() throws DatabaseException {
        return false;
    }

    public void setAutoCommit(boolean b) throws DatabaseException {

    }

    public boolean supportsDDLInTransaction() {
        return false;
    }

    public String getDatabaseProductName() {
        return "Hibernate Mapping";
    }

    public String getDatabaseProductVersion() throws DatabaseException {
        return "N/A";
    }

    public int getDatabaseMajorVersion() throws DatabaseException {
        return -1;
    }

    public int getDatabaseMinorVersion() throws DatabaseException {
        return -1;
    }

    public String getTypeName() {
        return "hibernate";
    }

    public String getDefaultCatalogName() throws DatabaseException {
        return null;
    }

    public String getDefaultSchemaName() {
        return defaultSchema;
    }

    public void setDefaultSchemaName(String schemaName) throws DatabaseException {
        this.defaultSchema = schemaName;
    }

    public boolean supportsInitiallyDeferrableColumns() {
        return false;
    }

    public boolean supportsSequences() {
        return false;
    }

    public boolean supportsAutoIncrement() {
        return false;
    }

    public String getDateLiteral(String isoDate) {
        return null;
    }

    public String getCurrentDateTimeFunction() {
        return null;
    }

    public void setCurrentDateTimeFunction(String function) {

    }

    public String getLineComment() {
        return null;
    }

    public String getAutoIncrementClause(BigInteger bigInteger, BigInteger bigInteger2) {
        return null;
    }

    public String getAutoIncrementClause() {
        return null;
    }

    public String getDatabaseChangeLogTableName() {
        return null;
    }

    public String getDatabaseChangeLogLockTableName() {
        return null;
    }

    /**
     * Does nothing because this is a hibernate database
     *
     * @see liquibase.database.Database#setDatabaseChangeLogLockTableName(java.lang.String)
     */
    public void setDatabaseChangeLogLockTableName(String tableName) {
    }

    /**
     * Does nothing because this is a hibernate database
     *
     * @see liquibase.database.Database#setDatabaseChangeLogTableName(java.lang.String)
     */
    public void setDatabaseChangeLogTableName(String tableName) {
    }

    public String getConcatSql(String... values) {
        return null;
    }

    public void setCanCacheLiquibaseTableInfo(boolean canCacheLiquibaseTableInfo) {
        //
    }

    public boolean hasDatabaseChangeLogTable() {
        return false;
    }

    public boolean hasDatabaseChangeLogLockTable() {
        return false;
    }

    public void checkDatabaseChangeLogTable() throws DatabaseException {

    }

    public void checkDatabaseChangeLogLockTable() throws DatabaseException {

    }

    public void dropDatabaseObjects(String schema) throws DatabaseException {

    }

    public void tag(String tagString) throws DatabaseException {

    }

    public boolean doesTagExist(String tag) throws DatabaseException {
        return false;
    }

    public boolean isSystemTable(String catalogName, String schemaName, String tableName) {
        return false;
    }

    public boolean isLiquibaseTable(String tableName) {
        return false;
    }

    public boolean shouldQuoteValue(String value) {
        return false;
    }

    public boolean supportsTablespaces() {
        return false;
    }

    public String getViewDefinition(String schemaName, String name) throws DatabaseException {
        return null;
    }

    public String getDatabaseProductName(DatabaseConnection conn) throws DatabaseException {
        return null;
    }

    public boolean isSystemView(String catalogName, String schemaName, String name) {
        return false;
    }

    public String getDateLiteral(Date date) {
        return null;
    }

    public String getTimeLiteral(Time time) {
        return null;
    }

    public String getDateTimeLiteral(Timestamp timeStamp) {
        return null;
    }

    public String getDateLiteral(java.util.Date defaultDateValue) {
        return null;
    }

    public String escapeTableName(String schemaName, String tableName) {
        return null;
    }

    public String escapeIndexName(String schemaName, String indexName) {
        return null;
    }

    public String escapeDatabaseObject(String objectName) {
        return null;
    }

    public String escapeColumnName(String schemaName, String tableName, String columnName) {
        return null;
    }

    public String escapeColumnNameList(String columnNames) {
        return null;
    }

    public String convertRequestedSchemaToSchema(String requestedSchema) throws DatabaseException {
        return null;
    }

    public String convertRequestedSchemaToCatalog(String requestedSchema) throws DatabaseException {
        return null;
    }

    public boolean supportsSchemas() {
        return false;
    }

    public String generatePrimaryKeyName(String tableName) {
        return null;
    }

    public String escapeSequenceName(String schemaName, String sequenceName) {
        return null;
    }

    public String escapeViewName(String schemaName, String viewName) {
        return null;
    }

    public ChangeSet.RunStatus getRunStatus(ChangeSet changeSet) throws DatabaseException, DatabaseHistoryException {
        return null;
    }

    public RanChangeSet getRanChangeSet(ChangeSet changeSet) throws DatabaseException, DatabaseHistoryException {
        return null;
    }

    public void markChangeSetExecStatus(ChangeSet changeSet, ChangeSet.ExecType execType) throws DatabaseException {

    }

    public List getRanChangeSetList() throws DatabaseException {
        return null;
    }

    public java.util.Date getRanDate(ChangeSet changeSet) throws DatabaseException, DatabaseHistoryException {
        return null;
    }

    public void removeRanStatus(ChangeSet changeSet) throws DatabaseException {

    }

    public void commit() throws DatabaseException {

    }

    public void rollback() throws DatabaseException {

    }

    public String escapeStringForDatabase(String string) {
        return null;
    }

    public void close() throws DatabaseException {

    }

    public Configuration createConfiguration() {
        Configuration config = null;

        switch (getConfigType()) {
            case EJB3:
                return createEjb3Configuration();
            case SPRING:
                return createSpringConfiguration();
            case HIBERNATE:
                return createHibernateConfiguration();
        }

        return config;
    }


    private Configuration createHibernateConfiguration() {
        Configuration config;
        config = new AnnotationConfiguration();
        config.configure(getConfigFile());
        return config;
    }

    private Configuration createSpringConfiguration() {
        AnnotationConfiguration config = new AnnotationConfiguration();
        BeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry();
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(registry);
        reader.loadBeanDefinitions(new FileSystemResource(locator.getPath()));

        Properties props = locator.getProperties();
        Class beanClass = FACTORY_BEAN_CLASS;

        String beanName = props.getProperty(SPRING_BEAN, null);
        String beanClassName = props.getProperty(SPRING_BEAN_CLASS, null);

        if (beanClassName != null)
            beanClass = findClass(beanClassName, beanClass);

        if (beanName == null) {
            throw new IllegalStateException("A 'bean' name is required, matching a '" + beanClassName + "' definition in '" + locator.getPath() + "'.");
        }

        BeanDefinition beanDef = registry.getBeanDefinition(beanName);
        if (beanDef == null)
            throw new IllegalStateException("A bean named '" + beanName + "' could not be found in '" + locator.getPath() + "'.");

        Class beanDefClass = findClass(beanDef.getBeanClassName(), beanClass);

        MutablePropertyValues properties = beanDef.getPropertyValues();

        // Add annotated classes list.
        PropertyValue annotatedClassesProp = properties.getPropertyValue("annotatedClasses");
        List annotatedClasses = (List) annotatedClassesProp.getValue();
        if (annotatedClasses != null) {
            for (TypedStringValue classname : annotatedClasses) {
                config.addAnnotatedClass(findClass(classname.getValue()));
            }
        }

        // Add properties
        ManagedProperties hibernateProps = (ManagedProperties) properties.getPropertyValue("hibernateProperties").getValue();

        if (hibernateProps != null) {
            Properties configProps = new Properties();
            for (Map.Entry entry : hibernateProps.entrySet()) {
                TypedStringValue key = (TypedStringValue) entry.getKey();
                TypedStringValue value = (TypedStringValue) entry.getValue();

                configProps.setProperty(key.getValue(), value.getValue());
            }

            config.setProperties(configProps);
        } else {
            throw new IllegalStateException("Please provide a 'hibernateProperties' property set to define the hibernate connection settings.");
        }

        return config;
    }

    private Class findClass(String className) {
        return findClass(className, Object.class);
    }

    private  Class findClass(String className, Class superClass) {
        try {
            Class newClass = ReflectHelper.classForName(className);
            if (superClass.isAssignableFrom(newClass)) {
                return newClass.asSubclass(superClass);
            } else {
                throw new IllegalStateException("The provided class '" + className + "' is not assignable from the '" + superClass.getName() + "' superclass.");
            }
        } catch (ClassNotFoundException e) {
            throw new IllegalStateException("Unable to find required class: '" + className + "'. Please check classpath and class name.");
        }
    }

    private Configuration createSpringConfigurationOld() {
        // Use 'file:' prefix to allow providing an absolute path by starting with '/'
        FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext("file:" + locator.getPath());

        Properties props = locator.getProperties();
        Class beanClass = FACTORY_BEAN_CLASS;

        String beanName = props.getProperty(SPRING_BEAN, null);
        String beanClassName = props.getProperty(SPRING_BEAN_CLASS, null);
        try {
            Class newBeanClass = Class.forName(beanClassName);
            if (FACTORY_BEAN_CLASS.isAssignableFrom(newBeanClass)) {
                beanClass = newBeanClass.asSubclass(FACTORY_BEAN_CLASS);
            }
        } catch (ClassNotFoundException e) {
            throw new IllegalStateException("Unable to find required factory class: '" + beanClassName + "'. Please check classpath and class name.");
        }

        LocalSessionFactoryBean factoryBean;
        if (beanName != null) { // Try the direct name.
            factoryBean = (LocalSessionFactoryBean) ctx.getBean(beanName, beanClass);

            if (factoryBean == null) {
                throw new IllegalStateException("Unable to locate a bean named '" + beanName + "' of type '" + beanClassName + "' in '" + locator.getPath() + ".");
            }

        } else { // Try finding a single bean that extends the bean factory class.
            Map beans = ctx.getBeansOfType(beanClass);
            if (beans.size() == 1)
                factoryBean = beans.values().iterator().next();
            else
                throw new IllegalStateException("Need exactly 1 bean of type '" + beanClassName + "' but found " + beans.size() + " in '" + locator.getPath() + ". "
                        + "Please provide a 'bean' name if multiple factories are defined in this config file.");
        }

        return factoryBean.getConfiguration();
    }

    private Configuration createEjb3Configuration() {
        Configuration config;
        Ejb3Configuration ejb3Configuration = new Ejb3Configuration();
        ejb3Configuration.configure(locator.getPath(), new HashMap());
        config = ejb3Configuration.getHibernateConfiguration();
        config.setProperty("hibernate.dialect", ejb3Configuration.getProperties().getProperty("hibernate.dialect"));
        for (PostInsertEventListener postInsertEventListener : config.getEventListeners().getPostInsertEventListeners()) {
            if (postInsertEventListener instanceof EJB3PostInsertEventListener) {
                AuditConfiguration.getFor(config);
            }
        }
        return config;
    }

    public boolean supportsRestrictForeignKeys() {
        return false;
    }

    public String escapeConstraintName(String constraintName) {
        return constraintName;
    }

    /**
     * As the connectionURL for Hibernate refers to a config file, just return false
     */
    public boolean isLocalDatabase() throws DatabaseException {
        return false;
    }

    public void executeStatements(Change change, DatabaseChangeLog changeLog, List sqlVisitors) throws LiquibaseException, UnsupportedChangeException {
    }

    public void execute(SqlStatement[] statements, List sqlVisitors) throws LiquibaseException {
    }

    public void saveStatements(Change change, List sqlVisitors, Writer writer) throws IOException, UnsupportedChangeException, StatementNotSupportedOnDatabaseException, LiquibaseException {
    }

    public void executeRollbackStatements(Change change, List sqlVisitors) throws LiquibaseException, UnsupportedChangeException, RollbackImpossibleException {
    }

    public void saveRollbackStatement(Change change, List sqlVisitors, Writer writer) throws IOException, UnsupportedChangeException, RollbackImpossibleException, StatementNotSupportedOnDatabaseException, LiquibaseException {
    }

    public String getLiquibaseSchemaName() {
        return null;
    }

    public int getNextChangeSetSequenceValue() throws LiquibaseException {
        return 1;
    }

    public java.util.Date parseDate(String dateAsString) throws DateParseException {
        return new java.util.Date();
    }

    public boolean isReservedWord(String string) {
        return false;
    }

    public void checkDatabaseChangeLogTable(boolean updateExistingNullChecksums, DatabaseChangeLog databaseChangeLog, String[] contexts) throws DatabaseException {
    }

    public boolean supportsDropTableCascadeConstraints() {
        return false;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy