/* * Copyright 2011 Brian Rosenberger (Brutex Network) * * 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 net.brutex.xservices.util; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.quartz.utils.ConnectionProvider; /** * @author Brian Rosenberger * */ public class BrutexHSQLQuartzConnectionProvider implements ConnectionProvider { private Connection conn = null; private final Logger logger = Logger.getLogger(this.getClass().getCanonicalName()); public Connection getConnection() throws SQLException { if( conn!= null ) { // Todo: && conn.conn.isValid(5)) { logger.debug("Checking tables on pre-exisiting database connection."); checkTables(); return conn; } try { // Class.forName("org.hsqldb.jdbc.JDBCDriver" ); Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); } catch (Exception e) { logger.fatal("Failed to load Derby JDBC driver."); e.printStackTrace(); return null; } if(isConnected(false)) { checkTables(); } else { return null; } return conn; } public void shutdown() throws SQLException { try { // Class.forName("org.hsqldb.jdbc.JDBCDriver" ); Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); } catch (Exception e) { System.err.println("ERROR: failed to load Derby JDBC driver."); e.printStackTrace(); return; } String t = this.getClass().getClassLoader().getResource("/").toString() .substring(6); t += "../data/db"; System.out.println("Shut down embedded database now."); Connection c = DriverManager.getConnection("jdbc:derby:" + t + ";shutdown=true;"); } private synchronized void recursiveDelete(File dbDir) { File[] files = dbDir.listFiles(); for (int i = 0; i < files.length; i++) { if (files[i].isFile()) { files[i].delete(); } else { recursiveDelete(files[i]); files[i].delete(); } } dbDir.delete(); } private synchronized void checkTables() throws SQLException { logger.debug("Checking QUARTZ database schema."); if(!isConnected(false)) { logger.error("Failed to validate QUARTZ database schema."); return; } List ddl_list = new ArrayList(11); ddl_list.add("QRTZ_JOB_DETAILS"); ddl_list.add("QRTZ_TRIGGERS"); ddl_list.add("QRTZ_SIMPLE_TRIGGERS"); ddl_list.add("QRTZ_CRON_TRIGGERS"); ddl_list.add("QRTZ_SIMPROP_TRIGGERS"); ddl_list.add("QRTZ_BLOB_TRIGGERS"); ddl_list.add("QRTZ_CALENDARS"); ddl_list.add("QRTZ_PAUSED_TRIGGER_GRPS"); ddl_list.add("QRTZ_FIRED_TRIGGERS"); ddl_list.add("QRTZ_SCHEDULER_STATE"); ddl_list.add("QRTZ_LOCKS"); String ddl = this.getClass().getClassLoader().getResource("/").toString() .substring(6)+ "../data/"; DatabaseMetaData dmd = conn.getMetaData(); for (String tbl : ddl_list) { ResultSet rs = dmd.getTables(null, "APP", tbl, null); if (!rs.next()) { logger.log(Level.INFO, "Adding DDL for table "+ tbl); Statement st = conn.createStatement(); File ddlFile = new File(ddl + tbl + ".ddl"); String create = ""; try { BufferedReader r = new BufferedReader(new FileReader(ddlFile)); while (r.ready()) { create += r.readLine() + "\n"; } create.trim(); if( st.execute(create)) { logger.log(Level.INFO, "Table " + tbl + " created."); } } catch (FileNotFoundException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } catch (SQLException ex) { logger.log(Level.ERROR, "Error executing statement "+ create ); System.out.println(ex.getMessage()); } } else { logger.trace("Table "+tbl+" exists."); } } } private synchronized boolean isConnected(boolean fail) throws SQLException { if(conn!=null ) { // Todo: && conn.conn.isValid(5)) {) { return true; } else { String t = this.getClass().getClassLoader().getResource("/").toString().substring(6); // WEB-INF/classes t += "../data/db"; logger.debug("Database directory is set to '" + t + "'"); try { this.conn = DriverManager.getConnection("jdbc:derby:" + t + ";create=true;"); } catch (SQLException ex) { logger.error(ex.getMessage(), ex); if(!fail) { logger.warn("Deleting database directory."); recursiveDelete(new File(t)); logger.warn("Retrying to connect to database."); return isConnected(true); } else { return false; } } } return false; } @Override public void initialize() throws SQLException { // TODO Auto-generated method stub } }