/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.apache.ode.il.dbutil; import java.io.File; import javax.naming.InitialContext; import javax.sql.DataSource; import javax.transaction.TransactionManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.ode.dao.bpel.BpelDAOConnectionFactory; import org.apache.ode.dao.scheduler.SchedulerDAOConnectionFactory; import org.apache.ode.dao.store.ConfStoreDAOConnectionFactory; import org.apache.ode.il.config.OdeConfigProperties; import org.apache.ode.utils.LoggingInterceptor; /** * Does the dirty work of setting up / obtaining a DataSource based on the configuration in the {@link OdeConfigProperties} object. * */ public class Database { private static final Log __log = LogFactory.getLog(Database.class); private static final Log __logSql = LogFactory.getLog("org.apache.ode.sql"); private static final Messages __msgs = Messages.getMessages(Messages.class); private OdeConfigProperties _odeConfig; private boolean _started; private DatabaseConnectionManager _connectionManager; private TransactionManager _txm; private DataSource _datasource; private File _workRoot; private boolean _needShutdown; private EmbeddedDatabase _embeddedDB; public Database(OdeConfigProperties props) { if (props == null) throw new NullPointerException("Must provide a configuration."); _odeConfig = props; } public void setWorkRoot(File workRoot) { _workRoot = workRoot; } public void setTransactionManager(TransactionManager txm) { _txm = txm; } public synchronized void start() throws DatabaseConfigException { if (_started) return; _needShutdown = false; _datasource = null; _connectionManager = null; initDataSource(); _started = true; } public synchronized void shutdown() { if (!_started) { return; } if (_connectionManager != null) { try { __log.debug("Stopping connection manager"); _connectionManager.shutdown(); } catch (Throwable t) { __log.warn("Exception while stopping connection manager: " + t.getMessage()); } finally { _connectionManager = null; } } if (_needShutdown) { __log.debug("shutting down database."); _embeddedDB.shutdown(); } _needShutdown = false; _datasource = null; _started = false; } public DataSource getDataSource() { DataSource ds = __logSql.isDebugEnabled() ? LoggingInterceptor.createLoggingDS(_datasource, __logSql) : _datasource; return ds; } private void initDataSource() throws DatabaseConfigException { switch (_odeConfig.getDbMode()) { case EXTERNAL: initExternalDb(); break; case EMBEDDED: initEmbeddedDb(); break; case INTERNAL: initInternalDb(); break; default: break; } } private void initExternalDb() throws DatabaseConfigException { try { _datasource = (DataSource) lookupInJndi(_odeConfig.getDbDataSource()); __log.debug(__msgs.msgOdeUsingExternalDb(_odeConfig.getDbDataSource())); } catch (Exception ex) { String msg = __msgs.msgOdeInitExternalDbFailed(_odeConfig.getDbDataSource()); __log.error(msg, ex); throw new DatabaseConfigException(msg, ex); } } private void initInternalDb() throws DatabaseConfigException { __log.debug(__msgs.msgOdeUsingInternalDb(_odeConfig.getDbIntenralJdbcUrl(), _odeConfig.getDbInternalJdbcDriverClass())); initInternalDb(_odeConfig.getDbIntenralJdbcUrl(), _odeConfig.getDbInternalJdbcDriverClass(), _odeConfig.getDbInternalUserName(), _odeConfig.getDbInternalPassword()); } private void initInternalDb(String url, String driverClass, String username,String password) throws DatabaseConfigException { _connectionManager = new DatabaseConnectionManager(_txm,_odeConfig); _connectionManager.init(url, driverClass, username, password); _datasource = _connectionManager.getDataSource(); } /** * Initialize embedded (DERBY) database. */ private void initEmbeddedDb() throws DatabaseConfigException { switch (_odeConfig.getDbEmbeddedType()) { case H2: _embeddedDB = new H2Database(); break; default: _embeddedDB = new H2Database(); } _embeddedDB.init(_workRoot,_odeConfig,_txm); _datasource = _embeddedDB.getDataSource(); _needShutdown = true; } @SuppressWarnings("unchecked") private <T> T lookupInJndi(String objName) throws Exception { ClassLoader old = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); try { InitialContext ctx = null; try { ctx = new InitialContext(); return (T) ctx.lookup(objName); } finally { if (ctx != null) try { ctx.close(); } catch (Exception ex1) { __log.error("Error closing JNDI connection.", ex1); } } } finally { Thread.currentThread().setContextClassLoader(old); } } public BpelDAOConnectionFactory createDaoCF() throws DatabaseConfigException { String pClassName = _odeConfig.getDAOConnectionFactory(); __log.debug(__msgs.msgOdeUsingDAOImpl(pClassName)); ClassLoader old = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); BpelDAOConnectionFactory cf; try { try { cf = (BpelDAOConnectionFactory) Class.forName(pClassName).newInstance(); } catch (Exception ex) { String errmsg = __msgs.msgDAOInstantiationFailed(pClassName); __log.error(errmsg, ex); throw new DatabaseConfigException(errmsg, ex); } cf.init(_odeConfig.getProperties(),_txm,getDataSource()); return cf; } finally { Thread.currentThread().setContextClassLoader(old); } } public ConfStoreDAOConnectionFactory createDaoStoreCF() throws DatabaseConfigException { String pClassName = _odeConfig.getDAOConfStoreConnectionFactory(); __log.debug(__msgs.msgOdeUsingDAOImpl(pClassName)); ClassLoader old = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); ConfStoreDAOConnectionFactory cf; try { try { cf = (ConfStoreDAOConnectionFactory) Class.forName(pClassName).newInstance(); } catch (Exception ex) { String errmsg = __msgs.msgDAOInstantiationFailed(pClassName); __log.error(errmsg, ex); throw new DatabaseConfigException(errmsg, ex); } cf.init(_odeConfig.getProperties(),_txm,getDataSource()); return cf; } finally { Thread.currentThread().setContextClassLoader(old); } } public SchedulerDAOConnectionFactory createDaoSchedulerCF() throws DatabaseConfigException { String pClassName = _odeConfig.getDAOConfScheduleConnectionFactory(); __log.debug(__msgs.msgOdeUsingDAOImpl(pClassName)); ClassLoader old = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); SchedulerDAOConnectionFactory sdcf; try { try { sdcf = (SchedulerDAOConnectionFactory) Class.forName(pClassName).newInstance(); } catch (Exception ex) { String errmsg = __msgs.msgDAOInstantiationFailed(pClassName); __log.error(errmsg, ex); throw new DatabaseConfigException(errmsg, ex); } sdcf.init(_odeConfig.getProperties(), _txm, getDataSource()); return sdcf; } finally { Thread.currentThread().setContextClassLoader(old); } } }