/* * 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 June 2, 2009 * @author mlowery */ package org.pentaho.platform.dataaccess.datasource.ui.selectdialog; import java.util.Collections; import java.util.List; import org.pentaho.metadata.model.Domain; import org.pentaho.platform.dataaccess.datasource.beans.LogicalModelSummary; import org.pentaho.platform.dataaccess.datasource.wizard.IDatasourceEditor; import org.pentaho.platform.dataaccess.datasource.wizard.service.IXulAsyncDatasourceService; import org.pentaho.ui.xul.XulComponent; import org.pentaho.ui.xul.XulException; import org.pentaho.ui.xul.XulServiceCallback; import org.pentaho.ui.xul.binding.Binding; import org.pentaho.ui.xul.binding.BindingConvertor; import org.pentaho.ui.xul.binding.BindingFactory; import org.pentaho.ui.xul.components.XulButton; import org.pentaho.ui.xul.components.XulMessageBox; import org.pentaho.ui.xul.containers.XulDialog; import org.pentaho.ui.xul.containers.XulListbox; import org.pentaho.ui.xul.dom.Document; import org.pentaho.ui.xul.stereotype.Bindable; import org.pentaho.ui.xul.util.AbstractXulDialogController; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.ui.RootPanel; public class DatasourceSelectionDialogController extends AbstractXulDialogController<LogicalModelSummary> { // ~ Static fields/initializers ====================================================================================== // ~ Instance fields ================================================================================================= private BindingFactory bf; private IXulAsyncDatasourceService datasourceService; private DatasourceSelectionDialogModel datasourceSelectionDialogModel = new DatasourceSelectionDialogModel(); private XulDialog datasourceSelectionDialog; private XulDialog removeDatasourceConfirmationDialog; private boolean administrator; /** * The controller for the datasource dialog, which is shown when the user clicks the Add button in this dialog. */ private IDatasourceEditor datasourceEditor; private XulButton addDatasourceButton; private XulButton editDatasourceButton; private XulButton removeDatasourceButton; private XulListbox datasourceListbox; private Binding editDatasourceButtonBinding; private Binding removeDatasourceButtonBinding; // ~ Constructors ==================================================================================================== public DatasourceSelectionDialogController() { } // ~ Methods ========================================================================================================= /** * Sets up bindings. */ @Bindable public void init() { internalInit(); datasourceService.hasPermission(new XulServiceCallback<Boolean>() { public void error(final String message, final Throwable error) { showMessagebox("Error", error.getLocalizedMessage()); //$NON-NLS-1$ } public void success(final Boolean administrator) { // now we have admin status; update add datasource and remove datasource buttons' enabled status DatasourceSelectionDialogController.this.administrator = administrator; addDatasourceButton.setVisible(administrator); editDatasourceButton.setVisible(administrator); removeDatasourceButton.setVisible(administrator); try { removeDatasourceButtonBinding.fireSourceChanged(); editDatasourceButtonBinding.fireSourceChanged(); } catch (Exception e) { showMessagebox("Error", e.getLocalizedMessage()); //$NON-NLS-1$ } } }); } private void internalInit() { try { datasourceListbox = (XulListbox) safeGetElementById(document, "datasourceListbox"); //$NON-NLS-1$ datasourceSelectionDialog = (XulDialog) safeGetElementById(document, "datasourceSelectionDialog"); //$NON-NLS-1$ removeDatasourceConfirmationDialog = (XulDialog) safeGetElementById(document, "removeDatasourceConfirmationDialog"); //$NON-NLS-1$ XulButton acceptButton = (XulButton) safeGetElementById(document, "datasourceSelectionDialog_accept"); //$NON-NLS-1$ addDatasourceButton = (XulButton) safeGetElementById(document, "addDatasource"); //$NON-NLS-1$ editDatasourceButton = (XulButton) safeGetElementById(document, "editDatasource"); //$NON-NLS-1$ removeDatasourceButton = (XulButton) safeGetElementById(document, "removeDatasource"); //$NON-NLS-1$ bf.setBindingType(Binding.Type.ONE_WAY); bf.createBinding(DatasourceSelectionDialogController.this.datasourceSelectionDialogModel, "logicalModelSummaries", datasourceListbox, "elements"); //$NON-NLS-1$ //$NON-NLS-2$ bf.setBindingType(Binding.Type.ONE_WAY); bf.createBinding(datasourceListbox, "selectedIndex", //$NON-NLS-1$ DatasourceSelectionDialogController.this.datasourceSelectionDialogModel, "selectedIndex"); //$NON-NLS-1$ // setup binding to disable accept button until user selects a datasource bf.setBindingType(Binding.Type.ONE_WAY); BindingConvertor<Integer, Boolean> acceptButtonConvertor = new BindingConvertor<Integer, Boolean>() { @Override public Boolean sourceToTarget(final Integer value) { return value > -1; } @Override public Integer targetToSource(final Boolean value) { throw new UnsupportedOperationException(); } }; bf.createBinding(DatasourceSelectionDialogController.this.datasourceSelectionDialogModel, "selectedIndex", //$NON-NLS-1$ acceptButton, "!disabled", acceptButtonConvertor); //$NON-NLS-1$ // setup binding to disable remove datasource button until user selects a datasource bf.setBindingType(Binding.Type.ONE_WAY); BindingConvertor<Integer, Boolean> removeDatasourceButtonConvertor = new BindingConvertor<Integer, Boolean>() { @Override public Boolean sourceToTarget(final Integer value) { return value > -1 && administrator; } @Override public Integer targetToSource(final Boolean value) { throw new UnsupportedOperationException(); } }; removeDatasourceButtonBinding = bf.createBinding(DatasourceSelectionDialogController.this.datasourceSelectionDialogModel, "selectedIndex", //$NON-NLS-1$ removeDatasourceButton, "!disabled", removeDatasourceButtonConvertor); //$NON-NLS-1$ BindingConvertor<Integer, Boolean> editDatasourceButtonConvertor = new BindingConvertor<Integer, Boolean>() { @Override public Boolean sourceToTarget(final Integer value) { return value > -1 && administrator && datasourceSelectionDialogModel.getLogicalModelSummaries().get(value).getModelId().equals("MODEL_1") //$NON-NLS-1$ ; } @Override public Integer targetToSource(final Boolean value) { throw new UnsupportedOperationException(); } }; editDatasourceButtonBinding = bf.createBinding(DatasourceSelectionDialogController.this.datasourceSelectionDialogModel, "selectedIndex", //$NON-NLS-1$ editDatasourceButton, "!disabled", editDatasourceButtonConvertor); //$NON-NLS-1$ datasourceListbox.setSelectedIndex(-1); // workaround for bug in some XulListbox implementations (doesn't fire event on setSelectedIndex call) DatasourceSelectionDialogController.this.datasourceSelectionDialogModel.setSelectedIndex(-1); } catch (Exception e) { e.printStackTrace(); showMessagebox("Error", e.getLocalizedMessage()); //$NON-NLS-1$ } refreshDatasources(null, null); } /** * Shows a informational dialog. * * @param title * title of dialog * @param message * message within dialog */ private void showMessagebox(final String title, final String message) { XulMessageBox messagebox = null; try { messagebox = (XulMessageBox) document.createElement("messagebox"); //$NON-NLS-1$ } catch (XulException e) { e.printStackTrace(); } messagebox.setTitle(title); messagebox.setMessage(message); messagebox.open(); } /** * A fail-quickly version of <code>getElementById()</code>. */ private XulComponent safeGetElementById(final Document doc, final String id) { XulComponent elem = doc.getElementById(id); if (elem != null) { return elem; } else { throw new NullPointerException("element with id \"" + id + "\" is null"); //$NON-NLS-1$ //$NON-NLS-2$ } } private void refreshDatasources(final String domainId, final String modelId) { datasourceService.getLogicalModels(new XulServiceCallback<List<LogicalModelSummary>>() { public void error(final String message, final Throwable error) { System.out.println(message); } public void success(final List<LogicalModelSummary> logicalModelSummaries) { Collections.sort(logicalModelSummaries); datasourceSelectionDialogModel.setLogicalModelSummaries(logicalModelSummaries); if (domainId != null && modelId != null) { datasourceSelectionDialogModel.setSelectedLogicalModel(domainId, modelId); datasourceListbox.setSelectedIndex(datasourceSelectionDialogModel.getSelectedIndex()); } else if (logicalModelSummaries.isEmpty()) { datasourceListbox.setSelectedIndex(-1); datasourceSelectionDialogModel.setSelectedIndex(-1); } else { datasourceListbox.setSelectedIndex(0); datasourceSelectionDialogModel.setSelectedIndex(0); } } }); // test code...... // List<IDatasource> datasourceList = new ArrayList<IDatasource>(); // IDatasource ds = new Datasource(); // ds.setDatasourceName("hello"); // datasourceList.add(ds); // ds = new Datasource(); // ds.setDatasourceName("goodbye"); // datasourceList.add(ds); // DatasourceSelectionDialogController.this.datasourceSelectionDialogModel.setDatasources(datasourceList); } /** * ID of this controller. This is how event handlers are referenced in <code>.xul</code> files. */ @Override public String getName() { return "datasourceSelectionDialogController"; //$NON-NLS-1$ } public void setBindingFactory(final BindingFactory bf) { this.bf = bf; } public void setDatasourceService(final IXulAsyncDatasourceService datasourceService) { this.datasourceService = datasourceService; } /** * @return selected datasource or <code>null</code> if no selected datasource */ @Override protected LogicalModelSummary getDialogResult() { int selectedIndex = datasourceSelectionDialogModel.getSelectedIndex(); if (selectedIndex > -1) { return datasourceSelectionDialogModel.getLogicalModelSummaries().get(selectedIndex); } else { return null; } } @Override protected XulDialog getDialog() { return datasourceSelectionDialog; } public void setDatasourceDialogController(final IDatasourceEditor gwtDatasourceEditor) { this.datasourceEditor = gwtDatasourceEditor; } private void enableWaitCursor(final boolean enable) { if (enable) { DOM.setStyleAttribute(RootPanel.get().getElement(), "cursor", "wait"); } else { DOM.setStyleAttribute(RootPanel.get().getElement(), "cursor", "default"); } } @Bindable public void addDatasource() { enableWaitCursor(true); datasourceEditor.addDialogListener(new DialogListener<Domain>() { public void onDialogAccept(final Domain domain) { refreshDatasources(domain.getId(), domain.getLogicalModels().get(0).getId()); } public void onDialogCancel() { } public void onDialogReady() { enableWaitCursor(false); } }); datasourceEditor.showDialog(); } @Bindable public void editDatasource() { // logicalModelSummary.getDomainId(), logicalModelSummary.getModelId() enableWaitCursor(true); datasourceEditor.addDialogListener(new DialogListener<Domain>() { public void onDialogAccept(final Domain domain) { refreshDatasources(domain.getId(), domain.getLogicalModels().get(0).getId()); } public void onDialogCancel() { } public void onDialogReady() { enableWaitCursor(false); } }); LogicalModelSummary logicalModelSummary = getDialogResult(); datasourceEditor.showEditDialog(logicalModelSummary.getDomainId(), logicalModelSummary.getModelId()); } @Bindable public void removeDatasourceConfirm() { removeDatasourceConfirmationDialog.show(); } @Bindable public void removeDatasourceCancel() { removeDatasourceConfirmationDialog.hide(); } @Bindable public void removeDatasourceAccept() { LogicalModelSummary logicalModelSummary = getDialogResult(); datasourceService.deleteLogicalModel(logicalModelSummary.getDomainId(), logicalModelSummary.getModelId(), new XulServiceCallback<Boolean>() { public void error(String message, Throwable error) { showMessagebox("Error", error.getLocalizedMessage()); //$NON-NLS-1$ } public void success(Boolean retVal) { refreshDatasources(null, null); removeDatasourceConfirmationDialog.hide(); } }); } }