/******************************************************************************* * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library 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. * *******************************************************************************/ package com.liferay.ide.server.ui.action; import com.liferay.ide.core.util.CoreUtil; import com.liferay.ide.server.core.ILiferayRuntime; import com.liferay.ide.server.core.LiferayServerCore; import com.liferay.ide.server.util.ServerUtil; import com.liferay.ide.ui.util.UIUtil; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.List; import java.util.Properties; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.datatools.connectivity.ConnectionProfileConstants; import org.eclipse.datatools.connectivity.ConnectionProfileException; import org.eclipse.datatools.connectivity.ProfileManager; import org.eclipse.datatools.connectivity.drivers.DriverInstance; import org.eclipse.datatools.connectivity.drivers.DriverManager; import org.eclipse.datatools.connectivity.drivers.jdbc.IJDBCDriverDefinitionConstants; import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.osgi.util.NLS; import org.eclipse.ui.IViewPart; import org.eclipse.wst.server.core.IServer; /** * @author Simon Jiang */ public class CreateDBConnectAction extends AbstractServerRunningAction { private final static String JDBC_DRIVER_CLASS_NAME = "jdbc.default.driverClassName"; //$NON-NLS-1$ private final static String PORTAL_EXT_PROPERTIES = "portal-ext.properties"; //$NON-NLS-1$ private final static String PORTAL_SETUP_PROPERTIES = "portal-setup-wizard.properties"; //$NON-NLS-1$ public CreateDBConnectAction() { super(); } private String generateUniqueConnectionProfileName( final String connectionProfileName ) { int index = 1; String testName = connectionProfileName; while( ProfileManager.getInstance().getProfileByName( testName ) != null ) { index++; testName = connectionProfileName + String.valueOf( index ); } return testName; } private Properties getDatabaseProperties( IPath bundlePath ) { final IPath bundleExtPath = bundlePath.append( PORTAL_EXT_PROPERTIES ); final Properties pluginPackageProperties = new Properties(); try { if( bundleExtPath.toFile().exists() ) { final InputStream extInputStream = new FileInputStream( bundleExtPath.toFile() ); pluginPackageProperties.load( extInputStream ); extInputStream.close(); final String driverName = (String) pluginPackageProperties.getProperty( JDBC_DRIVER_CLASS_NAME ); if( CoreUtil.isNullOrEmpty( driverName ) ) { final IPath setupWizardPath = bundlePath.append( PORTAL_SETUP_PROPERTIES ); if( setupWizardPath.toFile().exists() ) { final InputStream setupInputStream = new FileInputStream( setupWizardPath.toFile() ); pluginPackageProperties.load( setupInputStream ); setupInputStream.close(); } } } else { final IPath setupWizardPath = bundlePath.append( PORTAL_SETUP_PROPERTIES ); if( setupWizardPath.toFile().exists() ) { final InputStream setupInputStream = new FileInputStream( setupWizardPath.toFile() ); pluginPackageProperties.load( setupInputStream ); setupInputStream.close(); } } } catch( Exception extException ) { LiferayServerCore.logError( Msgs.noDatabasePropertyFile, extException ); } return pluginPackageProperties; } private LiferayDatabaseConnection getLiferayDBConnection( final String driverClass, final String userName, final String password, final String connectionUrl ) { if( driverClass.equals( "com.mysql.jdbc.Driver" ) ) //$NON-NLS-1$ { final String defaultDriverClass = "com.mysql.jdbc.Driver"; //$NON-NLS-1$ final String providerId = "org.eclipse.datatools.enablement.mysql.connectionProfile"; //$NON-NLS-1$ final String connectionDesc = "Mysql Connection Profile"; //$NON-NLS-1$ final String driverTemplate = "org.eclipse.datatools.enablement.mysql.5_1.driverTemplate"; //$NON-NLS-1$ return new MysqlLiferayDatabaseConnection( defaultDriverClass, providerId, connectionDesc, driverTemplate, userName, password, connectionUrl ); } else if( driverClass.equals( "org.postgresql.Driver" ) ) //$NON-NLS-1$ { final String defaultDriverClass = "org.postgresql.Driver"; //$NON-NLS-1$ final String providerId = "org.eclipse.datatools.enablement.postgresql.connectionProfile"; //$NON-NLS-1$ final String connectionDesc = "Posgresql Connection Profile"; //$NON-NLS-1$ final String driverTemplate = "org.eclipse.datatools.enablement.postgresql.postgresqlDriverTemplate"; //$NON-NLS-1$ return new PostgresqlLiferayDatabaseConnection( defaultDriverClass, providerId, connectionDesc, driverTemplate, userName, password, connectionUrl ); } else if( driverClass == null || driverClass.equals( "org.hsqldb.jdbcDriver" ) ) //$NON-NLS-1$ { final String defaultDriverClass = "org.hsqldb.jdbcDriver"; //$NON-NLS-1$ final String providerId = "org.eclipse.datatools.enablement.hsqldb.connectionProfile"; //$NON-NLS-1$ final String connectionDesc = "Hsql Connection Profile"; //$NON-NLS-1$ final String driverTemplate = "org.eclipse.datatools.enablement.hsqldb.1_8.driver"; //$NON-NLS-1$ return new HsqlLiferayDatabaseConnection( defaultDriverClass, providerId, connectionDesc, driverTemplate ); } return null; } private URL[] getLiferayRuntimeLibs( final ILiferayRuntime liferayRuntime ) throws Exception { final IPath[] extraLibs = liferayRuntime.getUserLibs(); final List<URL> libUrlList = new ArrayList<URL>(); if( !CoreUtil.isNullOrEmpty( extraLibs ) ) { for( IPath url : extraLibs ) { libUrlList.add( new File( url.toOSString() ).toURI().toURL() ); } } final URL[] urls = libUrlList.toArray( new URL[libUrlList.size()] ); return urls; } @Override protected int getRequiredServerState() { return IServer.STATE_STARTED | IServer.STATE_STARTING | IServer.STATE_STOPPING | IServer.STATE_STOPPED; } @SuppressWarnings( "resource" ) public void run( IAction action ) { if( selectedServer != null ) { final ILiferayRuntime liferayRuntime = ServerUtil.getLiferayRuntime( selectedServer ); final Properties pluginPackageProperties = getDatabaseProperties( liferayRuntime.getLiferayHome() ); final String driverName = pluginPackageProperties.getProperty( JDBC_DRIVER_CLASS_NAME, "org.hsqldb.jdbcDriver" ); //$NON-NLS-1$ final String connectionName = liferayRuntime.getRuntime().getName(); final String userName = pluginPackageProperties.getProperty( "jdbc.default.username" ); //$NON-NLS-1$ final String connectionUrl = pluginPackageProperties.getProperty( "jdbc.default.url" ); //$NON-NLS-1$ final String password = pluginPackageProperties.getProperty( "jdbc.default.password" ); //$NON-NLS-1$ try { final URL[] runtimeLibs = getLiferayRuntimeLibs( liferayRuntime ); new Job( Msgs.addDBConnnection ) { @Override protected IStatus run( IProgressMonitor monitor ) { try { final Class<?> classRef = new URLClassLoader( runtimeLibs ).loadClass( driverName ); if( classRef != null ) { final String libPath = classRef.getProtectionDomain().getCodeSource().getLocation().getPath(); final String jarPath = java.net.URLDecoder.decode( libPath, "UTF-8" ); //$NON-NLS-1$ final String driverPath = new File( jarPath ).getAbsolutePath(); final LiferayDatabaseConnection dbConnection = getLiferayDBConnection( driverName, userName, password, connectionUrl ); if( dbConnection != null ) { dbConnection.addDatabaseConnectionProfile( connectionName, driverPath ); UIUtil.async( new Runnable() { public void run() { IViewPart dbView = UIUtil.showView( "org.eclipse.datatools.connectivity.DataSourceExplorerNavigator" ); //$NON-NLS-1$ dbView.setFocus(); } }); } } } catch( Exception e ) { LiferayServerCore.logError( Msgs.addProfileError, e ); } return Status.OK_STATUS; } }.schedule(); } catch( Exception e ) { LiferayServerCore.logError( Msgs.noDBConnectDriver, e ); } } } @Override public void selectionChanged( IAction action, ISelection selection ) { super.selectionChanged( action, selection ); if( !selection.isEmpty() ) { if( selection instanceof IStructuredSelection ) { final IStructuredSelection sel = (IStructuredSelection) selection; if( sel.toList().size() > 1 ) { action.setEnabled( sel.toList().size() == 1 ); } } } } private class HsqlLiferayDatabaseConnection extends LiferayDatabaseConnection { private final static String defaultConnecionUrl = "jdbc:hsqldb:lportal"; //$NON-NLS-1$ private final static String defaultPassword = ""; //$NON-NLS-1$ private final static String defaultUserName = "sa"; //$NON-NLS-1$ public HsqlLiferayDatabaseConnection( final String driverClass, final String providerId, final String connectinDesc, final String driverTemplate) { super( driverClass, providerId, connectinDesc, driverTemplate, defaultUserName, defaultPassword, defaultConnecionUrl ); } @Override protected String getDatabaseName( String connectionUrl ) { String retval = "lportal"; if( !CoreUtil.isNullOrEmpty( connectionUrl ) ) { final int databaseNameBegin = connectionUrl.lastIndexOf( "/" ); //$NON-NLS-1$ if( databaseNameBegin > 0 ) { final String databaseName = connectionUrl.substring( databaseNameBegin + 1 ); if( !CoreUtil.isNullOrEmpty( databaseName ) ) { retval = databaseName; } } } return retval; } } private abstract class LiferayDatabaseConnection { private String connectionDesc; private String connectionUrl; private String driverClass; private String driverTemplate; private String password; private String providerId; private String userName; public LiferayDatabaseConnection( final String driverClass, final String providerId, final String connectinDesc, final String driverTemplate, final String userName, final String password, final String connectionUrl ) { super(); this.driverClass = driverClass; this.providerId = providerId; this.connectionDesc = connectinDesc; this.driverTemplate = driverTemplate; this.userName = userName; this.password = password; this.connectionUrl = connectionUrl; } public void addDatabaseConnectionProfile( String connectionName, String driverPath ) throws ConnectionProfileException { final String uniqueDriverInstanceName = generateUniqueDriverDefinitionName( connectionName ); final DriverInstance driverInstance = DriverManager.getInstance().createNewDriverInstance( driverTemplate, uniqueDriverInstanceName, driverPath, driverClass ); final String vendor = driverInstance.getProperty( IJDBCDriverDefinitionConstants.DATABASE_VENDOR_PROP_ID ); final String uniqueConnectionProfileName = generateUniqueConnectionProfileName( connectionName + " " + vendor ); //$NON-NLS-1$ final Properties connectionProfileProperties = driverInstance.getPropertySet().getBaseProperties(); connectionProfileProperties.setProperty( ConnectionProfileConstants.PROP_DRIVER_DEFINITION_ID, driverInstance.getId() ); connectionProfileProperties.setProperty( IJDBCDriverDefinitionConstants.DATABASE_NAME_PROP_ID, getDatabaseName( connectionUrl ) ); connectionProfileProperties.setProperty( IJDBCDriverDefinitionConstants.USERNAME_PROP_ID, userName ); connectionProfileProperties.setProperty( IJDBCDriverDefinitionConstants.PASSWORD_PROP_ID, password ); connectionProfileProperties.setProperty( IJDBCDriverDefinitionConstants.URL_PROP_ID, connectionUrl ); ProfileManager.getInstance().createProfile( uniqueConnectionProfileName, connectionDesc, providerId, connectionProfileProperties, "", false ); //$NON-NLS-1$ } private String generateUniqueDriverDefinitionName( final String driverDefinitionNameBase ) { int index = 1; String testName = driverDefinitionNameBase; while( DriverManager.getInstance().getDriverInstanceByName( testName ) != null ) { index++; testName = driverDefinitionNameBase + String.valueOf( index ); } return testName; } protected abstract String getDatabaseName( final String connectionUrl ); } private class MysqlLiferayDatabaseConnection extends LiferayDatabaseConnection { public MysqlLiferayDatabaseConnection( final String driverClass, final String providerId, final String connectinDesc, final String driverTemplate, final String userName, final String password, final String connectionUrl ) { super( driverClass, providerId, connectinDesc, driverTemplate, userName, password, connectionUrl ); } protected String getDatabaseName( String connectionUrl ) { String retval = "lportal"; if( !CoreUtil.isNullOrEmpty( connectionUrl ) ) { final int databaseNameEnd = connectionUrl.indexOf( "?" ); //$NON-NLS-1$ if( databaseNameEnd > 0 ) { final String databaseNameTmp = connectionUrl.substring( 0, databaseNameEnd ); if( !CoreUtil.isNullOrEmpty( databaseNameTmp ) ) { final int databaseNameBegin = databaseNameTmp.lastIndexOf( "/" ); //$NON-NLS-1$ if( databaseNameBegin > 0 ) { final String databaseName = connectionUrl.substring( databaseNameBegin + 1, databaseNameEnd ); if( !CoreUtil.isNullOrEmpty( databaseName ) ) { retval = databaseName; } } } } } return retval; } } private class PostgresqlLiferayDatabaseConnection extends LiferayDatabaseConnection { public PostgresqlLiferayDatabaseConnection( final String driverClass, final String providerId, final String connectinDesc, final String driverTemplate, final String userName, final String password, final String connectionUrl ) { super( driverClass, providerId, connectinDesc, driverTemplate, userName, password, connectionUrl ); } @Override protected String getDatabaseName( String connectionUrl ) { String retval = "lportal"; if( !CoreUtil.isNullOrEmpty( connectionUrl ) ) { final int databaseNameBegin = connectionUrl.lastIndexOf( "/" ); //$NON-NLS-1$ if( databaseNameBegin > 0 ) { final String databaseName = connectionUrl.substring( databaseNameBegin + 1 ); if( !CoreUtil.isNullOrEmpty( databaseName ) ) { retval = databaseName; } } } return retval; } } private static class Msgs extends NLS { public static String addDBConnnection; public static String addProfileError; public static String noDatabasePropertyFile; public static String noDBConnectDriver; static { initializeMessages( CreateDBConnectAction.class.getName(), Msgs.class ); } } }