org.eclipse.dirigible.repository.datasource.DataSourceFacade.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.dirigible.repository.datasource.DataSourceFacade.java

Source

/*******************************************************************************
 * Copyright (c) 2015 SAP and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * Contributors:
 * SAP - initial API and implementation
 *******************************************************************************/

package org.eclipse.dirigible.repository.datasource;

import java.sql.Connection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.naming.InitialContext;
import javax.servlet.http.HttpServletRequest;
import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.derby.jdbc.EmbeddedDataSource;
import org.eclipse.dirigible.repository.api.ICommonConstants;
import org.eclipse.dirigible.repository.logging.Logger;

/**
 * DataSource Facade utility class for IDE
 */
public class DataSourceFacade {

    // public static final String DATABASE_PRODUCT_NAME = "DATABASE_PRODUCT_NAME"; //$NON-NLS-1$
    // public static final String DATABASE_PRODUCT_VERSION = "DATABASE_PRODUCT_VERSION"; //$NON-NLS-1$
    // public static final String DATABASE_MINOR_VERSION = "DATABASE_MINOR_VERSION"; //$NON-NLS-1$
    // public static final String DATABASE_MAJOR_VERSION = "DATABASE_MAJOR_VERSION"; //$NON-NLS-1$
    // public static final String DATABASE_DRIVER_NAME = "DATABASE_DRIVER_NAME"; //$NON-NLS-1$
    // public static final String DATABASE_DRIVER_MINOR_VERSION = "DATABASE_DRIVER_MINOR_VERSION"; //$NON-NLS-1$
    // public static final String DATABASE_DRIVER_MAJOR_VERSION = "DATABASE_DRIVER_MAJOR_VERSION"; //$NON-NLS-1$
    // public static final String DATABASE_CONNECTION_CLASS_NAME = "DATABASE_CONNECTION_CLASS_NAME"; //$NON-NLS-1$

    private static final String EMPTY = "";

    private static final String EMBEDDED_DATA_SOURCE_IS_USED = Messages.DataSourceFacade_EMBEDDED_DATA_SOURCE_IS_USED;

    private static final String LOCAL_DB_ACTION = "create"; //$NON-NLS-1$
    private static final String LOCAL_DB_NAME = "derby"; //$NON-NLS-1$

    private static final String DATASOURCE_DEFAULT = "DEFAULT_DATASOURCE"; //$NON-NLS-1$
    private static final String DEFAULT_DATASOURCE_TYPE = ICommonConstants.INIT_PARAM_DEFAULT_DATASOURCE_TYPE;
    private static final String DEFAULT_DATASOURCE_TYPE_JNDI = ICommonConstants.INIT_PARAM_DEFAULT_DATASOURCE_TYPE_JNDI;
    private static final String DEFAULT_DATASOURCE_TYPE_LOCAL = ICommonConstants.INIT_PARAM_DEFAULT_DATASOURCE_TYPE_LOCAL;
    private static final String JNDI_DEFAULT_DATASOURCE = ICommonConstants.INIT_PARAM_JNDI_DEFAULT_DATASOURCE;

    public static final String DATASOURCE_PREFIX = "DATASOURCE_"; //$NON-NLS-1$

    public static final String PARAM_DB_ID = "db.id";
    public static final String PARAM_DB_NAME = "db.name";
    public static final String PARAM_DB_TYPE = "db.type";
    public static final String PARAM_DB_LOC = "db.location";
    public static final String PARAM_DB_DRIVER = "db.driver";
    public static final String PARAM_DB_USER = "db.user";
    public static final String PARAM_DB_PASSWORD = "db.password";
    public static final String PARAM_DB_AUTO_COMMIT = "db.auto-commit";
    public static final String PARAM_DB_AUTO_MAX_ACTIVE = "db.max-active";
    public static final String PARAM_DB_AUTO_MAX_IDLE = "db.max-idle";
    public static final String PARAM_DB_AUTO_MAX_WAIT = "db.max-wait";

    public static final String PARAM_DB_TYPE_JNDI = "jndi";
    public static final String PARAM_DB_TYPE_DIRECT = "direct";

    public static final Logger logger = Logger.getLogger(DataSourceFacade.class.getCanonicalName());

    private static DataSource localDataSource;

    private static DataSourceFacade instance;

    private WrappedDataSource dataSource;

    private static Map<String, Properties> namedDataSources = Collections
            .synchronizedMap(new HashMap<String, Properties>());

    public static DataSourceFacade getInstance() {
        if (instance == null) {
            instance = new DataSourceFacade();
        }
        return instance;
    }

    // public DataSource getDataSource() {
    // return getDataSource(null);
    // }

