/* * 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; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JavaScriptObject; import org.pentaho.agilebi.modeler.ModelerPerspective; import org.pentaho.gwt.widgets.client.dialogs.GlassPane; import org.pentaho.gwt.widgets.client.dialogs.GlassPaneNativeListener; import org.pentaho.metadata.model.Domain; import org.pentaho.platform.dataaccess.datasource.beans.LogicalModelSummary; import org.pentaho.platform.dataaccess.datasource.modeler.ModelerDialog; import org.pentaho.platform.dataaccess.datasource.ui.selectdialog.GwtDatasourceManageDialog; import org.pentaho.platform.dataaccess.datasource.ui.selectdialog.GwtDatasourceSelectionDialog; import org.pentaho.platform.dataaccess.datasource.wizard.jsni.WAQRTransport; import org.pentaho.platform.dataaccess.datasource.wizard.service.IXulAsyncConnectionService; import org.pentaho.platform.dataaccess.datasource.wizard.service.IXulAsyncDatasourceService; import org.pentaho.platform.dataaccess.datasource.wizard.service.gwt.ICsvDatasourceService; import org.pentaho.platform.dataaccess.datasource.wizard.service.gwt.ICsvDatasourceServiceAsync; import org.pentaho.platform.dataaccess.datasource.wizard.service.impl.ConnectionServiceGwtImpl; import org.pentaho.platform.dataaccess.datasource.wizard.service.impl.DatasourceServiceGwtImpl; import org.pentaho.ui.xul.XulComponent; import org.pentaho.ui.xul.XulException; import org.pentaho.ui.xul.XulServiceCallback; import org.pentaho.ui.xul.components.XulConfirmBox; import org.pentaho.ui.xul.gwt.util.AsyncConstructorListener; import org.pentaho.ui.xul.util.DialogController.DialogListener; import org.pentaho.ui.xul.util.XulDialogCallback; /** * Creates the singleton datasource wizard and sets up native JavaScript functions to show the wizard. */ public class GwtDatasourceEditorEntryPoint implements EntryPoint { private EmbeddedWizard wizard; // TODO: make this lazily loaded when the modelerMessages issue is fixed private ModelerDialog modeler; private IXulAsyncDatasourceService datasourceService; private IXulAsyncConnectionService connectionService; private ICsvDatasourceServiceAsync csvService; private GwtDatasourceSelectionDialog gwtDatasourceSelectionDialog; private EmbeddedWizard gwtDatasourceEditor; private GwtDatasourceManageDialog manageDialog; private GwtDatasourceSelectionDialog selectDialog ; private boolean asyncConstructorDone; private boolean hasPermissions; public void onModuleLoad() { datasourceService = new DatasourceServiceGwtImpl(); // only init the app if the user has permissions datasourceService.hasPermission(new XulServiceCallback<Boolean>() { public void error(String message, Throwable error) { setupStandardNativeHooks(GwtDatasourceEditorEntryPoint.this); initDashboardButtons(false); } public void success(Boolean retVal) { hasPermissions = retVal; setupStandardNativeHooks(GwtDatasourceEditorEntryPoint.this); if (retVal) { connectionService = new ConnectionServiceGwtImpl(); csvService = (ICsvDatasourceServiceAsync) GWT.create(ICsvDatasourceService.class); setupPrivilegedNativeHooks(GwtDatasourceEditorEntryPoint.this); } initDashboardButtons(retVal); } }); } public native void initDashboardButtons(boolean val) /*-{ if($wnd.initDataAccess){ $wnd.initDataAccess(val); } }-*/; private native void setupStandardNativeHooks(GwtDatasourceEditorEntryPoint wizard)/*-{ if(!$wnd.pho){ $wnd.pho = {}; } $wnd.addDataAccessGlassPaneListener = function(callback) { wizard.@org.pentaho.platform.dataaccess.datasource.wizard.GwtDatasourceEditorEntryPoint::addGlassPaneListener(Lcom/google/gwt/core/client/JavaScriptObject;)(callback); } $wnd.pho.showDatasourceSelectionDialog = function(callback) { wizard.@org.pentaho.platform.dataaccess.datasource.wizard.GwtDatasourceEditorEntryPoint::showSelectionDialog(Ljava/lang/String;Lcom/google/gwt/core/client/JavaScriptObject;)("true", callback); } $wnd.gwtConfirm = function(message, callback, options){ var title = options.title || $wnd.pho_messages.getMessage("prompt","Prompt"); var accept = options.acceptLabel || $wnd.pho_messages.getMessage("okButton","OK"); var cancel = options.cancelLabel || $wnd.pho_messages.getMessage("cancelButton","Cancel"); try{ wizard.@org.pentaho.platform.dataaccess.datasource.wizard.GwtDatasourceEditorEntryPoint::showConfirm(Lcom/google/gwt/core/client/JavaScriptObject;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)(callback, message, title, accept, cancel); } catch(e) { // if it fails just show browser prompt callback.okOk($wnd.confirm(message)); } } }-*/; private native void setupPrivilegedNativeHooks(GwtDatasourceEditorEntryPoint wizard)/*-{ $wnd.pho.openDatasourceEditor= function(callback, reportingOnlyValid) { if(typeof reportingOnlyValid == "undefined"){ reportingOnlyValid = true; } wizard.@org.pentaho.platform.dataaccess.datasource.wizard.GwtDatasourceEditorEntryPoint::showWizard(ZLcom/google/gwt/core/client/JavaScriptObject;)(reportingOnlyValid, callback); } $wnd.pho.openEditDatasourceEditor= function(domainId, modelId, callback, perspective, reportingOnlyValid) { if(typeof reportingOnlyValid == "undefined"){ reportingOnlyValid = true; } wizard.@org.pentaho.platform.dataaccess.datasource.wizard.GwtDatasourceEditorEntryPoint::showWizardEdit(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLcom/google/gwt/core/client/JavaScriptObject;)(domainId, modelId, perspective, reportingOnlyValid, callback); } $wnd.pho.deleteModel=function(domainId, modelName, callback) { wizard.@org.pentaho.platform.dataaccess.datasource.wizard.GwtDatasourceEditorEntryPoint::deleteLogicalModel(Ljava/lang/String;Ljava/lang/String;Lcom/google/gwt/core/client/JavaScriptObject;)(domainId, modelName, callback); } $wnd.pho.showDatasourceManageDialog = function(callback) { wizard.@org.pentaho.platform.dataaccess.datasource.wizard.GwtDatasourceEditorEntryPoint::showSelectionDialog(Ljava/lang/String;Lcom/google/gwt/core/client/JavaScriptObject;)("false", callback); } }-*/; public void showConfirm(final JavaScriptObject callback, String message, String title, String okText, String cancelText) throws XulException{ XulConfirmBox confirm = (XulConfirmBox) wizard.getMainWizardContainer().getDocumentRoot().createElement("confirmbox"); confirm.setTitle(title); confirm.setMessage(message); confirm.setAcceptLabel(okText); confirm.setCancelLabel(cancelText); confirm.addDialogCallback(new XulDialogCallback<String>(){ public void onClose(XulComponent component, Status status, String value) { if(status == XulDialogCallback.Status.ACCEPT){ notifyDialogCallbackSuccess(callback, value); } } public void onError(XulComponent component, Throwable err) { notifyDialogCallbackError(callback, err.getMessage()); } }); confirm.open(); } @SuppressWarnings("unused") private void addGlassPaneListener(JavaScriptObject obj) { GlassPane.getInstance().addGlassPaneListener(new GlassPaneNativeListener(obj)); } /** * Entry-point from Javascript, responds to provided callback with the following: * * onOk(String JSON, String mqlString); * onCancel(); * onError(String errorMessage); * * @param callback * */ private void showWizard(final boolean relationalOnlyValid, final JavaScriptObject callback) { final DialogListener<Domain> listener = new DialogListener<Domain>(){ public void onDialogCancel() { wizard.removeDialogListener(this); notifyCallbackCancel(callback); } public void onDialogAccept(final Domain domain) { wizard.removeDialogListener(this); WAQRTransport transport = WAQRTransport.createFromMetadata(domain); notifyCallbackSuccess(callback, true, transport); } public void onDialogReady() { notifyCallbackReady(callback); } }; if(wizard == null){ wizard = new EmbeddedWizard(false); wizard.setDatasourceService(datasourceService); wizard.setConnectionService(connectionService); wizard.setCsvDatasourceService(csvService); wizard.setReportingOnlyValid(relationalOnlyValid); wizard.init(new AsyncConstructorListener<EmbeddedWizard>() { @Override public void asyncConstructorDone(EmbeddedWizard source) { wizard.addDialogListener(listener); wizard.showDialog(); } }); } else { wizard.addDialogListener(listener); wizard.showDialog(); } } private void showWizardEdit(final String domainId, final String modelId, boolean relationalOnlyValid, final JavaScriptObject callback) { showWizardEdit(domainId, modelId, ModelerPerspective.REPORTING.name(), relationalOnlyValid, callback); } /** * edit entry-point from Javascript, responds to provided callback with the following: * * onOk(String JSON, String mqlString); * onCancel(); * onError(String errorMessage); * * @param callback * */ private void showWizardEdit(final String domainId, final String modelId, final String perspective, boolean relationalOnlyValid, final JavaScriptObject callback) { final String modelPerspective; if (perspective == null) { modelPerspective = ModelerPerspective.REPORTING.name(); } else { modelPerspective = perspective; } final DialogListener<Domain> listener = new DialogListener<Domain>(){ public void onDialogCancel() { modeler.removeDialogListener(this); notifyCallbackCancel(callback); } public void onDialogAccept(final Domain domain) { modeler.removeDialogListener(this); WAQRTransport transport = WAQRTransport.createFromMetadata(domain); notifyCallbackSuccess(callback, true, transport); } public void onDialogReady() { notifyCallbackReady(callback); } }; modeler = ModelerDialog.getInstance(wizard, new AsyncConstructorListener<ModelerDialog>(){ public void asyncConstructorDone(ModelerDialog dialog) { ModelerPerspective modelerPerspective; try { modelerPerspective = ModelerPerspective.valueOf(modelPerspective); } catch (IllegalArgumentException e) { modelerPerspective = ModelerPerspective.REPORTING; } dialog.addDialogListener(listener); dialog.showDialog(domainId, modelId, modelerPerspective); } }); } /** * Deletes the selected model * * onOk(Boolean value); * onCancel(); * onError(String errorMessage); * * @param callback * */ private void deleteLogicalModel(String domainId, String modelName, final JavaScriptObject callback) { datasourceService.deleteLogicalModel(domainId, modelName, new XulServiceCallback<Boolean>(){ public void success(Boolean value) { notifyCallbackSuccess(callback, value); } public void error(String s, Throwable throwable) { notifyCallbackError(callback, throwable.getMessage()); } }); } @SuppressWarnings("unused") private void showSelectionDialog(final String selectDatasource, final JavaScriptObject callback) { final boolean selectDs = Boolean.valueOf(selectDatasource); final DialogListener<LogicalModelSummary> listener = new DialogListener<LogicalModelSummary>(){ public void onDialogCancel() { selectDialog.removeDialogListener(this); asyncConstructorDone = false; notifyCallbackCancel(callback); } public void onDialogAccept(final LogicalModelSummary logicalModelSummary) { selectDialog.removeDialogListener(this); asyncConstructorDone = false; notifyCallbackSuccess(callback, logicalModelSummary.getDomainId(), logicalModelSummary.getModelId(),logicalModelSummary.getModelName()); } public void onDialogReady() { } }; if(wizard == null && this.hasPermissions){ wizard = new EmbeddedWizard(false); wizard.setDatasourceService(datasourceService); wizard.setConnectionService(connectionService); wizard.setCsvDatasourceService(csvService); wizard.init(new AsyncConstructorListener<EmbeddedWizard>() { public void asyncConstructorDone(EmbeddedWizard source) { showSelectionDialog(selectDs, listener); } }); } else { showSelectionDialog(selectDs, listener); } } private void showSelectionDialog(final boolean selectDs, final DialogListener<LogicalModelSummary> listener) { if (selectDs) { // selection dialog if (selectDialog == null) { final AsyncConstructorListener<GwtDatasourceSelectionDialog> constructorListener = getSelectionDialogListener(listener); asyncConstructorDone = false; selectDialog = new GwtDatasourceSelectionDialog(datasourceService, wizard, constructorListener); } else { selectDialog.addDialogListener(listener); selectDialog.reset(); selectDialog.showDialog(); } } else { // manage dialog if (manageDialog == null) { final AsyncConstructorListener<GwtDatasourceSelectionDialog> constructorListener = getSelectionDialogListener(listener); asyncConstructorDone = false; manageDialog = new GwtDatasourceManageDialog(datasourceService, wizard, constructorListener); } else { manageDialog.reset(); manageDialog.showDialog(); } } } private AsyncConstructorListener<GwtDatasourceSelectionDialog> getSelectionDialogListener(final DialogListener<LogicalModelSummary> listener){ return new AsyncConstructorListener<GwtDatasourceSelectionDialog>() { public void asyncConstructorDone(GwtDatasourceSelectionDialog dialog) { dialog.removeDialogListener(listener); dialog.addDialogListener(listener); if (!asyncConstructorDone) { dialog.showDialog(); } asyncConstructorDone = true; } }; } private native void notifyCallbackSuccess(JavaScriptObject callback, String domainId, String modelId, String modelName) /*-{ callback.onFinish(domainId, modelId, modelName); }-*/; private native void notifyCallbackSuccess(JavaScriptObject callback, String domainId, String modelId) /*-{ callback.onFinish(domainId, modelId); }-*/; private native void notifyCallbackSuccess(JavaScriptObject callback, Boolean value, WAQRTransport transport)/*-{ callback.onFinish(value, transport); }-*/; private native void notifyCallbackSuccess(JavaScriptObject callback, Boolean value)/*-{ callback.onFinish(value); }-*/; private native void notifyCallbackError(JavaScriptObject callback, String error)/*-{ callback.onError(error); }-*/; private native void notifyCallbackCancel(JavaScriptObject callback)/*-{ callback.onCancel(); }-*/; private native void notifyCallbackReady(JavaScriptObject callback)/*-{ callback.onReady(); }-*/; private native void notifyDialogCallbackSuccess(JavaScriptObject callback, Object value)/*-{ callback.onOk(value); }-*/; private native void notifyDialogCallbackCancel(JavaScriptObject callback)/*-{ callback.onCancel(); }-*/; private native void notifyDialogCallbackError(JavaScriptObject callback, String error)/*-{ callback.onError(error); }-*/; }