rolapconnection.java

来自「数据仓库展示程序」· Java 代码 · 共 525 行 · 第 1/2 页

JAVA
525
字号
/*
// $Id: //open/mondrian/src/main/mondrian/rolap/RolapConnection.java#38 $
// This software is subject to the terms of the Common Public License
// Agreement, available at the following URL:
// http://www.opensource.org/licenses/cpl.html.
// Copyright (C) 2001-2005 Kana Software, Inc. and others.
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
//
// jhyde, 2 October, 2002
*/
package mondrian.rolap;

import mondrian.olap.*;
import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DataSourceConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;

import org.apache.log4j.Logger;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;

/**
 * A <code>RolapConnection</code> is a connection to a Mondrian OLAP Server.
 *
 * <p>Typically, you create a connection via
 * {@link DriverManager#getConnection(java.lang.String, javax.servlet.ServletContext, boolean)}.
 * {@link RolapConnectionProperties} describes allowable keywords.</p>
 *
 * @see RolapSchema
 * @see DriverManager
 * @author jhyde
 * @since 2 October, 2002
 * @version $Id: //open/mondrian/src/main/mondrian/rolap/RolapConnection.java#38 $
 */
public class RolapConnection extends ConnectionBase {
    private static final Logger LOGGER = Logger.getLogger(RolapConnection.class);

    private final Util.PropertyList connectInfo;
    /** Factory for JDBC connections to talk to the RDBMS. This factory will
     * usually use a connection pool. */
    private final DataSource dataSource;
    private final String catalogName;
    private final RolapSchema schema;
    private SchemaReader schemaReader;
    protected Role role;
    private Locale locale = Locale.US;

    /**
     * Creates a connection.
     *
     * @param connectInfo Connection properties; keywords are described in
     *   {@link RolapConnectionProperties}.
     */
    public RolapConnection(Util.PropertyList connectInfo) {
        this(connectInfo, null, null);
    }

    /**
     * Creates a connection.
     *
     * @param connectInfo Connection properties; keywords are described in
     *   {@link RolapConnectionProperties}.
     */
    public RolapConnection(Util.PropertyList connectInfo, DataSource datasource) {
        this(connectInfo, null, datasource);
    }

    /**
     * Creates a RolapConnection.
     *
     * <p>Only {@link mondrian.rolap.RolapSchema.Pool#get} calls this with schema != null (to
     * create a schema's internal connection). Other uses retrieve a schema
     * from the cache based upon the <code>Catalog</code> property.
     *
     * @param connectInfo Connection properties; keywords are described in
     *   {@link RolapConnectionProperties}.
     * @param schema Schema for the connection. Must be null unless this is to
     *   be an internal connection.
     * @pre connectInfo != null
     */
    RolapConnection(Util.PropertyList connectInfo, RolapSchema schema) {
        this(connectInfo, schema, null);
    }

    /**
     * Creates a RolapConnection.
     *
     * <p>Only {@link mondrian.rolap.RolapSchema.Pool#get} calls this with
     * schema != null (to create a schema's internal connection).
     * Other uses retrieve a schema from the cache based upon
     * the <code>Catalog</code> property.
     *
     * @param connectInfo Connection properties; keywords are described in
     *   {@link RolapConnectionProperties}.
     * @param schema Schema for the connection. Must be null unless this is to
     *   be an internal connection.
     * @param dataSource If not null an external DataSource to be used
     *        by Mondrian
     * @pre connectInfo != null
     */
    RolapConnection(Util.PropertyList connectInfo,
                    RolapSchema schema,
                    DataSource dataSource) {
        super();

        String provider = connectInfo.get(RolapConnectionProperties.Provider);
        Util.assertTrue(provider.equalsIgnoreCase("mondrian"));
        this.connectInfo = connectInfo;
        this.catalogName = connectInfo.get(RolapConnectionProperties.Catalog);
        this.dataSource = (dataSource != null)
            ? dataSource
            : createDataSource(connectInfo);
        Role role = null;
        if (schema == null) {
            // If RolapSchema.Pool.get were to call this with schema == null,
            // we would loop.
            if (dataSource == null) {
                // If there is no external data source is passed in,
                // we expect the following properties to be set,
                // as they are used to generate the schema cache key.
                final String jdbcConnectString =
                    connectInfo.get(RolapConnectionProperties.Jdbc);
                final String jdbcUser =
                    connectInfo.get(RolapConnectionProperties.JdbcUser);
                final String strDataSource =
                    connectInfo.get(RolapConnectionProperties.DataSource);
                final String connectionKey = jdbcConnectString +
                getJDBCProperties(connectInfo).toString();

                schema = RolapSchema.Pool.instance().get(
                            catalogName,
                            connectionKey,
                            jdbcUser,
                            strDataSource,
                            connectInfo);
            } else {
                schema = RolapSchema.Pool.instance().get(
                            catalogName,
                            dataSource,
                            connectInfo);
            }
            String roleName = connectInfo.get(RolapConnectionProperties.Role);
            if (roleName != null) {
                role = schema.lookupRole(roleName);
                if (role == null) {
                    throw Util.newError("Role '" + roleName + "' not found");
                }
            }
        }
        if (role == null) {
            role = schema.getDefaultRole();
        }
        this.schema = schema;
        setRole(role);
    }

