All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.efaps.init.StartupDatabaseConnection Maven / Gradle / Ivy

/*
 * Copyright 2003 - 2012 The eFaps Team
 *
 * 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.
 *
 * Revision:        $Rev: 7483 $
 * Last Changed:    $Date: 2012-05-11 11:57:38 -0500 (Fri, 11 May 2012) $
 * Last Changed By: $Author: [email protected] $
 */

package org.efaps.init;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.sql.DataSource;
import javax.transaction.TransactionManager;

import org.efaps.db.databases.AbstractDatabase;
import org.efaps.db.transaction.DelegatingUserTransaction;
import org.efaps.util.DateTimeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Initialize the database connection for an eFaps instance.
 *
 * @author The eFaps Team
 * @version $Id: StartupDatabaseConnection.java 7483 2012-05-11 16:57:38Z [email protected] $
 */
public final class StartupDatabaseConnection
    implements INamingBinds
{

    /**
     * Logging instance used to give logging information of this class.
     */
    private static final Logger LOG = LoggerFactory.getLogger(DateTimeUtil.class);

    /**
     * Name of the environment variable to define the bootstrap path.
     */
    private static final String ENV_PATH = "EFAPS_BOOTSTRAP_PATH";

    /**
     * Name of the environment variable to define the name of the bootstrap file.
     */
    private static final String ENV_FILE = "EFAPS_BOOTSTRAP_FILE";

    /**
     * Name of the property for the database type class.
     */
    private static final String PROP_DBTYPE_CLASS = "org.efaps.db.type";

    /**
     * Name of the property for the database factory class.
     */
    private static final String PROP_DBFACTORY_CLASS = "org.efaps.db.factory";

    /**
     * Name of the property for the database connection.
     */
    private static final String PROP_DBCONNECTION = "org.efaps.db.connection";

    /**
     * Name of the property for the transaction manager class.
     */
    private static final String PROP_TM_CLASS = "org.efaps.transaction.manager";

    /**
     * Name of the property for the timeout of the transaction manager.
     */
    private static final String PROP_CONFIGPROP = "org.efaps.configuration.properties";

    /**
     * Name of the default bootstrap path in the user home directory.
     */
    private static final String DEFAULT_BOOTSTRAP_PATH = ".efaps/bootstrap";

    /**
     * Name of the default bootstrap file.
     */
    private static final String DEFAULT_BOOTSTRAP_FILE = "default.efaps.xml";

    /**
     * Constructor is hidden to prevent instantiation.
     */
    private StartupDatabaseConnection()
    {
    }

    /**
     * Startups the eFaps kernel with the bootstrap configuration defined as shell variable. If the bootstrap
     * configuration is not defined as shell variables, the default bootstrap definition is used.
     *
     * @throws StartupException if startup failed
     * @see #startup(String, String)
     */
    public static void startup()
        throws StartupException
    {
        StartupDatabaseConnection.startup(null, null);
    }

    /**
     * Startups the eFaps kernel with the bootstrap path defined as shell variable (or if not defined the default
     * bootstrap path is used).
     *
     * @param _bootstrapFile name of the bootstrap file (without file extension); null means the the name
     *            of the bootstrap is not predefined
     * @throws StartupException if startup failed
     * @see #startup(String, String)
     */
    public static void startup(final String _bootstrapFile)
        throws StartupException
    {
        StartupDatabaseConnection.startup(null, _bootstrapFile);
    }

    /**
     * 

* Startups he kernel depending on a bootstrap definition. *

* *

* Following rules applies for the bootstrap path: *

    *
  • if _bootstrapPath is not null, _bootstrapPath is used as bootstrap * path
  • *
  • if in the system environment the shell variable {@link #ENV_PATH} is defined, this value of this shell * variable is used
  • *
  • in all other cases {@link #DEFAULT_BOOTSTRAP_PATH} is used
  • *
*

* *

* Following rules applies for the bootstrap name: *

    *
  • if _bootstrapFile is not null, _bootstrapFile is used as bootstrap * name
  • *
  • if in the system environment the shell variable {@link #ENV_FILE} is defined, this value of this shell * variable is used
  • *
  • in all other cases {@link #DEFAULT_BOOTSTRAP_FILE} is used
  • *
*

* *

* After the used bootstrap file is identified, this file is opened and the keys are read and evaluated. *

* * @param _bootstrapPath path where the bootstrap files are located; null means that the path is not * predefined * @param _bootstrapFile name of the bootstrap file (without file extension); null means the the name * of the bootstrap is not predefined * @throws StartupException if startup failed */ public static void startup(final String _bootstrapPath, final String _bootstrapFile) throws StartupException { // evaluate bootstrap path final File bsPath; if (_bootstrapPath != null) { bsPath = new File(_bootstrapPath); } else { final String envPath = System.getenv(StartupDatabaseConnection.ENV_PATH); if (envPath != null) { bsPath = new File(envPath); } else { bsPath = new File(System.getProperty("user.home"), StartupDatabaseConnection.DEFAULT_BOOTSTRAP_PATH); } } // evaluate bootstrap file final String bsFile; File bootstrap = null; if (_bootstrapFile != null) { bsFile = _bootstrapFile; } else { final String envFile = System.getenv(StartupDatabaseConnection.ENV_FILE); if (envFile != null) { bsFile = envFile; } else { bsFile = StartupDatabaseConnection.DEFAULT_BOOTSTRAP_FILE; } } bootstrap = new File(bsFile); if (bootstrap == null || !bootstrap.exists()) { bootstrap = new File(bsPath, bsFile); } // read bootstrap file final Properties props = new Properties(); try { props.loadFromXML(new FileInputStream(bootstrap)); } catch (final FileNotFoundException e) { throw new StartupException("bootstrap file " + bootstrap + " not found", e); } catch (final IOException e) { throw new StartupException("bootstrap file " + bootstrap + " could not be read", e); } // and startup final Map eFapsProps; if (props.containsKey(StartupDatabaseConnection.PROP_CONFIGPROP)) { eFapsProps = StartupDatabaseConnection.convertToMap(props .getProperty(StartupDatabaseConnection.PROP_CONFIGPROP)); } else { eFapsProps = new HashMap(); } StartupDatabaseConnection.startup(props.getProperty(StartupDatabaseConnection.PROP_DBTYPE_CLASS), props.getProperty(StartupDatabaseConnection.PROP_DBFACTORY_CLASS), props.getProperty(StartupDatabaseConnection.PROP_DBCONNECTION), props.getProperty(StartupDatabaseConnection.PROP_TM_CLASS), eFapsProps); } /** * Initialize the database information set for given parameter values. * * @param _classDBType class name of the database type * @param _classDSFactory class name of the SQL data source factory * @param _propConnection string with properties for the JDBC connection * @param _classTM class name of the transaction manager * @param _timeout timeout for the transaction manager in seconds, if null the default from the transaction manager * will be used * @throws StartupException if the database connection or transaction manager could not be initialized * @see StartupDatabaseConnection#startup(String, String, Map, String, Integer) * @see StartupDatabaseConnection#convertToMap(String) */ public static void startup(final String _classDBType, final String _classDSFactory, final String _propConnection, final String _classTM, final Map _eFapsProps) throws StartupException { StartupDatabaseConnection.startup(_classDBType, _classDSFactory, StartupDatabaseConnection.convertToMap(_propConnection), _classTM, _eFapsProps); } /** * Initialize the database information set for given parameter values. *
    *
  • configure the database type
  • *
  • initialize the SQL data source (JDBC connection to the database)
  • *
  • initialize transaction manager
  • *
* * @param _classDBType class name of the database type * @param _classDSFactory class name of the SQL data source factory * @param _propConnection map of properties for the JDBC connection * @param _classTM class name of the transaction manager * @param _timeout timeout for the transaction manager in seconds, if null the default from the transaction manager * will be used * @throws StartupException if the database connection or transaction manager could not be initialized * @see #configureDBType(Context, String) * @see #configureDataSource(Context, String, Map) * @see #configureTransactionManager(Context, String, Integer) */ public static void startup(final String _classDBType, final String _classDSFactory, final Map _propConnection, final String _classTM, final Map _eFapsProps) throws StartupException { if (StartupDatabaseConnection.LOG.isInfoEnabled()) { StartupDatabaseConnection.LOG.info("Initialise Database Connection"); } final Context compCtx; try { final InitialContext context = new InitialContext(); compCtx = (javax.naming.Context) context.lookup("java:comp"); } catch (final NamingException e) { throw new StartupException("Could not initialize JNDI", e); } StartupDatabaseConnection.configureEFapsProperties(compCtx, _eFapsProps); StartupDatabaseConnection.configureDBType(compCtx, _classDBType); StartupDatabaseConnection.configureDataSource(compCtx, _classDSFactory, _propConnection); StartupDatabaseConnection.configureTransactionManager(compCtx, _classTM); // and reset eFaps context (to be sure..) org.efaps.db.Context.reset(); } /** * Add the eFaps Properties to the JNDI binding. * @param _compCtx Java root naming context * @param _eFapsProps Properties to bind * @throws StartupException on error */ protected static void configureEFapsProperties(final Context _compCtx, final Map _eFapsProps) throws StartupException { try { Util.bind(_compCtx, "env/" + INamingBinds.RESOURCE_CONFIGPROPERTIES, _eFapsProps); } catch (final NamingException e) { throw new StartupException("could not bind eFaps Properties '" + _eFapsProps + "'", e); // CHECKSTYLE:OFF } catch (final Exception e) { // CHECKSTYLE:ON throw new StartupException("could not bind eFaps Properties '" + _eFapsProps + "'", e); } } /** * The class defined with parameter _classDSFactory initialized and bind to * {@link #RESOURCE_DATASOURCE}. The initialized class must implement interface {@link DataSource}. As JDBC * connection properties the map _propConneciton is used. * * @param _compCtx Java root naming context * @param _classDSFactory class name of the SQL data source factory * @param _propConnection map of properties for the JDBC connection * @throws StartupException on error */ protected static void configureDataSource(final Context _compCtx, final String _classDSFactory, final Map _propConnection) throws StartupException { final Reference ref = new Reference(DataSource.class.getName(), _classDSFactory, null); for (final Entry entry : _propConnection.entrySet()) { ref.add(new StringRefAddr(entry.getKey(), entry.getValue())); } try { Util.bind(_compCtx, "env/" + INamingBinds.RESOURCE_DATASOURCE, ref); } catch (final NamingException e) { throw new StartupException("could not bind JDBC pooling class '" + _classDSFactory + "'", e); // CHECKSTYLE:OFF } catch (final Exception e) { // CHECKSTYLE:ON throw new StartupException("coud not get object instance of factory '" + _classDSFactory + "'", e); } } /** * The class defined with parameter _classDBType initialized and bind to {@link #RESOURCE_DBTYPE}. The initialized * class must be extended from class {@link AbstractDatabase}. * * @param _compCtx Java root naming context * @param _classDBType class name of the database type * @throws StartupException if the database type class could not be found, initialized, accessed or bind to the * context */ protected static void configureDBType(final Context _compCtx, final String _classDBType) throws StartupException { try { final AbstractDatabase dbType = (AbstractDatabase) (Class.forName(_classDBType)).newInstance(); if (dbType == null) { throw new StartupException("could not initaliase database type '" + _classDBType + "'"); } else { Util.bind(_compCtx, "env/" + INamingBinds.RESOURCE_DBTYPE, dbType); } } catch (final ClassNotFoundException e) { throw new StartupException("could not found database description class '" + _classDBType + "'", e); } catch (final InstantiationException e) { throw new StartupException("could not initialise database description class '" + _classDBType + "'", e); } catch (final IllegalAccessException e) { throw new StartupException("could not access database description class '" + _classDBType + "'", e); } catch (final NamingException e) { throw new StartupException("could not bind database description class '" + _classDBType + "'", e); } } /** * The class defined with parameter _classTM initialized and bind to {@link #RESOURCE_TRANSMANAG}. The initialized * class must implement interface {@link TransactionManager}. * * @param _compCtx Java root naming context * @param _classTM class name of the transaction manager * @throws StartupException if the transaction manager class could not be found, initialized, accessed or bind to * the context */ protected static void configureTransactionManager(final Context _compCtx, final String _classTM) throws StartupException { try { final TransactionManager tm = (TransactionManager) (Class.forName(_classTM)).newInstance(); if (tm == null) { throw new StartupException("could not initaliase database type"); } else { Util.bind(_compCtx, "env/" + INamingBinds.RESOURCE_TRANSMANAG, tm); Util.bind(_compCtx, "env/" + INamingBinds.RESOURCE_USERTRANSACTION, new DelegatingUserTransaction(tm)); } } catch (final ClassNotFoundException e) { throw new StartupException("could not found transaction manager class '" + _classTM + "'", e); } catch (final InstantiationException e) { throw new StartupException("could not initialise transaction manager class '" + _classTM + "'", e); } catch (final IllegalAccessException e) { throw new StartupException("could not access transaction manager class '" + _classTM + "'", e); } catch (final NamingException e) { throw new StartupException("could not bind transaction manager class '" + _classTM + "'", e); } } /** *

* Separates all key / value pairs of given text string. *

*

* Evaluation algorithm:
* Separates the text by all found commas (only if in front of the comma is no back slash). This are the key / value * pairs. A key / value pair is separated by the first equal ('=') sign. *

* * @param _text text string to convert to a key / value map * @return Map of strings with all found key / value pairs */ protected static Map convertToMap(final String _text) { final Map properties = new HashMap(); // separated all key / value pairs final Pattern pattern = Pattern.compile("(([^\\\\,])|(\\\\,)|(\\\\))*"); final Matcher matcher = pattern.matcher(_text); while (matcher.find()) { final String group = matcher.group().trim(); if (group.length() > 0) { // separated key from value final int index = group.indexOf('='); final String key = (index > 0) ? group.substring(0, index).trim() : group.trim(); final String value = (index > 0) ? group.substring(index + 1).trim() : ""; properties.put(key, value); } } return properties; } /** * Shutdowns the connection to the database. * * @throws StartupException if shutdown failed */ public static void shutdown() throws StartupException { final Context compCtx; try { final InitialContext context = new InitialContext(); compCtx = (javax.naming.Context) context.lookup("java:comp"); } catch (final NamingException e) { throw new StartupException("Could not initialize JNDI", e); } try { Util.unbind(compCtx, "env/" + INamingBinds.RESOURCE_DATASOURCE); Util.unbind(compCtx, "env/" + INamingBinds.RESOURCE_DBTYPE); Util.unbind(compCtx, "env/" + INamingBinds.RESOURCE_CONFIGPROPERTIES); Util.unbind(compCtx, "env/" + INamingBinds.RESOURCE_TRANSMANAG); } catch (final NamingException e) { throw new StartupException("unbind of the database connection failed", e); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy