/*! * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright (c) 2002-2016 Pentaho Corporation.. All rights reserved. */ package org.pentaho.platform.plugin.services.connections.mondrian; import java.sql.DriverManager; import java.sql.SQLException; import java.util.List; import java.util.Properties; import mondrian.olap.Util; import mondrian.parser.TokenMgrError; import mondrian.rolap.RolapConnectionProperties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.olap4j.OlapConnection; import org.pentaho.commons.connection.IPentahoConnection; import org.pentaho.commons.connection.IPentahoResultSet; import org.pentaho.platform.plugin.services.messages.Messages; /** * MDXOlap4jConnection implements IPentahoConenction to support olap4j connections to any olap4j provider. Developers * may subclass MDXOlap4jConnection to unwrap the olap4j connection to directly manipulate the underlying connection. An example of this is * setting a DelegatingRole in the case of Mondrian. * * @author Benny Chow * @version $Id: $ * @created Jan 9, 2013 * @updated $DateTime: $ */ public class MDXOlap4jConnection implements IPentahoConnection { static final Log log = LogFactory.getLog( MDXOlap4jConnection.class ); /** * Underlying connection to OLAP system. */ protected OlapConnection connection = null; /** * Closes the connection. */ public void close() { try { if ( connection != null ) { connection.close(); } } catch ( SQLException e ) { throw new RuntimeException( e ); } } /** * Sets the properties to be used when the connection is made. The standard keys for the properties are defined in * this interface. * * @param props Properties to be used for creating connection. * This particular method relies on the following properties: url, driver, user, password. */ public boolean connect( Properties props ) { String url = props.getProperty( "url" ); String driver = props.getProperty( "driver" ); // Fetch the user/password out of the properties so we can pass them // as actual JDBC parameters. String user = props.getProperty( "user", null ); String password = props.getProperty( "password", null ); try { if ( connection != null ) { connection.close(); } // For Mondrian olap4j driver, we will also do role mapping. if ( url.startsWith( "jdbc:mondrian" ) ) { Util.PropertyList connectProperties = Util.parseConnectString( url ); MDXConnection.mapPlatformRolesToMondrianRolesHelper( connectProperties ); url = connectProperties.toString(); } // Make sure the driver is loaded into the thread's classloader. ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); if ( contextClassLoader == null ) { contextClassLoader = getClass().getClassLoader(); } contextClassLoader.loadClass( driver ); // Create the connection through JDBC. java.sql.Connection sqlConnection = DriverManager.getConnection( url, user, password ); // Unwrap into OlapConnection. connection = sqlConnection.unwrap( org.olap4j.OlapConnection.class ); } catch ( Exception e ) { log.error( Messages.getInstance().getErrorString( "MDXConnection.ERROR_0002_INVALID_CONNECTION", "driver=" + driver + ";url=" + getLogUrl( url ) ), e ); return false; } catch ( TokenMgrError e ) { log.error( Messages.getInstance().getErrorString( "MDXConnection.ERROR_0002_INVALID_CONNECTION", "driver=" + driver + ";url=" + getLogUrl( url ) ), e ); return false; } return true; } /** * Removes password from connection url */ private String getLogUrl( String url ) { Util.PropertyList connectProperties = Util.parseConnectString( url ); connectProperties.remove( RolapConnectionProperties.JdbcPassword.name() ); return connectProperties.toString(); } /** * Executes the specified query against the connection. * @param query * SQL-like query string. May be data source specific. * @return Returns result set of the query. */ public IPentahoResultSet executeQuery( String arg0 ) { throw new UnsupportedOperationException(); } /**Returns resultset of the last executed query. * @return Returns the resultset from the last query executed. */ public IPentahoResultSet getResultSet() { throw new UnsupportedOperationException(); } /**Checks if the connection is initialized or not. * @return Returns true if the connection has been properly initialized. */ public boolean initialized() { return connection != null; } /**Checks if the connection is closed or not. * @return Returns true if this connection has been closed. */ public boolean isClosed() { if ( connection == null ) { throw new IllegalStateException(); } try { return connection.isClosed(); } catch ( SQLException e ) { throw new RuntimeException( e ); } } /**Checks if the connection is read only or not. * @return Returns true if this connection is read only. * * NOTE: Current implementation for all connections is read only. */ public boolean isReadOnly() { if ( connection == null ) { throw new IllegalStateException(); } try { return connection.isReadOnly(); } catch ( SQLException e ) { throw new RuntimeException( e ); } } /**Builds the query based on the pattern and parameters list and executes it against the connection. * @param arg0 * SQL-like query string. May be data source specific. * @param arg1 * List of objects to bind into prepared query. * @return Returns result set of the query. */ public IPentahoResultSet prepareAndExecuteQuery( String arg0, List arg1 ) throws Exception { throw new UnsupportedOperationException(); } /**Checks if the given connection supports prepared queries. * * @return Returns true if the connection supports prepared queries. */ public boolean preparedQueriesSupported() { return false; } /** * Sets size of the fetch buffer used when retrieving rows from the underlying database. * * @param fetchSize The buffer size. */ public void setFetchSize( int arg0 ) { throw new UnsupportedOperationException(); } /** * Sets maximum rows that will be returned by the next query. * * @param maxRows Maximum rows that are returned by the next query. */ public void setMaxRows( int arg0 ) { throw new UnsupportedOperationException(); } /** * Sets the properties to be used when the connection is made. It connects to the OLAP system described by the properties. * The standard keys for the properties are defined in * IPentahoConnection interface. * * @param props Properties to be used when the connection is made. */ public void setProperties( Properties props ) { this.connect( props ); } /** * Clears any warnings cached by the connection. */ public void clearWarnings() { } /** * Returns the type of connection. * * @return Returns the type of the connection. */ public String getDatasourceType() { return IPentahoConnection.MDX_OLAP4J_DATASOURCE; } /**Retrieves the string representation of the last executed query. * @return Returns the last query string executed. */ public String getLastQuery() { throw new UnsupportedOperationException(); } /** * Returns the underlying connection to OLAP system. * @return Returns the underlying connection. */ public OlapConnection getConnection() { return connection; } }