    protected Logger getLogger() {
        return LOGGER;
    }


    // This is package-level in order for the RolapConnectionTest class to have
    // access.
    static DataSource createDataSource(Util.PropertyList connectInfo) {
        final String jdbcConnectString =
                connectInfo.get(RolapConnectionProperties.Jdbc);
        final String poolNeededString =
                connectInfo.get(RolapConnectionProperties.PoolNeeded);

        Properties jdbcProperties = getJDBCProperties(connectInfo);
        String propertyString = jdbcProperties.toString();
        if (jdbcConnectString != null) {
            // Get connection through own pooling datasource
            String jdbcDrivers =
                    connectInfo.get(RolapConnectionProperties.JdbcDrivers);
            if (jdbcDrivers != null) {
                RolapUtil.loadDrivers(jdbcDrivers);
            }
            final String jdbcDriversProp =
                    MondrianProperties.instance().JdbcDrivers.get();
            RolapUtil.loadDrivers(jdbcDriversProp);

            final boolean poolNeeded = (poolNeededString == null)
                // JDBC connections are dumb beasts, so we assume they're not
                // pooled.
                ? true
                : poolNeededString.equalsIgnoreCase("true");

            final String jdbcUser =
                    connectInfo.get(RolapConnectionProperties.JdbcUser);
            final String jdbcPassword =
                    connectInfo.get(RolapConnectionProperties.JdbcPassword);

            if (jdbcUser != null) {
                jdbcProperties.put("user", jdbcUser);
            }
            if (jdbcPassword != null) {
                jdbcProperties.put("password", jdbcPassword);
            }

            if (!poolNeeded) {
                // Connection is already pooled; don't pool it again.
                return new DriverManagerDataSource(jdbcConnectString,
                        jdbcProperties);
            }

            if (jdbcConnectString.toLowerCase().indexOf("mysql") > -1) {
                // mysql driver needs this autoReconnect parameter
                jdbcProperties.setProperty("autoReconnect", "true");
            }
            // use the DriverManagerConnectionFactory to create connections
            ConnectionFactory connectionFactory =
                    new DriverManagerConnectionFactory(jdbcConnectString ,
                            jdbcProperties);
            try {
                return RolapConnectionPool.instance().getPoolingDataSource(
                        jdbcConnectString + propertyString, connectionFactory);
            } catch (Throwable e) {
                throw Util.newInternal(e,
                        "Error while creating connection pool (with URI " +
                        jdbcConnectString + ")");
            }

        } else {

            final String dataSourceName =
                connectInfo.get(RolapConnectionProperties.DataSource);
            if (dataSourceName == null) {
                throw Util.newInternal(
                    "Connect string '" + connectInfo.toString() +
                    "' must contain either '" + RolapConnectionProperties.Jdbc +
                    "' or '" + RolapConnectionProperties.DataSource + "'");
            }

            final boolean poolNeeded = (poolNeededString == null)
                // Data sources are fairly smart, so we assume they look after
                // their own pooling.
                ? false
                : poolNeededString.equalsIgnoreCase("true");

            // Get connection from datasource.
            final DataSource dataSource;
            try {
                dataSource =
                    (DataSource) new InitialContext().lookup(dataSourceName);
            } catch (NamingException e) {
                throw Util.newInternal(e,
                    "Error while looking up data source (" +
                        dataSourceName + ")");
            }
            if (!poolNeeded) {
                return dataSource;
            }
            ConnectionFactory connectionFactory =
                    new DataSourceConnectionFactory(dataSource);
            try {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?