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

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

Go to download

eFaps is a framework used to map objects with or without attached files to a relational database and optional file systems (only for attaches files). Configurable access control can be provided down to object and attribute level depending on implementation and use case. Depending on requirements, events (like triggers) allow to implement business logic and to separate business logic from user interface. The framework includes integrations (e.g. webdav, full text search) and a web application as 'simple' configurable user interface. Some best practises, example web application modules (e.g. team work module) support administrators and implementers using this framework.

There is a newer version: 3.2.0
Show newest version
/*
 * 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