/* * 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 2008 - 2009 Pentaho Corporation. All rights reserved. * * * Created April 21, 2009 * @author rmansoor */ package org.pentaho.platform.dataaccess.datasource.wizard.service.impl; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.pentaho.commons.connection.IPentahoConnection; import org.pentaho.database.dialect.GenericDatabaseDialect; import org.pentaho.database.dialect.IDatabaseDialect; import org.pentaho.database.model.IDatabaseConnection; import org.pentaho.database.service.DatabaseConnectionService; import org.pentaho.di.core.exception.KettleDatabaseException; import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.api.engine.IPluginResourceLoader; import org.pentaho.platform.api.engine.IServiceManager; import org.pentaho.platform.api.engine.ServiceException; import org.pentaho.platform.api.repository.datasource.DatasourceMgmtServiceException; import org.pentaho.platform.api.repository.datasource.IDatasource; import org.pentaho.platform.api.repository.datasource.IDatasourceMgmtService; import org.pentaho.platform.dataaccess.datasource.IConnection; import org.pentaho.platform.dataaccess.datasource.beans.Connection; import org.pentaho.platform.dataaccess.datasource.wizard.service.ConnectionServiceException; import org.pentaho.platform.dataaccess.datasource.wizard.service.gwt.IConnectionService; import org.pentaho.platform.dataaccess.datasource.wizard.service.impl.utils.ConnectionServiceHelper; import org.pentaho.platform.dataaccess.datasource.wizard.service.messages.Messages; import org.pentaho.platform.engine.core.system.PentahoBase; import org.pentaho.platform.engine.core.system.PentahoSessionHolder; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.engine.services.connection.PentahoConnectionFactory; import org.pentaho.platform.plugin.services.connections.sql.SQLConnection; import org.pentaho.platform.repository.hibernate.HibernateUtil; /** * ConnectionServiceImpl extends PenahoBase so that it inherits the ILogger functionality. */ public class ConnectionServiceImpl extends PentahoBase implements IConnectionService { private IDataAccessPermissionHandler dataAccessPermHandler; private IDatasourceMgmtService datasourceMgmtSvc; private static final Log logger = LogFactory.getLog(ConnectionServiceImpl.class); public Log getLogger() { return logger; } public ConnectionServiceImpl() { IPentahoSession session = PentahoSessionHolder.getSession(); datasourceMgmtSvc = PentahoSystem.get(IDatasourceMgmtService.class, session); String dataAccessClassName = null; try { //FIXME: we should be using an object factory of some kind here IPluginResourceLoader resLoader = PentahoSystem.get(IPluginResourceLoader.class, null); dataAccessClassName = resLoader.getPluginSetting(getClass(), "settings/data-access-permission-handler", SimpleDataAccessPermissionHandler.class.getName()); //$NON-NLS-1$ Class<?> clazz = Class.forName(dataAccessClassName, true, getClass().getClassLoader()); Constructor<?> defaultConstructor = clazz.getConstructor(new Class[] {}); dataAccessPermHandler = (IDataAccessPermissionHandler) defaultConstructor.newInstance(new Object[] {}); } catch (Exception e) { logger.error(Messages.getInstance().getErrorString("ConnectionServiceImpl.ERROR_0007_DATAACCESS_PERMISSIONS_INIT_ERROR", e //$NON-NLS-1$ .getLocalizedMessage()), e); // TODO: Unhardcode once this is an actual plugin dataAccessPermHandler = new SimpleDataAccessPermissionHandler(); } } protected boolean hasDataAccessPermission() { return dataAccessPermHandler != null && dataAccessPermHandler.hasDataAccessPermission(PentahoSessionHolder.getSession()); } public List<IConnection> getConnections() throws ConnectionServiceException { if (!hasDataAccessPermission()) { logger.error(Messages.getInstance().getErrorString("ConnectionServiceImpl.ERROR_0001_PERMISSION_DENIED")); //$NON-NLS-1$ throw new ConnectionServiceException(Messages.getInstance() .getErrorString("ConnectionServiceImpl.ERROR_0001_PERMISSION_DENIED")); //$NON-NLS-1$ } List<IConnection> connectionList = new ArrayList<IConnection>(); try { for (IDatasource datasource : datasourceMgmtSvc.getDatasources()) { connectionList.add(convertTo(datasource)); } } catch (DatasourceMgmtServiceException dme) { logger.error(Messages.getInstance().getErrorString("ConnectionServiceImpl.ERROR_0002_UNABLE_TO_GET_CONNECTION_LIST", dme //$NON-NLS-1$ .getLocalizedMessage())); throw new ConnectionServiceException(Messages.getInstance().getErrorString( "ConnectionServiceImpl.ERROR_0002_UNABLE_TO_GET_CONNECTION_LIST", dme.getLocalizedMessage()), dme); //$NON-NLS-1$ } return connectionList; } public IConnection getConnectionByName(String name) throws ConnectionServiceException { if (!hasDataAccessPermission()) { logger.error(Messages.getInstance().getErrorString("ConnectionServiceImpl.ERROR_0001_PERMISSION_DENIED")); //$NON-NLS-1$ throw new ConnectionServiceException(Messages.getInstance() .getErrorString("ConnectionServiceImpl.ERROR_0001_PERMISSION_DENIED")); //$NON-NLS-1$ } try { return convertTo(datasourceMgmtSvc.getDatasource(name)); } catch (DatasourceMgmtServiceException dme) { logger.error(Messages.getInstance().getErrorString("ConnectionServiceImpl.ERROR_0003_UNABLE_TO_GET_CONNECTION", name, dme //$NON-NLS-1$ .getLocalizedMessage())); throw new ConnectionServiceException(Messages.getInstance().getErrorString( "ConnectionServiceImpl.ERROR_0003_UNABLE_TO_GET_CONNECTION", name, dme.getLocalizedMessage()), dme); //$NON-NLS-1$ } } public boolean addConnection(IConnection connection) throws ConnectionServiceException { if (!hasDataAccessPermission()) { logger.error(Messages.getInstance().getErrorString("ConnectionServiceImpl.ERROR_0001_PERMISSION_DENIED")); //$NON-NLS-1$ throw new ConnectionServiceException(Messages.getInstance() .getErrorString("ConnectionServiceImpl.ERROR_0001_PERMISSION_DENIED")); //$NON-NLS-1$ } try { HibernateUtil.beginTransaction(); datasourceMgmtSvc.createDatasource(convertFrom(connection)); HibernateUtil.commitTransaction(); return true; } catch (Exception e) { logger.error(Messages.getInstance().getErrorString("ConnectionServiceImpl.ERROR_0004_UNABLE_TO_ADD_CONNECTION", connection //$NON-NLS-1$ .getName(), e.getLocalizedMessage())); throw new ConnectionServiceException(Messages.getInstance().getErrorString( "ConnectionServiceImpl.ERROR_0004_UNABLE_TO_ADD_CONNECTION", connection.getName(), e //$NON-NLS-1$ .getLocalizedMessage()), e); } } public boolean updateConnection(IConnection connection) throws ConnectionServiceException { if (!hasDataAccessPermission()) { logger.error(Messages.getInstance().getErrorString("ConnectionServiceImpl.ERROR_0001_PERMISSION_DENIED")); //$NON-NLS-1$ throw new ConnectionServiceException(Messages.getInstance() .getErrorString("ConnectionServiceImpl.ERROR_0001_PERMISSION_DENIED")); //$NON-NLS-1$ } try { HibernateUtil.beginTransaction(); connection.setPassword(ConnectionServiceHelper.getConnectionPassword(connection.getName(), connection .getPassword())); datasourceMgmtSvc.updateDatasource(convertFrom(connection)); HibernateUtil.commitTransaction(); return true; } catch (Exception e) { logger.error(Messages.getInstance().getErrorString("ConnectionServiceImpl.ERROR_0005_UNABLE_TO_UPDATE_CONNECTION", //$NON-NLS-1$ connection.getName(), e.getLocalizedMessage())); throw new ConnectionServiceException(Messages.getInstance().getErrorString( "ConnectionServiceImpl.ERROR_0005_UNABLE_TO_UPDATE_CONNECTION", connection.getName(), e //$NON-NLS-1$ .getLocalizedMessage()), e); } } public boolean deleteConnection(IConnection connection) throws ConnectionServiceException { if (!hasDataAccessPermission()) { logger.error(Messages.getInstance().getErrorString("ConnectionServiceImpl.ERROR_0001_PERMISSION_DENIED")); //$NON-NLS-1$ throw new ConnectionServiceException(Messages.getInstance() .getErrorString("ConnectionServiceImpl.ERROR_0001_PERMISSION_DENIED")); //$NON-NLS-1$ } try { HibernateUtil.beginTransaction(); datasourceMgmtSvc.deleteDatasource(convertFrom(connection)); HibernateUtil.commitTransaction(); return true; } catch (Exception e) { logger.error(Messages.getInstance().getErrorString("ConnectionServiceImpl.ERROR_0006_UNABLE_TO_DELETE_CONNECTION", //$NON-NLS-1$ connection.getName(), e.getLocalizedMessage())); throw new ConnectionServiceException(Messages.getInstance().getErrorString( "ConnectionServiceImpl.ERROR_0006_UNABLE_TO_DELETE_CONNECTION", connection.getName(), e //$NON-NLS-1$ .getLocalizedMessage()), e); } } public boolean deleteConnection(String name) throws ConnectionServiceException { if (!hasDataAccessPermission()) { logger.error(Messages.getInstance().getErrorString("ConnectionServiceImpl.ERROR_0001_PERMISSION_DENIED")); //$NON-NLS-1$ throw new ConnectionServiceException(Messages.getInstance() .getErrorString("ConnectionServiceImpl.ERROR_0001_PERMISSION_DENIED")); //$NON-NLS-1$ } try { HibernateUtil.beginTransaction(); datasourceMgmtSvc.deleteDatasource(name); HibernateUtil.commitTransaction(); return true; } catch (Exception e) { logger.error(Messages.getInstance().getErrorString("ConnectionServiceImpl.ERROR_0006_UNABLE_TO_DELETE_CONNECTION", name, e //$NON-NLS-1$ .getLocalizedMessage())); throw new ConnectionServiceException(Messages.getInstance().getErrorString( "ConnectionServiceImpl.ERROR_0006_UNABLE_TO_DELETE_CONNECTION", name, e.getLocalizedMessage()), e); //$NON-NLS-1$ } } public boolean testConnection(IConnection connection) throws ConnectionServiceException { if (!hasDataAccessPermission()) { logger.error(Messages.getInstance().getErrorString("ConnectionServiceImpl.ERROR_0001_PERMISSION_DENIED")); //$NON-NLS-1$ throw new ConnectionServiceException(Messages.getInstance() .getErrorString("ConnectionServiceImpl.ERROR_0001_PERMISSION_DENIED")); //$NON-NLS-1$ } if (connection != null) { IPentahoConnection pentahoConnection = null; pentahoConnection = PentahoConnectionFactory.getConnection(IPentahoConnection.SQL_DATASOURCE, connection .getDriverClass(), connection.getUrl(), connection.getUsername(), ConnectionServiceHelper .getConnectionPassword(connection.getName(), connection.getPassword()), null, this); if (pentahoConnection != null) { // make sure we have a native connection behind the SQLConnection object // if the native connection is null, the test of the connection failed boolean testedOk = ((SQLConnection) pentahoConnection).getNativeConnection() != null; pentahoConnection.close(); return testedOk; } else { return false; } } else { logger.error(Messages.getInstance().getErrorString("ConnectionServiceImpl.ERROR_0008_UNABLE_TO_TEST_NULL_CONNECTION")); //$NON-NLS-1$ throw new ConnectionServiceException(Messages.getInstance() .getErrorString("ConnectionServiceImpl.ERROR_0008_UNABLE_TO_TEST_NULL_CONNECTION")); //$NON-NLS-1$ } } /** * This method converts from IDatasource to IConnection * * @param IDatasource * @return IConnection */ private IConnection convertTo(IDatasource datasource) { if( datasource == null ) { // make sure we don't attempt bad conversions return null; } IConnection returnDatasource = new org.pentaho.platform.dataaccess.datasource.beans.Connection(); returnDatasource.setDriverClass(datasource.getDriverClass()); returnDatasource.setName(datasource.getName()); returnDatasource.setPassword(ConnectionServiceHelper.encodePassword(datasource.getPassword())); returnDatasource.setUsername(datasource.getUserName()); returnDatasource.setUrl(datasource.getUrl()); return returnDatasource; } /** * This method converts from IConnection to IDatasource * * @param IConnection * @return IDatasource */ private IDatasource convertFrom(IConnection connection) { if( connection == null ) { // make sure we don't attempt bad conversions return null; } IDatasource returnDatasource = (IDatasource) PentahoSystem.get(IDatasource.class, null); returnDatasource.setDriverClass(connection.getDriverClass()); returnDatasource.setName(connection.getName()); returnDatasource.setPassword(connection.getPassword()); returnDatasource.setUserName(connection.getUsername()); returnDatasource.setUrl(connection.getUrl()); return returnDatasource; } public IDatabaseConnection convertFromConnection(IConnection connection) throws ConnectionServiceException { if( connection == null ) { // make sure we don't attempt bad conversions return null; } if (!hasDataAccessPermission()) { logger.error(Messages.getInstance().getErrorString("ConnectionServiceImpl.ERROR_0001_PERMISSION_DENIED")); //$NON-NLS-1$ throw new ConnectionServiceException(Messages.getInstance() .getErrorString("ConnectionServiceImpl.ERROR_0001_PERMISSION_DENIED")); //$NON-NLS-1$ } try { IServiceManager manager = PentahoSystem.get(IServiceManager.class); DatabaseConnectionService service = (DatabaseConnectionService) manager.getServiceBean("gwt", //$NON-NLS-1$ "databaseConnectionService"); //$NON-NLS-1$ IDatabaseConnection conn = service.createDatabaseConnection(connection.getDriverClass(), connection.getUrl()); conn.setName(connection.getName()); conn.setUsername(connection.getUsername()); conn.setPassword(ConnectionServiceHelper.encodePassword(connection.getPassword())); return conn; } catch (ServiceException e) { throw new ConnectionServiceException(e); } catch (Throwable e) { throw new ConnectionServiceException(e); } } public IConnection convertToConnection(IDatabaseConnection connection) throws ConnectionServiceException { if( connection == null ) { // make sure we don't attempt bad conversions return null; } if (!hasDataAccessPermission()) { logger.error(Messages.getInstance().getErrorString("ConnectionServiceImpl.ERROR_0001_PERMISSION_DENIED")); //$NON-NLS-1$ throw new ConnectionServiceException(Messages.getInstance() .getErrorString("ConnectionServiceImpl.ERROR_0001_PERMISSION_DENIED")); //$NON-NLS-1$ } try { IServiceManager manager = PentahoSystem.get(IServiceManager.class); DatabaseConnectionService service = (DatabaseConnectionService) manager.getServiceBean("gwt", //$NON-NLS-1$ "databaseConnectionService"); //$NON-NLS-1$ IDatabaseDialect dialect = service.getDialectService().getDialect(connection); Connection conn = new Connection(); conn.setName(connection.getName()); conn.setUsername(connection.getUsername()); conn.setPassword(connection.getPassword()); String url = dialect.getURLWithExtraOptions(connection); conn.setUrl(url); if (connection.getDatabaseType().getShortName().equals("GENERIC")) { //$NON-NLS-1$ conn.setDriverClass(connection.getAttributes().get(GenericDatabaseDialect.ATTRIBUTE_CUSTOM_DRIVER_CLASS)); } else { conn.setDriverClass(dialect.getNativeDriver()); } return conn; } catch (KettleDatabaseException e) { throw new ConnectionServiceException(e); } catch (ServiceException e) { throw new ConnectionServiceException(e); } } }