Package org.jbpm.db

Source Code of org.jbpm.db.JbpmSchema

/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jbpm.db;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.connection.ConnectionProvider;
import org.hibernate.connection.ConnectionProviderFactory;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.Mapping;
import org.hibernate.mapping.ForeignKey;
import org.hibernate.mapping.Table;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.util.JDBCExceptionReporter;
import org.jbpm.JbpmException;

/**
* utilities for the jBPM database schema. 
*/
public class JbpmSchema implements Serializable {
 
  private static final long serialVersionUID = 1L;

  static final String JBPM_TABLE_PREFIX = "JBPM_";
 
  Configuration configuration = null;
  Properties properties = null;
  Dialect dialect = null;
  Mapping mapping = null;
  String[] createSql = null;
  String[] dropSql = null;
  String[] cleanSql = null;

  ConnectionProvider connectionProvider = null;
  Connection connection = null;
  Statement statement = null;

  public JbpmSchema(Configuration configuration) {
    this.configuration = configuration;
    this.properties = configuration.getProperties();
    this.dialect = Dialect.getDialect(properties);
    try {
      // get the mapping field via reflection :-(
      Field mappingField = Configuration.class.getDeclaredField("mapping");
      mappingField.setAccessible(true);
      this.mapping = (Mapping) mappingField.get(configuration);
    } catch (Exception e) {
      throw new JbpmException("couldn't get the hibernate mapping", e);
    }
  }

  public String[] getCreateSql() {
    if (createSql==null) {
      createSql = configuration.generateSchemaCreationScript(dialect);
    }
    return createSql;
  }
 
  public String[] getDropSql() {
    if (dropSql==null) {
      dropSql = configuration.generateDropSchemaScript(dialect);
    }
    return dropSql;
  }
 
  public String[] getCleanSql() {
    if (cleanSql==null) {
      // loop over all foreign key constraints
      List dropForeignKeysSql = new ArrayList();
      List createForeignKeysSql = new ArrayList();
      Iterator iter = configuration.getTableMappings();
      while ( iter.hasNext() ) {
        Table table = ( Table ) iter.next();
        if ( table.isPhysicalTable() ) {
          Iterator subIter = table.getForeignKeyIterator();
          while ( subIter.hasNext() ) {
            ForeignKey fk = ( ForeignKey ) subIter.next();
            if ( fk.isPhysicalConstraint() ) {
              // collect the drop foreign key constraint sql
              dropForeignKeysSql.add( fk.sqlDropString(
                  dialect,
                  properties.getProperty(Environment.DEFAULT_CATALOG),
                  properties.getProperty(Environment.DEFAULT_SCHEMA) ) );
              // and collect the create foreign key constraint sql
              createForeignKeysSql.add( fk.sqlCreateString(
                  dialect,
                  mapping,
                  properties.getProperty(Environment.DEFAULT_CATALOG),
                  properties.getProperty(Environment.DEFAULT_SCHEMA) ) );
            }
          }
        }
      }

      List deleteSql = new ArrayList();
      iter = configuration.getTableMappings();
      while (iter.hasNext()) {
        Table table = (Table) iter.next();
        deleteSql.add("delete from "+table.getName());
      }

      // glue
      //  - drop foreign key constraints
      //  - delete contents of all tables
      //  - create foreign key constraints
      // together to form the clean script
      List cleanSqlList = new ArrayList();
      cleanSqlList.addAll(dropForeignKeysSql);
      cleanSqlList.addAll(deleteSql);
      cleanSqlList.addAll(createForeignKeysSql);
     
      cleanSql = (String[]) cleanSqlList.toArray(new String[cleanSqlList.size()]);
    }
    return cleanSql;
  }

  public boolean hasJbpmTables() {
    return (getJbpmTables().size()>0);
  }

  public List getJbpmTables() {
    // delete all the data in the jbpm tables
    List jbpmTableNames = new ArrayList();
    try {
      createConnection();
      ResultSet resultSet = connection.getMetaData().getTables(null, null, null, null);
      while(resultSet.next()) {
        String tableName = resultSet.getString("TABLE_NAME");
        if ( (tableName!=null)
             && (tableName.length()>5)
             && (JBPM_TABLE_PREFIX.equalsIgnoreCase(tableName.substring(0,5))) ) {
          jbpmTableNames.add(tableName);
        }
      }
    } catch (SQLException e) {
      throw new JbpmException("couldn't get the jbpm table names");
    } finally {
      closeConnection();
    }
    return jbpmTableNames;
  }
 
  public void dropSchema() {
    execute( getDropSql() );
  }

  public void createSchema() {
    execute( getCreateSql() );
  }

  public void cleanSchema() {
    execute( getCleanSql() );
  }

