Java tutorial
/* * 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.controllers; import java.util.ArrayList; import java.util.List; import org.pentaho.database.model.DatabaseConnection; import org.pentaho.database.model.IDatabaseConnection; import org.pentaho.database.model.IDatabaseType; import org.pentaho.database.util.DatabaseTypeHelper; import org.pentaho.platform.dataaccess.datasource.beans.AutobeanUtilities; import org.pentaho.platform.dataaccess.datasource.utils.ExceptionParser; import org.pentaho.platform.dataaccess.datasource.wizard.ConnectionDialogListener; import org.pentaho.platform.dataaccess.datasource.wizard.models.DatasourceModel; import org.pentaho.ui.database.event.DatabaseDialogListener; import org.pentaho.ui.database.event.IConnectionAutoBeanFactory; import org.pentaho.ui.database.gwt.GwtDatabaseDialog; import org.pentaho.ui.database.gwt.GwtXulAsyncDatabaseDialectService; import org.pentaho.ui.xul.XulServiceCallback; import org.pentaho.ui.xul.components.XulLabel; import org.pentaho.ui.xul.containers.XulDialog; import org.pentaho.ui.xul.containers.XulHbox; import org.pentaho.ui.xul.dom.Document; import org.pentaho.ui.xul.impl.AbstractXulEventHandler; import org.pentaho.ui.xul.stereotype.Bindable; import com.google.gwt.core.client.GWT; import com.google.gwt.http.client.Request; import com.google.gwt.http.client.RequestBuilder; import com.google.gwt.http.client.RequestCallback; import com.google.gwt.http.client.RequestException; import com.google.gwt.http.client.Response; import com.google.web.bindery.autobean.shared.AutoBean; import com.google.web.bindery.autobean.shared.AutoBeanCodex; import com.google.web.bindery.autobean.shared.AutoBeanUtils; public class WizardConnectionController extends AbstractXulEventHandler { // private IXulAsyncConnectionService connectionService; private List<ConnectionDialogListener> listeners = new ArrayList<ConnectionDialogListener>(); private DatasourceModel datasourceModel; private XulDialog removeConfirmationDialog; private XulDialog saveConnectionConfirmationDialog; private XulDialog overwriteConnectionConfirmationDialog; private XulDialog renameConnectionConfirmationDialog; private XulDialog errorDialog; private XulDialog errorDetailsDialog; private XulDialog successDialog; private XulDialog successDetailsDialog; private XulLabel errorLabel = null; private XulLabel successLabel = null; // GwtXulAsyncDatabaseConnectionService connService = new GwtXulAsyncDatabaseConnectionService(); GwtXulAsyncDatabaseDialectService dialectService = new GwtXulAsyncDatabaseDialectService(); GwtDatabaseDialog databaseDialog; DatabaseTypeHelper databaseTypeHelper; IDatabaseConnection currentConnection; ConnectionSetter connectionSetter = new ConnectionSetter(); protected IConnectionAutoBeanFactory connectionAutoBeanFactory; protected String previousConnectionName, existingConnectionName; public WizardConnectionController(Document document) { this.document = document; connectionAutoBeanFactory = GWT.create(IConnectionAutoBeanFactory.class); init(); } protected void copyDatabaseConnectionProperties(IDatabaseConnection source, IDatabaseConnection target) { target.setId(source.getId()); target.setAccessType(source.getAccessType()); target.setDatabaseType(source.getDatabaseType()); target.setExtraOptions(source.getExtraOptions()); target.setName(source.getName()); target.setHostname(source.getHostname()); target.setDatabaseName(source.getDatabaseName()); target.setDatabasePort(source.getDatabasePort()); target.setUsername(source.getUsername()); target.setPassword(source.getPassword()); target.setStreamingResults(source.isStreamingResults()); target.setDataTablespace(source.getDataTablespace()); target.setIndexTablespace(source.getIndexTablespace()); target.setSQLServerInstance(source.getSQLServerInstance()); target.setUsingDoubleDecimalAsSchemaTableSeparator(source.isUsingDoubleDecimalAsSchemaTableSeparator()); target.setInformixServername(source.getInformixServername()); //target.addExtraOption(String databaseTypeCode, String option, String value); target.setAttributes(source.getAttributes()); target.setChanged(source.getChanged()); target.setQuoteAllFields(source.isQuoteAllFields()); // advanced option (convert to enum with upper, lower, none?) target.setForcingIdentifiersToLowerCase(source.isForcingIdentifiersToLowerCase()); target.setForcingIdentifiersToUpperCase(source.isForcingIdentifiersToUpperCase()); target.setConnectSql(source.getConnectSql()); target.setUsingConnectionPool(source.isUsingConnectionPool()); target.setInitialPoolSize(source.getInitialPoolSize()); target.setMaximumPoolSize(source.getMaximumPoolSize()); target.setPartitioned(source.isPartitioned()); target.setConnectionPoolingProperties(source.getConnectionPoolingProperties()); target.setPartitioningInformation(source.getPartitioningInformation()); } protected AutoBean<IDatabaseConnection> createIDatabaseConnectionBean(IDatabaseConnection connection) { AutoBean<IDatabaseConnection> bean = connectionAutoBeanFactory.iDatabaseConnection(); IDatabaseConnection connectionBean = bean.as(); copyDatabaseConnectionProperties(connection, connectionBean); return AutoBeanUtils.getAutoBean(connectionBean); //return connectionBean; } @Bindable public void init() { XulServiceCallback<List<IDatabaseType>> callback = new XulServiceCallback<List<IDatabaseType>>() { public void error(String message, Throwable error) { error.printStackTrace(); } public void success(List<IDatabaseType> retVal) { databaseTypeHelper = new DatabaseTypeHelper(retVal); } }; dialectService.getDatabaseTypes(callback); saveConnectionConfirmationDialog = (XulDialog) document.getElementById("saveConnectionConfirmationDialog"); //$NON-NLS-1$ overwriteConnectionConfirmationDialog = (XulDialog) document .getElementById("overwriteConnectionConfirmationDialog"); renameConnectionConfirmationDialog = (XulDialog) document .getElementById("renameConnectionConfirmationDialog"); errorDialog = (XulDialog) document.getElementById("errorDialog"); //$NON-NLS-1$ errorDetailsDialog = (XulDialog) document.getElementById("errorDetailsDialog"); //$NON-NLS-1$ errorLabel = (XulLabel) document.getElementById("errorLabel");//$NON-NLS-1$ successDialog = (XulDialog) document.getElementById("successDialog"); //$NON-NLS-1$ successDetailsDialog = (XulDialog) document.getElementById("successDetailsDialog"); //$NON-NLS-1$ successLabel = (XulLabel) document.getElementById("successLabel");//$NON-NLS-1$ removeConfirmationDialog = (XulDialog) document.getElementById("removeConfirmationDialog"); //$NON-NLS-1$ } @Bindable public void openErrorDialog(String title, String message) { errorDialog.setTitle(title); errorLabel.setValue(message); errorDialog.show(); } @Bindable public void closeErrorDialog() { if (!errorDialog.isHidden()) { errorDialog.hide(); } } @Bindable public void closeSuccessDetailsDialog() { if (!successDetailsDialog.isHidden()) { successDetailsDialog.hide(); } } @Bindable public void toggleDetails() { XulHbox details = (XulHbox) document.getElementById("details_hider"); //$NON-NLS-1$ details.setVisible(!details.isVisible()); } @Bindable public void openSuccesDialog(String title, String message) { successDialog.setTitle(title); successLabel.setValue(message); successDialog.show(); } @Bindable public void closeSuccessDialog() { if (!successDialog.isHidden()) { successDialog.hide(); } } @Bindable public void toggleSuccessDetails() { XulHbox details = (XulHbox) document.getElementById("success_details_hider"); //$NON-NLS-1$ details.setVisible(!details.isVisible()); } @Bindable public void closeErrorDetailsDialog() { if (!errorDetailsDialog.isHidden()) { errorDetailsDialog.hide(); } } public void setDatasourceModel(DatasourceModel model) { this.datasourceModel = model; } public DatasourceModel getDatasourceModel() { return this.datasourceModel; } public String getName() { return "wizardConnectionController";//$NON-NLS-1$ } @Bindable public void closeDialog() { for (ConnectionDialogListener listener : listeners) { listener.onDialogCancel(); } } @Bindable public void handleDialogAccept() { //first, test the connection RequestBuilder testConnectionBuilder = new RequestBuilder(RequestBuilder.PUT, ConnectionController.getServiceURL("test")); testConnectionBuilder.setHeader("Content-Type", "application/json"); try { //AutoBean<IDatabaseConnection> bean = AutoBeanUtils.getAutoBean(currentConnection); AutoBean<IDatabaseConnection> bean = createIDatabaseConnectionBean(currentConnection); testConnectionBuilder.sendRequest(AutoBeanCodex.encode(bean).getPayload(), new RequestCallback() { @Override public void onError(Request request, Throwable exception) { saveConnectionConfirmationDialog.show(); } @Override public void onResponseReceived(Request request, Response response) { try { if (response.getStatusCode() == Response.SC_OK) { //test is ok, now check if we are renaming renameCheck(); } else { //confirm if we should continu saving this invalid connection. saveConnectionConfirmationDialog.show(); } } catch (Exception e) { displayErrorMessage(e); } } }); } catch (RequestException e) { displayErrorMessage(e); } } @Bindable public void renameCheck() { if (!saveConnectionConfirmationDialog.isHidden()) closeSaveConnectionConfirmationDialog(); if (datasourceModel.isEditing() && !previousConnectionName.equals(currentConnection.getName())) { showRenameConnectionConfirmationDialog(); } else { overwriteCheck(); } } @Bindable public void overwriteCheck() { if (!saveConnectionConfirmationDialog.isHidden()) closeSaveConnectionConfirmationDialog(); if (!renameConnectionConfirmationDialog.isHidden()) closeRenameConnectionConfirmationDialog(); if (datasourceModel.isEditing() && previousConnectionName.equals(currentConnection.getName())) { //if editing and no name change, proceed. updateConnection(); } else { //either new connection, or editing involved a name change. RequestBuilder getConnectionBuilder = new RequestBuilder(RequestBuilder.GET, ConnectionController .getServiceURL("get", new String[][] { { "name", currentConnection.getName() } })); getConnectionBuilder.setHeader("Content-Type", "application/json"); try { AutoBean<IDatabaseConnection> bean = createIDatabaseConnectionBean(currentConnection); getConnectionBuilder.sendRequest(AutoBeanCodex.encode(bean).getPayload(), new RequestCallback() { public void onResponseReceived(Request request, Response response) { switch (response.getStatusCode()) { case Response.SC_OK: showOverwriteConnectionConfirmationDialog(); break; case Response.SC_NOT_FOUND: saveConnection(); break; default: //TODO: error message saveConnection(); } } public void onError(Request request, Throwable exception) { displayErrorMessage(exception); } }); } catch (Exception e) { displayErrorMessage(e); } } } @Bindable public void updateConnection() { RequestBuilder updateConnectionBuilder = new RequestBuilder(RequestBuilder.POST, ConnectionController.getServiceURL("update")); updateConnectionBuilder.setHeader("Content-Type", "application/json"); try { //AutoBean<IDatabaseConnection> bean = AutoBeanUtils.getAutoBean(currentConnection); AutoBean<IDatabaseConnection> bean = createIDatabaseConnectionBean(currentConnection); updateConnectionBuilder.sendRequest(AutoBeanCodex.encode(bean).getPayload(), new RequestCallback() { @Override public void onError(Request request, Throwable exception) { displayErrorMessage(exception); } @Override public void onResponseReceived(Request request, Response response) { try { if (response.getStatusCode() == Response.SC_OK) { datasourceModel.getGuiStateModel().updateConnection(existingConnectionName, currentConnection); datasourceModel.setSelectedRelationalConnection(currentConnection); } else { openErrorDialog(MessageHandler.getString("ERROR"), MessageHandler//$NON-NLS-1$ .getString("ConnectionController.ERROR_0004_UNABLE_TO_UPDATE_CONNECTION"));//$NON-NLS-1$ } } catch (Exception e) { displayErrorMessage(e); } } }); } catch (RequestException e) { displayErrorMessage(e); } } @Bindable public void addConnection() { RequestBuilder addConnectionBuilder = new RequestBuilder(RequestBuilder.POST, ConnectionController.getServiceURL("add")); addConnectionBuilder.setHeader("Content-Type", "application/json"); try { //AutoBean<IDatabaseConnection> bean = AutoBeanUtils.getAutoBean(currentConnection); AutoBean<IDatabaseConnection> bean = createIDatabaseConnectionBean(currentConnection); addConnectionBuilder.sendRequest(AutoBeanCodex.encode(bean).getPayload(), new RequestCallback() { @Override public void onError(Request request, Throwable exception) { displayErrorMessage(exception); } @Override public void onResponseReceived(Request request, Response response) { try { if (response.getStatusCode() == Response.SC_OK) { IDatabaseConnection conn = AutobeanUtilities.connectionBeanToImpl(currentConnection); datasourceModel.getGuiStateModel().addConnection(conn); datasourceModel.setSelectedRelationalConnection(conn); } else { openErrorDialog(MessageHandler.getString("ERROR"), MessageHandler//$NON-NLS-1$ .getString("ConnectionController.ERROR_0001_UNABLE_TO_ADD_CONNECTION"));//$NON-NLS-1$ } } catch (Exception e) { displayErrorMessage(e); } } }); } catch (RequestException e) { displayErrorMessage(e); } } @Bindable public void overwriteConnection() { if (!saveConnectionConfirmationDialog.isHidden()) closeSaveConnectionConfirmationDialog(); if (!renameConnectionConfirmationDialog.isHidden()) closeRenameConnectionConfirmationDialog(); if (!overwriteConnectionConfirmationDialog.isHidden()) overwriteConnectionConfirmationDialog.hide(); existingConnectionName = currentConnection.getName(); updateConnection(); } @Bindable public void saveConnection() { if (!saveConnectionConfirmationDialog.isHidden()) closeSaveConnectionConfirmationDialog(); if (!renameConnectionConfirmationDialog.isHidden()) closeRenameConnectionConfirmationDialog(); if (!overwriteConnectionConfirmationDialog.isHidden()) overwriteConnectionConfirmationDialog.hide(); if (datasourceModel.isEditing()) updateConnection(); else addConnection(); } @Bindable public void testConnection() { RequestBuilder testConnectionBuilder = new RequestBuilder(RequestBuilder.PUT, ConnectionController.getServiceURL("test")); testConnectionBuilder.setHeader("Content-Type", "application/json"); try { //AutoBean<IDatabaseConnection> bean = AutoBeanUtils.getAutoBean(currentConnection); AutoBean<IDatabaseConnection> bean = createIDatabaseConnectionBean(currentConnection); testConnectionBuilder.sendRequest(AutoBeanCodex.encode(bean).getPayload(), new RequestCallback() { @Override public void onError(Request request, Throwable exception) { displayErrorMessage(exception); } @Override public void onResponseReceived(Request request, Response response) { Boolean testPassed = new Boolean(response.getText()); try { if (testPassed) { openSuccesDialog(MessageHandler.getString("SUCCESS"), MessageHandler//$NON-NLS-1$ .getString("ConnectionController.CONNECTION_TEST_SUCCESS"));//$NON-NLS-1$ } else { openErrorDialog(MessageHandler.getString("ERROR"), MessageHandler//$NON-NLS-1$ .getString("ConnectionController.ERROR_0003_CONNECTION_TEST_FAILED"));//$NON-NLS-1$ } } catch (Exception e) { displayErrorMessage(e); } } }); } catch (RequestException e) { displayErrorMessage(e); } } @Bindable public void deleteConnection() { removeConfirmationDialog.hide(); RequestBuilder deleteConnectionBuilder = new RequestBuilder(RequestBuilder.DELETE, ConnectionController.getServiceURL("deletebyname", new String[][] { { "name", datasourceModel.getSelectedRelationalConnection().getName() } })); try { deleteConnectionBuilder.sendRequest(null, new RequestCallback() { @Override public void onError(Request request, Throwable exception) { displayErrorMessage(exception); } @Override public void onResponseReceived(Request request, Response response) { try { if (response.getStatusCode() == Response.SC_OK) { openSuccesDialog(MessageHandler.getString("SUCCESS"), MessageHandler//$NON-NLS-1$ .getString("ConnectionController.CONNECTION_DELETED"));//$NON-NLS-1$ datasourceModel.getGuiStateModel() .deleteConnection(datasourceModel.getSelectedRelationalConnection().getName()); List<IDatabaseConnection> connections = datasourceModel.getGuiStateModel() .getConnections(); if (connections != null && connections.size() > 0) { datasourceModel .setSelectedRelationalConnection(connections.get(connections.size() - 1)); } else { datasourceModel.setSelectedRelationalConnection(null); } } else { openErrorDialog(MessageHandler.getString("ERROR"), MessageHandler//$NON-NLS-1$ .getString("ConnectionController.ERROR_0002_UNABLE_TO_DELETE_CONNECTION"));//$NON-NLS-1$ } } catch (Exception e) { displayErrorMessage(e); } } }); } catch (RequestException e) { displayErrorMessage(e); } } public void addConnectionDialogListener(ConnectionDialogListener listener) { if (listeners.contains(listener) == false) { listeners.add(listener); } } public void removeConnectionDialogListener(ConnectionDialogListener listener) { if (listeners.contains(listener)) { listeners.remove(listener); } } public void displayErrorMessage(Throwable th) { errorDialog.setTitle( ExceptionParser.getErrorHeader(th, MessageHandler.getString("DatasourceEditor.USER_ERROR_TITLE")));//$NON-NLS-1$ errorLabel.setValue(ExceptionParser.getErrorMessage(th, MessageHandler.getString("DatasourceEditor.ERROR_0001_UNKNOWN_ERROR_HAS_OCCURED")));//$NON-NLS-1$ errorDialog.show(); } @Bindable public void onDialogAccept(IDatabaseConnection databaseConnection) { currentConnection = databaseConnection; addConnection(); } @Bindable public void onDialogCancel() { // do nothing } @Bindable public void onDialogReady() { if (datasourceModel.isEditing()) { showEditConnectionDialog(); } else { showAddConnectionDialog(); } } @Bindable public void showAddConnectionDialog() { datasourceModel.setEditing(false); if (databaseDialog != null) { previousConnectionName = null; existingConnectionName = previousConnectionName; databaseDialog.setDatabaseConnection(null); databaseDialog.show(); } else { databaseDialog = new GwtDatabaseDialog(databaseTypeHelper, GWT.getModuleBaseURL() + "dataaccess-databasedialog.xul", connectionSetter); //$NON-NLS-1$ } } @Bindable public void showEditConnectionDialog() { datasourceModel.setEditing(true); if (databaseDialog != null) { IDatabaseConnection connection = datasourceModel.getSelectedRelationalConnection(); previousConnectionName = connection.getName(); existingConnectionName = previousConnectionName; DatabaseConnection editConnection = new DatabaseConnection(); copyDatabaseConnectionProperties(connection, editConnection); databaseDialog.setDatabaseConnection(editConnection); databaseDialog.show(); } else { databaseDialog = new GwtDatabaseDialog(databaseTypeHelper, GWT.getModuleBaseURL() + "dataaccess-databasedialog.xul", connectionSetter); //$NON-NLS-1$ } } @Bindable public void showRemoveConnectionDialog() { // Display the warning message. // If ok then remove the connection from the list removeConfirmationDialog.show(); } @Bindable public void closeSaveConnectionConfirmationDialog() { saveConnectionConfirmationDialog.hide(); } @Bindable public void closeRemoveConfirmationDialog() { removeConfirmationDialog.hide(); } public void showRenameConnectionConfirmationDialog() { renameConnectionConfirmationDialog.show(); } @Bindable public void closeRenameConnectionConfirmationDialog() { renameConnectionConfirmationDialog.hide(); } public void showOverwriteConnectionConfirmationDialog() { overwriteConnectionConfirmationDialog.show(); } @Bindable public void closeOverwriteConnectionConfirmationDialog() { overwriteConnectionConfirmationDialog.hide(); } class ConnectionSetter implements DatabaseDialogListener { /* (non-Javadoc) * @see org.pentaho.ui.database.event.DatabaseDialogListener#onDialogAccept(org.pentaho.database.model.IDatabaseConnection) */ public void onDialogAccept(IDatabaseConnection connection) { currentConnection = connection; handleDialogAccept(); } /* (non-Javadoc) * @see org.pentaho.ui.database.event.DatabaseDialogListener#onDialogCancel() */ public void onDialogCancel() { // do nothing } /* (non-Javadoc) * @see org.pentaho.ui.database.event.DatabaseDialogListener#onDialogReady() */ public void onDialogReady() { if (datasourceModel.isEditing()) { showEditConnectionDialog(); } else { showAddConnectionDialog(); } } } }