    public DataSource getDataSource(HttpServletRequest request) {
        if (dataSource == null) {
            logger.debug("Lookup Datasource...");
            if (request == null) {
                logger.debug("No request - try from Env...");
                dataSource = getFromEnv();
            } else {
                logger.debug("Request exists - try from Request...");
                dataSource = getFromSession(request);
            }

            if (dataSource == null) {
                logger.debug("Try from Context...");
                String jndiName = System.getProperty(JNDI_DEFAULT_DATASOURCE);
                dataSource = (WrappedDataSource) getFromContext(jndiName, true);
            }

            if (dataSource == null) {
                dataSource = createLocal();
                logger.warn("Created Local DataSource!");
            } else {
                logger.debug("Lookup done.");
            }
            // populateMetaData(dataSource);
        }
        return dataSource;
    }

    private WrappedDataSource getFromSession(HttpServletRequest request) {
        logger.debug("Try to get datasource from the Request");

        DataSource dataSource = null;
        dataSource = (DataSource) request.getAttribute(DATASOURCE_DEFAULT);
        if (dataSource != null) {
            WrappedDataSource wrappedDataSource = new WrappedDataSource(dataSource);
            logger.debug("Datasource retrieved from the Request");
            return wrappedDataSource;
        } else {
            logger.debug("Datasource NOT available in the Request");
        }
        return null;
    }

    private WrappedDataSource getFromEnv() {
        logger.debug("Try to get datasource from System Properties");

        DataSource dataSource = null;
        dataSource = (DataSource) System.getProperties().get(DATASOURCE_DEFAULT);
        if (dataSource != null) {
            WrappedDataSource wrappedDataSource = new WrappedDataSource(dataSource);
            logger.debug("Datasource retrieved from System Properties");
            return wrappedDataSource;
        } else {
            logger.debug("Datasource NOT available in System Properties");
        }
        return null;
    }

    private DataSource getFromContext(String jndiName, boolean wrap) {

        String defaultDataSourceType = System.getProperty(DEFAULT_DATASOURCE_TYPE);
        if (!DEFAULT_DATASOURCE_TYPE_JNDI.equalsIgnoreCase(defaultDataSourceType)) {
            logger.warn(
                    "Getting from Context not possible - no configured default DataSource as initial parameter");
            return null;
        }

        logger.debug("Try to get datasource from the InitialContext");

        try {
            InitialContext context = (InitialContext) System.getProperties().get(ICommonConstants.INITIAL_CONTEXT);
            if ((context == null) || (jndiName == null)) {
                return null;
            }
            DataSource datasource = (DataSource) context.lookup(jndiName);
            if (datasource == null) {
                logger.error("Could not find DataSource in Initial Context by name: " + jndiName);
            } else {
                Connection con = null;
                try {
                    con = datasource.getConnection();
                } catch (Exception e) {
                    logger.error(
                            "Datasource retrieved from InitialContext, but it is broken - not bound to a real database",
                            e);
                    return null;
                } finally {
                    if (con != null) {
                        con.close();
                    }
                }

                if (wrap) {
                    WrappedDataSource wrappedDataSource = new WrappedDataSource(datasource);
                    logger.debug("Datasource retrieved from InitialContext and wrapped");
                    return wrappedDataSource;
                }
                logger.debug("Datasource retrieved from InitialContext and returned unwrapped");
                return datasource;
            }
        } catch (Throwable e) {
            logger.error("Could not find DataSource", e);
        }

        return null;
    }

    private WrappedDataSource createLocal() {

        logger.debug("Try to create embedded datasource");

        localDataSource = (DataSource) System.getProperties().get(LOCAL_DB_NAME);
        if (localDataSource == null) {
            localDataSource = new EmbeddedDataSource();
            ((EmbeddedDataSource) localDataSource).setDatabaseName(LOCAL_DB_NAME);
            ((EmbeddedDataSource) localDataSource).setCreateDatabase(LOCAL_DB_ACTION);
            System.getProperties().put(LOCAL_DB_NAME, localDataSource);
        }
        logger.warn(EMBEDDED_DATA_SOURCE_IS_USED);

        WrappedDataSource wrappedDataSource = new WrappedDataSource(localDataSource);
        return wrappedDataSource;
    }

    // private void populateMetaData(DataSource dataSource) {
    // Connection connection = null;
    // try {
    // try {
    // connection = dataSource.getConnection();
    // DatabaseMetaData metaData = connection.getMetaData();
    // System.setProperty(DATABASE_PRODUCT_NAME, metaData.getDatabaseProductName());
    // System.setProperty(DATABASE_PRODUCT_VERSION, metaData.getDatabaseProductVersion());
    // System.setProperty(DATABASE_MINOR_VERSION, metaData.getDatabaseMinorVersion() + EMPTY);
    // System.setProperty(DATABASE_MAJOR_VERSION, metaData.getDatabaseMajorVersion() + EMPTY);
    // System.setProperty(DATABASE_DRIVER_NAME, metaData.getDriverName());
    // System.setProperty(DATABASE_DRIVER_MINOR_VERSION, metaData.getDriverMinorVersion() + EMPTY);
    // System.setProperty(DATABASE_DRIVER_MAJOR_VERSION, metaData.getDriverMajorVersion() + EMPTY);
    // System.setProperty(DATABASE_CONNECTION_CLASS_NAME, connection.getClass().getCanonicalName());
    // } finally {
    // if (connection != null) {
    // connection.close();
    // }
    // }
    // } catch (SQLException e) {
    // logger.error(e.getMessage(), e);
    // }
    // }

