com.liferay.ide.server.ui.action.CreateDBConnectAction.java Source code

Java tutorial

Introduction

Here is the source code for com.liferay.ide.server.ui.action.CreateDBConnectAction.java

Source

/*******************************************************************************
 * 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);
        }
    }
}