  public void saveSqlScripts(String dir, String prefix) {
    try {
      new File(dir).mkdirs();
      saveSqlScript(dir+"/"+prefix+".drop.sql", getDropSql());
      saveSqlScript(dir+"/"+prefix+".create.sql", getCreateSql());
      saveSqlScript(dir+"/"+prefix+".clean.sql", getCleanSql());
      new SchemaExport(configuration)
        .setDelimiter(getSqlDelimiter())
        .setOutputFile(dir+"/"+prefix+".drop.create.sql")
        .create(true, false);
    } catch (Exception e) {
      throw new JbpmException("couldn't generate scripts", e);
    }
  }

  public static void main(String[] args) {
    try {
      if ( (args==null) || (args.length==0) ) {
        throw new IllegalArgumentException();
      }
     
      String cmd = args[0];
     
      if ("create".equalsIgnoreCase(cmd)) {
        Configuration configuration = createConfiguration(args, 1);
        new JbpmSchema(configuration).createSchema();
      } else if ("drop".equalsIgnoreCase(cmd)) {
        Configuration configuration = createConfiguration(args, 1);
        new JbpmSchema(configuration).dropSchema();
      } else if ("clean".equalsIgnoreCase(cmd)) {
        Configuration configuration = createConfiguration(args, 1);
        new JbpmSchema(configuration).cleanSchema();
      } else if ("scripts".equalsIgnoreCase(cmd)) {
        Configuration configuration = createConfiguration(args, 3);
        new JbpmSchema(configuration).saveSqlScripts(args[1], args[2]);
      }

    } catch (IllegalArgumentException e) {
      System.err.println("syntax: JbpmSchema create [<hibernate.cfg.xml> [<hibernate.properties>]]");
      System.err.println("syntax: JbpmSchema drop [<hibernate.cfg.xml> [<hibernate.properties>]]");
      System.err.println("syntax: JbpmSchema clean [<hibernate.cfg.xml> [<hibernate.properties>]]");
      System.err.println("syntax: JbpmSchema scripts <dir> <prefix> [<hibernate.cfg.xml> [<hibernate.properties>]]");
    } catch (Exception e) {
      e.printStackTrace();
      throw new JbpmException(e);
    }
  }
 
  static Configuration createConfiguration(String[] args, int index) {
    String hibernateCfgXml = (args.length>index ? args[index] : "hibernate.cfg.xml");
    String hibernateProperties = (args.length>(index+1) ? args[index+1] : null);
   
    Configuration configuration = new Configuration();
    configuration.configure(new File(hibernateCfgXml));
    if (hibernateProperties!=null) {
      try {
        Properties properties = new Properties();
        InputStream inputStream = new FileInputStream(hibernateProperties);
        properties.load(inputStream);
        configuration.setProperties(properties);
      } catch (Exception e) {
        e.printStackTrace();
        throw new JbpmException("couldn't load hibernate configuration", e);
      }
    }
   
    return configuration;
  }

  void saveSqlScript(String fileName, String[] sql) throws FileNotFoundException {
    FileOutputStream fileOutputStream = new FileOutputStream(fileName);
    try {
      PrintStream printStream = new PrintStream(fileOutputStream);
      for (int i=0; i<sql.length; i++) {
        printStream.println(sql[i]+getSqlDelimiter());
      }
    } finally {
      try {
        fileOutputStream.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

  public void execute(String[] sqls) {
    String sql = null;
    String showSqlText = properties.getProperty("hibernate.show_sql");
    boolean showSql = ("true".equalsIgnoreCase(showSqlText));

    try {
      createConnection();
      statement = connection.createStatement();
     
      for (int i=0; i<sqls.length; i++) {
        sql = sqls[i];
       
        if (showSql) log.debug(sql);
        statement.executeUpdate(sql);
      }
   
    } catch (SQLException e) {
      e.printStackTrace();
      throw new JbpmException("couldn't execute sql '"+sql+"'", e);
    } finally {
      closeConnection();
    }
  }

  void closeConnection() {
    try {
      if (statement!=null) statement.close();
      if (connection!=null) {
        JDBCExceptionReporter.logWarnings( connection.getWarnings() );
        connection.clearWarnings();
        connectionProvider.closeConnection(connection);
        connectionProvider.close();
      }
    }
    catch(Exception e) {
      System.err.println( "Could not close connection" );
      e.printStackTrace();
    }
  }

  void createConnection() throws SQLException {
    connectionProvider = ConnectionProviderFactory.newConnectionProvider(properties);
    connection = connectionProvider.getConnection();
    if ( !connection.getAutoCommit() ) {
      connection.commit();
      connection.setAutoCommit(true);
    }
  }

  public Properties getProperties() {
    return properties;
  }

  // sql delimiter ////////////////////////////////////////////////////////////
 
  static String sqlDelimiter = null;
  synchronized String getSqlDelimiter() {
    if (sqlDelimiter==null) {
      sqlDelimiter = properties.getProperty("jbpm.sql.delimiter", ";");
    }
    return sqlDelimiter;
  }

  // logger ///////////////////////////////////////////////////////////////////

  private static final Log log = LogFactory.getLog(JbpmSchema.class);
}
TOP

Related Classes of org.jbpm.db.JbpmSchema

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.