/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jkiss.dbeaver.ui.dialogs.connection;
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.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.osgi.util.NLS;
import org.eclipse.ui.INewWizard;
import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.core.CoreMessages;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.DBPDataSourceInfo;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration;
import org.jkiss.dbeaver.model.exec.DBCSession;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
import org.jkiss.dbeaver.registry.driver.DriverDescriptor;
import org.jkiss.dbeaver.runtime.jobs.ConnectJob;
import org.jkiss.dbeaver.runtime.jobs.DisconnectJob;
import org.jkiss.dbeaver.ui.UIUtils;
import org.jkiss.dbeaver.utils.GeneralUtils;
import org.jkiss.dbeaver.utils.RuntimeUtils;
import org.jkiss.utils.CommonUtils;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.util.HashMap;
import java.util.Map;
/**
* Abstract connection wizard
*/
public abstract class ConnectionWizard extends Wizard implements INewWizard {
private static final Log log = Log.getLog(ConnectionWizard.class);
// protected final IProject project;
private final Map<DriverDescriptor, DataSourceDescriptor> infoMap = new HashMap<>();
private boolean resized = false;
protected ConnectionWizard()
{
setNeedsProgressMonitor(true);
}
@Override
public void dispose() {
// Dispose all temp data sources
for (DataSourceDescriptor dataSource : infoMap.values()) {
dataSource.dispose();
}
super.dispose();
}
abstract public DBPDataSourceRegistry getDataSourceRegistry();
abstract DriverDescriptor getSelectedDriver();
public abstract ConnectionPageSettings getPageSettings();
protected abstract void saveSettings(DataSourceDescriptor dataSource);
@NotNull
public DataSourceDescriptor getActiveDataSource()
{
DriverDescriptor driver = getSelectedDriver();
DataSourceDescriptor info = infoMap.get(driver);
if (info == null) {
DBPConnectionConfiguration connectionInfo = new DBPConnectionConfiguration();
info = new DataSourceDescriptor(
getDataSourceRegistry(),
DataSourceDescriptor.generateNewId(getSelectedDriver()),
getSelectedDriver(),
connectionInfo);
info.getConnectionConfiguration().setClientHomeId(driver.getDefaultClientHomeId());
infoMap.put(driver, info);
}
return info;
}
public DataSourceDescriptor getOriginalDataSource() {
return null;
}
public void testConnection()
{
DataSourceDescriptor dataSource = getPageSettings().getActiveDataSource();
DataSourceDescriptor testDataSource = new DataSourceDescriptor(dataSource);
saveSettings(testDataSource);
// Generate new ID to avoid session conflicts in QM
testDataSource.setId(DataSourceDescriptor.generateNewId(dataSource.getDriver()));
try {
final ConnectionTester op = new ConnectionTester(testDataSource);
try {
getContainer().run(true, true, new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
// Wait for job to finish
op.ownerMonitor = RuntimeUtils.makeMonitor(monitor);
op.schedule();
while (op.getState() == Job.WAITING || op.getState() == Job.RUNNING) {
if (monitor.isCanceled()) {
op.cancel();
throw new InterruptedException();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
break;
}
}
if (op.getConnectError() != null) {
throw new InvocationTargetException(op.getConnectError());
}
if (op.getConnectStatus() == Status.CANCEL_STATUS) {
throw new InterruptedException();
}
}
});
String message = "";
if (!CommonUtils.isEmpty(op.productName)) {
message += "Server: " + op.productName + " " + op.productVersion + "\n";
}
if (!CommonUtils.isEmpty(op.driverName)) {
message += "Driver: " + op.driverName + " " + op.driverVersion + "\n";
}
if (!CommonUtils.isEmpty(message)) {
message += "\n";
}
message += NLS.bind(CoreMessages.dialog_connection_wizard_start_connection_monitor_connected, op.connectTime);
MessageDialog.openInformation(getShell(), CoreMessages.dialog_connection_wizard_start_connection_monitor_success,
message);
} catch (InterruptedException ex) {
UIUtils.showErrorDialog(getShell(), CoreMessages.dialog_connection_wizard_start_dialog_interrupted_title,
CoreMessages.dialog_connection_wizard_start_dialog_interrupted_message);
} catch (InvocationTargetException ex) {
UIUtils.showErrorDialog(
getShell(),
CoreMessages.dialog_connection_wizard_start_dialog_error_title,
null,
GeneralUtils.makeExceptionStatus(ex.getTargetException()));
}
} finally {
testDataSource.dispose();
}
}
public boolean isNew()
{
return false;
}
private class ConnectionTester extends ConnectJob {
String productName;
String productVersion;
String driverName;
String driverVersion;
long connectTime = -1;
DBRProgressMonitor ownerMonitor;
public ConnectionTester(DataSourceDescriptor testDataSource)
{
super(testDataSource);
setSystem(true);
super.initialize = true;//CommonUtils.toBoolean(testDataSource.getDriver().getDriverParameter(DBConstants.PARAM_INIT_ON_TEST));
productName = null;
productVersion = null;
}
@Override
public IStatus run(DBRProgressMonitor monitor)
{
if (ownerMonitor != null) {
monitor = ownerMonitor;
}
monitor.beginTask(CoreMessages.dialog_connection_wizard_start_connection_monitor_start, 4);
Thread.currentThread().setName(CoreMessages.dialog_connection_wizard_start_connection_monitor_thread);
try {
container.setName(container.getConnectionConfiguration().getUrl());
monitor.worked(1);
long startTime = System.currentTimeMillis();
super.run(monitor);
connectTime = (System.currentTimeMillis() - startTime);
if (connectError != null || monitor.isCanceled()) {
return Status.OK_STATUS;
}
if (connectStatus == Status.CANCEL_STATUS) {
return Status.CANCEL_STATUS;
}
monitor.worked(1);
DBPDataSource dataSource = container.getDataSource();
if (dataSource == null) {
throw new DBException(CoreMessages.editors_sql_status_not_connected_to_database);
}
monitor.subTask(CoreMessages.dialog_connection_wizard_start_connection_monitor_subtask_test);
DBPDataSourceInfo info = dataSource.getInfo();
if (info != null) {
try {
productName = info.getDatabaseProductName();
productVersion = info.getDatabaseProductVersion();
driverName = info.getDriverName();
driverVersion = info.getDriverVersion();
} catch (Exception e) {
log.error("Can't obtain connection metadata", e);
}
} else {
try (DBCSession session = DBUtils.openUtilSession(monitor, dataSource, "Test connection")) {
if (session instanceof Connection) {
try {
Connection connection = (Connection) session;
DatabaseMetaData metaData = connection.getMetaData();
productName = metaData.getDatabaseProductName();
productVersion = metaData.getDatabaseProductVersion();
driverName = metaData.getDriverName();
driverVersion = metaData.getDriverVersion();
} catch (Exception e) {
log.error("Can't obtain connection metadata", e);
}
}
}
}
new DisconnectJob(container).schedule();
monitor.subTask(CoreMessages.dialog_connection_wizard_start_connection_monitor_success);
} catch (DBException ex) {
connectError = ex;
}
monitor.done();
return Status.OK_STATUS;
}
}
}