    /**
     * Register a named data-source's meta-data by name in the list of known named data sources
     *
     * @param name
     * @param namedDataSource
     */
    public void registerDataSource(String name, Properties namedDataSource) {
        this.namedDataSources.put(name, namedDataSource);
        logger.debug(String.format("Datasource with name %s has been registered", name));
    }

    /**
     * Gives the named data source from the list, if any
     *
     * @param name
     * @return
     */
    public DataSource getNamedDataSource(HttpServletRequest request, String name) {
        Properties properties = this.namedDataSources.get(name);
        if (properties == null) {
            logger.error(String.format("Named DataSource %s is not configured in the Repository.", name));
            return null;
        }

        String id = properties.getProperty(PARAM_DB_ID);
        String type = properties.getProperty(PARAM_DB_TYPE);
        String loc = properties.getProperty(PARAM_DB_LOC);
        DataSource namedDataSource = null;
        if (request != null) {
            String nameInSession = DATASOURCE_PREFIX + id;
            namedDataSource = (DataSource) request.getAttribute(nameInSession);
            if (namedDataSource == null) {
                if (PARAM_DB_TYPE_JNDI.equals(type)) {
                    namedDataSource = getFromContext(loc, false);
                    if (namedDataSource != null) {
                        request.setAttribute(nameInSession, namedDataSource);
                    } else {
                        logger.error(String.format(
                                "Named DataSource %s has not been injected in the request's session. Check the initial parameters.",
                                nameInSession));
                    }
                } else if (PARAM_DB_TYPE_DIRECT.equals(type)) {
                    namedDataSource = createDirectDataSource(properties);
                    if (namedDataSource != null) {
                        request.setAttribute(nameInSession, namedDataSource);
                    } else {
                        logger.error(String.format(
                                "Named DataSource %s cannot be created based on the configurations metadata",
                                nameInSession));
                    }
                }
            }
        } else {
            namedDataSource = getFromContext(loc, false);
        }
        return namedDataSource;
    }

    private DataSource createDirectDataSource(Properties properties) {
        String id = properties.getProperty(DataSourceFacade.PARAM_DB_ID);
        String name = properties.getProperty(DataSourceFacade.PARAM_DB_NAME);
        String url = properties.getProperty(DataSourceFacade.PARAM_DB_LOC);
        String driver = properties.getProperty(DataSourceFacade.PARAM_DB_DRIVER);
        String user = properties.getProperty(DataSourceFacade.PARAM_DB_USER);
        String password = properties.getProperty(DataSourceFacade.PARAM_DB_PASSWORD);
        String defaultAutoCommit = properties.getProperty(DataSourceFacade.PARAM_DB_AUTO_COMMIT);
        String maxActive = properties.getProperty(DataSourceFacade.PARAM_DB_AUTO_MAX_ACTIVE);
        String maxIdle = properties.getProperty(DataSourceFacade.PARAM_DB_AUTO_MAX_IDLE);
        String maxWait = properties.getProperty(DataSourceFacade.PARAM_DB_AUTO_MAX_WAIT);

        BasicDataSource basicDataSource = new BasicDataSource();
        basicDataSource.setDriverClassName(driver);
        basicDataSource.setUrl(url);
        basicDataSource.setUsername(user);
        basicDataSource.setPassword(password);
        basicDataSource.setDefaultAutoCommit(Boolean.parseBoolean(defaultAutoCommit));
        basicDataSource.setMaxActive(maxActive != null ? Integer.parseInt(maxActive) : 100);
        basicDataSource.setMaxIdle(maxIdle != null ? Integer.parseInt(maxIdle) : 30);
        basicDataSource.setMaxWait(maxWait != null ? Integer.parseInt(maxWait) : 10000);

        return basicDataSource;

    }

    /**
     * List the registered DataSources names
     *
     * @return
     */
    public Set<String> getNamedDataSourcesNames() {
        return this.namedDataSources.keySet();
    }

    /**
     * Un-register an already registered DataSource
     *
     * @param name
     */
    public void unregisterDataSource(String name) {
        this.namedDataSources.remove(name);
    }

    /**
     * Un-register all the registered DataSources
     */
    public void unregisterAllDataSources() {
        this.namedDataSources.clear();
    }

    public Properties getNamedDataSourceConfig(String dsName) {
        return DataSourceFacade.namedDataSources.get(dsName);
    }

}