Package org.jbpm.db.compatibility

Source Code of org.jbpm.db.compatibility.JbpmSchemaUpdate

package org.jbpm.db.compatibility;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.ArrayList;
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.NamingStrategy;
import org.hibernate.cfg.Settings;
import org.hibernate.connection.ConnectionProvider;
import org.hibernate.dialect.Dialect;
import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
import org.hibernate.util.JDBCExceptionReporter;
import org.hibernate.util.PropertiesHelper;
import org.hibernate.util.ReflectHelper;

/**
* This is a modified version of the hibernate tools schema update. The modification is to support
* saving of the update script to a file.
*
* @author Christoph Sturm
* @author Koen Aers
*/
public class JbpmSchemaUpdate {

  private Configuration configuration;
  private Settings settings;

  private File outputFile;
  private String delimiter;

  private final List<Exception> exceptions = new ArrayList<Exception>();

  private static final Log log = LogFactory.getLog(JbpmSchemaUpdate.class);

  public JbpmSchemaUpdate(Configuration configuration) {
    this(configuration, configuration.getProperties());
  }

  public JbpmSchemaUpdate(Configuration configuration, Properties properties) {
    Properties copy = (Properties) properties.clone();
    PropertiesHelper.resolvePlaceHolders(copy);
    this.configuration = configuration;
    this.settings = configuration.buildSettings(copy);
  }

  public JbpmSchemaUpdate(Configuration configuration, Settings settings) {
    this.configuration = configuration;
    this.settings = settings;
  }

  /**
   * Set an output file. The generated script will be written to this file.
   */
  public void setOutputFile(File outputFile) {
    this.outputFile = outputFile;
  }

  public void setDelimiter(String delimiter) {
    this.delimiter = delimiter;
  }

  public static void main(String[] args) {
    try {
      Configuration cfg = new Configuration();

      boolean script = true;
      boolean doUpdate = true;
      String propFile = null;
      File out = null;

      for (int i = 0; i < args.length; i++) {
        if (args[i].startsWith("--")) {
          if (args[i].equals("--quiet")) {
            script = false;
          }
          else if (args[i].startsWith("--properties=")) {
            propFile = args[i].substring(13);
          }
          else if (args[i].startsWith("--config=")) {
            cfg.configure(args[i].substring(9));
          }
          else if (args[i].startsWith("--text")) {
            doUpdate = false;
          }
          else if (args[i].startsWith("--naming=")) {
            Class<?> clazz = ReflectHelper.classForName(args[i].substring(9));
            cfg.setNamingStrategy(clazz.asSubclass(NamingStrategy.class).newInstance());
          }
          else if (args[i].startsWith("--output=")) {
            out = new File(args[i].substring(9));
          }
        }
        else {
          cfg.addFile(args[i]);
        }
      }

      if (propFile != null) {
        InputStream inStream = new FileInputStream(propFile);
        try {
          Properties props = new Properties();
          props.load(inStream);
          cfg.addProperties(props);
        }
        finally {
          inStream.close();
        }
      }

      new JbpmSchemaUpdate(cfg).execute(script, doUpdate, out);
    }
    catch (Exception e) {
      log.error("Error running schema update", e);
    }
  }

  /**
   * Executes the schema update tool.
   *
   * @param printScript print DDL statements to the console
   * @param doUpdate post DDL statements to the database
   * @param outputFile write DDL statements to this file, can be <code>null</code>
   */
  public void execute(boolean printScript, boolean doUpdate, File outputFile) {
    setOutputFile(outputFile);
    execute(printScript, doUpdate);
  }

  /**
   * Executes the schema update tool.
   *
   * @param printScript print DDL statements to the console
   * @param doUpdate post DDL statements to the database
   */
  public void execute(boolean printScript, boolean doUpdate) {
    log.info("running schema update");
    exceptions.clear();
    try {
      String[] script = generateScript(doUpdate);
      if (printScript) {
        printScript(script);
      }
      if (outputFile != null) {
        writeFile(script);
      }
    }
    catch (SQLException e) {
      exceptions.add(e);
      log.error("database connection failed", e);
    }
    catch (IOException e) {
      exceptions.add(e);
      log.error("could not write file: " + outputFile, e);
    }
  }

  private String[] generateScript(boolean doUpdate) throws SQLException {
    ConnectionProvider connectionProvider = settings.getConnectionProvider();
    try {
      log.info("acquiring a connection");
      Connection connection = connectionProvider.getConnection();
      try {
        if (!connection.getAutoCommit()) {
          connection.commit();
          connection.setAutoCommit(true);
        }
        log.info("fetching database metadata");
        Dialect dialect = settings.getDialect();
        DatabaseMetadata meta = new DatabaseMetadata(connection, dialect);

        log.info("generating schema update script");
        String[] script = configuration.generateSchemaUpdateScript(dialect, meta);

        if (doUpdate) {
          log.info("updating schema");
          doUpdate(script, connection);
          log.info("schema update complete");
        }

        return script;
      }
      finally {
        JDBCExceptionReporter.logAndClearWarnings(connection);
        connectionProvider.closeConnection(connection);
      }
    }
    finally {
      connectionProvider.close();
    }
  }

  private void doUpdate(String[] script, Connection connection) throws SQLException {
    Statement statement = connection.createStatement();
    try {
      for (int i = 0; i < script.length; i++) {
        String sql = script[i];
        log.debug(sql);
        try {
          statement.execute(sql);
          SQLWarning warning = statement.getWarnings();
          if (warning != null) {
            JDBCExceptionReporter.logWarnings(warning);
          }
        }
        catch (SQLException e) {
          exceptions.add(e);
          log.error("unsuccessful: " + sql);
          log.error(e.getMessage());
        }
      }
    }
    finally {
      statement.close();
    }
  }

  private void printScript(String[] script) {
    for (int i = 0; i < script.length; i++) {
      System.out.println(script[i]);
    }
  }

  private void writeFile(String[] script) throws IOException {
    Writer writer = new FileWriter(outputFile);
    String lineSeparator = System.getProperty("line.separator");
    try {
      for (int i = 0; i < script.length; i++) {
        writer.write(script[i]);
        if (delimiter != null)
          writer.write(delimiter);
        writer.write(lineSeparator);
      }
    }
    finally {
      writer.close();
    }
  }

  /**
   * Returns a List of all Exceptions that occurred during the export.
   *
   * @return the exceptions that occurred during the export
   */
  public List<Exception> getExceptions() {
    return exceptions;
  }
}
TOP

Related Classes of org.jbpm.db.compatibility.JbpmSchemaUpdate

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.