/** * Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * 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.wso2.carbon.bpmn.core.db; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.bpmn.core.BPMNConstants; import org.wso2.carbon.bpmn.core.exception.BPMNMetaDataTableCreationException; import org.wso2.carbon.bpmn.core.exception.DatabaseConfigurationException; import org.wso2.carbon.bpmn.core.utils.BPMNDatabaseCreator; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; /** * manages the activiti engine database. */ public class Database { private static final Log log = LogFactory.getLog(Database.class); private String jndiDataSourceName; private DataSource dataSource; private boolean started; /** * Obtains the DataSource object of activiti database * * @return The BPMN DataSource.. */ public synchronized DataSource getDataSource() { if (this.dataSource == null) { throw new RuntimeException("Activiti Engine Database is not properly initialised!"); } return this.dataSource; } /** * Constructor for initializing the database class which connects and manages the activiti engine database * @param jndiDataSourceName activiti's JNDI datasource name */ public Database(String jndiDataSourceName) { this.jndiDataSourceName = jndiDataSourceName; } /** * Database initialization logic. * * @throws DatabaseConfigurationException Error in activiti db configuration * @throws BPMNMetaDataTableCreationException Error on creating BPMNMetaDataTable inside activiti DB */ public synchronized void init() throws DatabaseConfigurationException, BPMNMetaDataTableCreationException { this.dataSource = null; initDataSource(); createActivitiMetaDataTable(); started = true; } /** * during the start up of the server this method will create BPS_BPMN_DEPLOYMENT_METADATA table * if it doesn't exist in the activiti database. * * @throws org.wso2.carbon.bpmn.core.exception.BPMNMetaDataTableCreationException */ private void createActivitiMetaDataTable() throws BPMNMetaDataTableCreationException { BPMNDatabaseCreator bpmnDatabaseCreator = new BPMNDatabaseCreator(getDataSource()); String bpmnDeploymentMetaDataQuery = "SELECT * FROM " + BPMNConstants.BPS_BPMN_DEPLOYMENT_METADATA_TABLE; if (!bpmnDatabaseCreator.isDatabaseStructureCreated(bpmnDeploymentMetaDataQuery)) { try { bpmnDatabaseCreator.createRegistryDatabase(); } catch (Exception e) { String errMsg = "Error creating BPS_BPMN_DEPLOYMENT_METADATA table"; throw new BPMNMetaDataTableCreationException(errMsg, e); } } else { if (log.isDebugEnabled()) { log.debug("BPS_BPMN_DEPLOYMENT_METADATA table already exists. Using the old table."); } } } /** * Shut down logic for the Database related resources. */ public synchronized void shutdown() { if (!started) { return; } this.dataSource = null; this.started = false; } /** * Initializes the data source * * @throws DatabaseConfigurationException - throws when database configuration failed */ private void initDataSource() throws DatabaseConfigurationException { initExternalDb(); } /** * Initializes the activiti db * * @throws DatabaseConfigurationException - throws when database configuration failed */ private void initExternalDb() throws DatabaseConfigurationException { try { this.dataSource = lookupInJndi(jndiDataSourceName); if (log.isDebugEnabled()) { log.debug("BPMN Activiti initialization using external DataSource " + jndiDataSourceName); } } catch (NamingException e) { String errorMsg = "Failed to resolved external DataSource at " + jndiDataSourceName; throw new DatabaseConfigurationException(errorMsg, e); } } /** * Performs lookup of JNDI datasource name * * @param objName Lookup jndi data source name * @param <T> Lookup object type * @return DataSource object * @throws NamingException Throws exception when lookup naming failed */ @SuppressWarnings("unchecked") private <T> T lookupInJndi(String objName) throws NamingException { ClassLoader old = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); InitialContext ctx = null; try { try { ctx = new InitialContext(); return (T) ctx.lookup(objName); } finally { if (ctx != null) { try { ctx.close(); } catch (NamingException ex1) { log.error("Error closing JNDI connection.", ex1); } } } } finally { Thread.currentThread().setContextClassLoader(old); } } }