Package org.jboss.dashboard.database

Source Code of org.jboss.dashboard.database.DatabaseAutoSynchronizer

/**
* Copyright (C) 2012 JBoss Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.dashboard.database;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.dashboard.Application;
import org.jboss.dashboard.commons.io.DirectoriesScanner;
import org.jboss.dashboard.database.hibernate.HibernateInitializer;
import org.jboss.dashboard.annotation.config.Config;
import org.jboss.dashboard.database.hibernate.HibernateTxFragment;
import org.apache.commons.lang.ArrayUtils;
import org.hibernate.Session;
import org.hibernate.jdbc.Work;
import org.jboss.dashboard.error.ErrorManager;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.io.*;
import java.sql.*;
import java.util.*;

/**
* This component manages the database creation.
*/
@ApplicationScoped
public class DatabaseAutoSynchronizer {

    private static transient Log log = LogFactory.getLog(DatabaseAutoSynchronizer.class.getName());

    @Inject @Config("sql")
    protected String databaseConfigDir;

    @Inject @Config("dashb_installed_module")
    protected String installedModulesTable;

    @Inject @Config("oracle, mysql, postgres, sqlserver, h2")
    protected String[] supportedDatabases;

    @Inject @Config("delimiter //, //, , delimiter ;, GO")
    protected String[] excludedScriptStatements;

    @Inject @Config("-- CUSTOM_DELIMITER")
    protected String customDelimiter;

    @Inject @Config("-- ENABLE_CUSTOM_DELIMITER")
    protected String customDelimiterEnabler;

    public void synchronize(HibernateInitializer hibernateInitializer) throws Exception {
        String databaseName = hibernateInitializer.getDatabaseName();
        if (isCurrentDatabaseSupported(databaseName)) {
            boolean tableExists = existsModulesTable(databaseName);
            if (!tableExists) {
                createDatabase(databaseName);
            }
        }
    }

    protected void createDatabase(String databaseName) throws Exception {
        // Search in the classpath for the SQL files for the given database.
        String sqlDir = Application.lookup().getBaseCfgDirectory() + File.separator + databaseConfigDir;
        Map<String, File> sqlFileMap = new HashMap<String, File>();
        DirectoriesScanner scanner = new DirectoriesScanner("sql");
        File[] sqlFiles = scanner.findFiles(new File(sqlDir));
        for (File sqlFile : sqlFiles) {
            // The file name must start with an ordinal which indicates the order of execution and finish with the databaseName.
            if (sqlFile.getName().endsWith(databaseName + ".sql") && Character.isDigit(sqlFile.getName().charAt(0))) {
                sqlFileMap.put(sqlFile.getName(), sqlFile);
            }
        }

        // Sort by name and run the SQL files encountered.
        List<String> sqlFileNames = new ArrayList<String>(sqlFileMap.keySet());
        Collections.sort(sqlFileNames);
        for (String sqlFileName : sqlFileNames) {
            File sqlFile = sqlFileMap.get(sqlFileName);
            runSQLFile(sqlFile);
        }
    }

    protected void runSQLFile(File f) throws Exception {
        if (f.exists() && f.isFile()) {
            log.warn("Running file " + f.getName());
            BufferedReader reader = new BufferedReader(new FileReader(f));
            StringBuffer sb = new StringBuffer();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line).append("\n");
            }
            runDDL(sb.toString());
        }
    }

    protected void runDDL(final String ddl) throws Exception {
        String separator = ";";
        if (ddl.startsWith(customDelimiterEnabler)) separator = customDelimiter;
        String[] statements = splitString(ddl, separator);
        for (int i = 0; i < statements.length; i++) {
            final String ddlStatement = removeComments(statements[i]);
            if (ArrayUtils.contains(excludedScriptStatements, ddlStatement)) {
                continue;
            }

            if (log.isDebugEnabled()) log.debug("Running statement: " + ddlStatement);
            new HibernateTxFragment() {
            protected void txFragment(Session session) throws Exception {
                Work w = new Work() {
                public void execute(Connection connection) throws SQLException {
                    Statement statement = null;
                    try {
                        statement = connection.createStatement();
                        statement.execute(ddlStatement);
                    } catch (Exception e) {
                        Throwable root = ErrorManager.lookup().getRootCause(e);
                        log.error("Error executing " + ddlStatement + ": " + root.getMessage());
                    } finally {
                        if (statement != null) {
                            statement.close();
                        }
                    }
                }};
                session.doWork(w);
                session.flush();
            }}.execute();
        }
    }

    private String[] splitString(String str, String delims) {
        if (str == null) {
            return null;
        } else if (str.equals("") || delims == null || delims.length() == 0) {
            return new String[]{str};
        }
        String[] s;
        Vector v = new Vector();
        int pos = 0;
        int newpos = str.indexOf(delims, pos);
        while (newpos != -1) {
            v.addElement(str.substring(pos, newpos));
            pos = newpos + delims.length();
            newpos = str.indexOf(delims, pos);
        }
        v.addElement(str.substring(pos));
        s = new String[v.size()];
        for (int i = 0, cnt = s.length; i < cnt; i++) {
            s[i] = ((String) v.elementAt(i)).trim();
        }
        return s;
    }

    protected String removeComments(String ddlStatement) {
        StringBuffer sb = new StringBuffer();
        BufferedReader strreader = new BufferedReader(new StringReader(ddlStatement));
        String line = null;
        try {
            while ((line = strreader.readLine()) != null) {
                if (line.trim().startsWith("--")) continue;
                sb.append(line).append("\n");
            }
        } catch (IOException e) {
            log.error("Error: ", e);
        }
        return sb.toString().trim();
    }

    protected boolean existsModulesTable(final String databaseName) throws Exception {
        final boolean[] returnValue = {false};
        new HibernateTxFragment(true) {
        protected void txFragment(Session session) throws Exception {
            Work w = new Work() {
            public void execute(Connection connection) throws SQLException {
                DatabaseMetaData metaData = connection.getMetaData();
                ResultSet resultLowcase = metaData.getTables(null, null, installedModulesTable.toLowerCase(), null);
                ResultSet resultUppercase = metaData.getTables(null, null, installedModulesTable.toUpperCase(), null);
                returnValue[0] = resultLowcase.next() || resultUppercase.next();
            }};
            session.doWork(w);
        }}.execute();
        return returnValue[0];
    }

    public boolean isCurrentDatabaseSupported(String databaseName) {
        for (int i = 0; supportedDatabases != null && i < supportedDatabases.length; i++) {
            if (databaseName.equals(supportedDatabases[i])) return true;
        }
        return false;
    }
}
TOP

Related Classes of org.jboss.dashboard.database.DatabaseAutoSynchronizer

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.