org.pentaho.aggdes.ui.form.controller.ConnectionController.java Source code

Java tutorial

Introduction

Here is the source code for org.pentaho.aggdes.ui.form.controller.ConnectionController.java

Source

/*
* 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.
*
*
* Copyright 2006 - 2013 Pentaho Corporation.  All rights reserved.
*/

package org.pentaho.aggdes.ui.form.controller;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.aggdes.AggDesignerException;
import org.pentaho.aggdes.model.Schema;
import org.pentaho.aggdes.output.OutputService;
import org.pentaho.aggdes.ui.Workspace;
import org.pentaho.aggdes.ui.ext.SchemaProviderUiExtension;
import org.pentaho.aggdes.ui.form.model.ConnectionModel;
import org.pentaho.aggdes.ui.model.SchemaModel;
import org.pentaho.aggdes.ui.util.Messages;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.ui.xul.XulEventSource;
import org.pentaho.ui.xul.XulException;
import org.pentaho.ui.xul.binding.Binding;
import org.pentaho.ui.xul.binding.BindingFactory;
import org.pentaho.ui.xul.components.XulMessageBox;
import org.pentaho.ui.xul.components.XulTextbox;
import org.pentaho.ui.xul.containers.XulDialog;
import org.pentaho.ui.xul.impl.AbstractXulEventHandler;
import org.pentaho.ui.xul.impl.XulEventHandler;
import org.pentaho.ui.xul.stereotype.Controller;
import org.pentaho.ui.xul.stereotype.RequestHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;

@Controller
public class ConnectionController extends AbstractXulEventHandler {

    public static final String CONNECT_ERROR_DIALOG = "connectErrorDialog";

    public static final String CONNECTION_DIALOG = "connection_dialog";

    public static final String ANON_WAIT_DIALOG = "anonWaitDialog";

    public static final String GENERAL_DATASOURCE_WINDOW = "general-datasource-window";

    private static final Log logger = LogFactory.getLog(ConnectionController.class);

    private ConnectionModel connectionModel;

    private XulEventHandler dataHandler;

    private Workspace workspace;

    private OutputService outputService;

    private List<SchemaProviderUiExtension> schemaProviders = new ArrayList<SchemaProviderUiExtension>();

    private SchemaProviderUiExtension selectedSchemaProvider = null;

    private Schema schema = null;

    private BindingFactory bindingFactory;

    @Autowired
    public void setBindingFactory(BindingFactory bindingFactory) {
        this.bindingFactory = bindingFactory;
    }

    public void setOutputService(OutputService outputService) {
        this.outputService = outputService;
    }

    public List<SchemaProviderUiExtension> getSchemaProviders() {
        return schemaProviders;
    }

    public void setConnectionModel(ConnectionModel connectionModel) {

        this.connectionModel = connectionModel;
    }

    public void setDataHandler(XulEventHandler dataHandler) {

        this.dataHandler = dataHandler;
    }

    public void setWorkspace(Workspace workspace) {

        this.workspace = workspace;
    }

    @Autowired
    public void setSchemaProviders(List<SchemaProviderUiExtension> schemaProviders) {
        this.schemaProviders = schemaProviders;
    }

    public void setSelectedSchemaProvider() {
        selectedSchemaProvider = null;
        for (SchemaProviderUiExtension sProvider : schemaProviders) {
            if (sProvider.isSelected()) {
                selectedSchemaProvider = sProvider;
            }
        }
    }

    public void reset() throws Exception {
        connectionModel.reset();
        for (SchemaProviderUiExtension extension : schemaProviders) {
            extension.reset();
        }
    }

    @RequestHandler
    public void onLoad() throws Exception {
        BindingFactory bf = bindingFactory;
        bf.setDocument(document);

        for (final SchemaProviderUiExtension extension : schemaProviders) {
            try {
                document.addOverlay(extension.getOverlayPath());
                getXulDomContainer().addEventHandler(extension);

                ((XulEventSource) extension).addPropertyChangeListener(new PropertyChangeListener() {

                    public void propertyChange(PropertyChangeEvent evt) {
                        boolean schemaAppliable = false;
                        if (evt.getPropertyName().equals("schemaDefined")
                                || evt.getPropertyName().equals("selected")) {
                            logger.debug("*** got schemaDefined=" + evt.getNewValue()
                                    + ", checking if any providers are applyable");
                            for (SchemaProviderUiExtension ex : schemaProviders) {

                                //De-select other extensions
                                if (evt.getPropertyName().equals("selected") && extension != ex
                                        && evt.getNewValue() == Boolean.TRUE) {
                                    ex.setSelected(false);
                                }

                                if (ex.isSchemaDefined() && ex.isSelected()) {
                                    logger.debug("provider " + ex.getName() + " is applyable");
                                    schemaAppliable = true;
                                } else {
                                    logger.debug(ex.getName() + " NOT applyable: defined=[" + ex.isSchemaDefined()
                                            + "] selected=[" + ex.isSelected() + "]");
                                }
                            }
                            connectionModel.setApplySchemaSourceEnabled(schemaAppliable);
                        }
                    }

                });

                bf.setBindingType(Binding.Type.ONE_WAY);
                bf.createBinding(connectionModel, "schemaLocked", extension, "!enabled");

                //        extension.onLoad();
            } catch (XulException e) {
                logger.error("Error loading Schema Provider Overlay", e);
            }
        }

        bf.setBindingType(Binding.Type.BI_DIRECTIONAL);

        bf.createBinding(workspace, "applicationUnlocked", "open_advisor", "!disabled");
        bf.createBinding(workspace, "applicationUnlocked", "open_export", "!disabled");
        bf.createBinding(workspace, "applicationUnlocked", "agg_add_btn", "!disabled");
        bf.createBinding(connectionModel, "cubeNames", "cubeSelector", "elements");
        bf.createBinding(connectionModel, "cubeName", "cubeSelector", "selectedItem");

        bf.setBindingType(Binding.Type.ONE_WAY);

        bf.createBinding(connectionModel, "applySchemaSourceEnabled", "applySchemaSourceButton", "!disabled");
        bf.createBinding(connectionModel, "databaseName", "databaseName", "value");
        bf.createBinding(connectionModel, "cubeSelectionEnabled", "cubeSelector", "!disabled");

        bf.createBinding(connectionModel, "schemaLocked", "cubeSelector", "disabled");
        bf.createBinding(connectionModel, "schemaLocked", "applySchemaSourceButton", "disabled");

        bf.createBinding(connectionModel, "connectEnabled", "connection_dialog_accept", "!disabled")
                .fireSourceChanged();

        connectionModel.addPropertyChangeListener(new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
                if (evt.getPropertyName().equals("selectedSchemaModel")) {
                    SchemaModel model = (SchemaModel) evt.getNewValue();
                    // select the correct schema value
                    for (SchemaProviderUiExtension extension : schemaProviders) {
                        if (model != null && extension.supportsSchemaModel(model)) {
                            selectedSchemaProvider = extension;
                            extension.setSelected(true);
                            extension.setSchemaModel(model);
                        } else {
                            extension.setSelected(false);
                        }
                    }
                }
            }
        });

        //call unload after the bindings since the extension's onload might trigger something
        for (SchemaProviderUiExtension extension : schemaProviders) {
            extension.onLoad();
        }

        // auto select provider if only one is present
        if (schemaProviders.size() == 1) {
            schemaProviders.get(0).setSelected(true);
        }

        document.invokeLater(new Runnable() {
            public void run() {
                showConnectionDialog();
            }
        });

    }

    @RequestHandler
    public void loadDatabaseDialog() {
        dataHandler.setData(connectionModel.getDatabaseMeta());

        XulDialog dialog = (XulDialog) document.getElementById(GENERAL_DATASOURCE_WINDOW);
        dialog.show();

        DatabaseMeta databaseMeta = (DatabaseMeta) dataHandler.getData();

        if (databaseMeta != null) {
            connectionModel.setDatabaseMeta(databaseMeta);
        }
    }

    //  TODO: What if cancel is pressed?
    @RequestHandler
    public void connect() {

        final XulDialog waitDialog = (XulDialog) document.getElementById(ANON_WAIT_DIALOG);
        try {
            if (selectedSchemaProvider == null) {
                throw new AggDesignerException(Messages.getString("select_olap_model"));
            }

            workspace.setApplicationUnlocked(false);

            new Thread() {
                @Override
                public void run() {
                    try {
                        while (waitDialog.isHidden()) {
                            Thread.sleep(300);
                        }
                        ConnectionController.this.schema = selectedSchemaProvider
                                .loadSchema(connectionModel.getCubeName());
                    } catch (Exception e) {
                        //consume, schema will be null which is checked outside of this thread
                        logger.error("Error loading schema: ", e);
                    } finally {
                        waitDialog.hide();
                    }
                }
            }.start();

            waitDialog.show();
            if (schema == null) {
                throw new AggDesignerException("Error loading Schema");
            }
            connectionModel.setSchema(schema);
            outputService.init(schema);
            connectionModel.setSchemaUpToDate(true);

            // don't unlock app until everything has succeeded.
            workspace.setApplicationUnlocked(true);
            hideConnectionDialog();
        } catch (Exception e) {
            logger.error("Unable to connect", e);
            if (!waitDialog.isHidden()) {
                waitDialog.hide();
            }

            XulDialog connectErrorDialog = (XulDialog) document.getElementById(CONNECT_ERROR_DIALOG);
            Assert.notNull(connectErrorDialog, "missing element from document");
            XulTextbox connectErrorDialogMessage = (XulTextbox) document
                    .getElementById("connectErrorDialogMessage");
            Assert.notNull(connectErrorDialogMessage, "missing element from document");
            connectErrorDialogMessage.setValue(e.getLocalizedMessage());
            connectErrorDialog.show();

        }
    }

    @RequestHandler
    public void connectErrorDialogDismiss() {
        XulDialog connectErrorDialog = (XulDialog) document.getElementById(CONNECT_ERROR_DIALOG);
        Assert.notNull(connectErrorDialog, "missing element from document");
        if (!connectErrorDialog.isHidden()) {
            connectErrorDialog.hide();
        }
    }

    @RequestHandler
    public void showConnectionDialog() {
        logger.debug("In Thread showing mondrian dialog");
        XulDialog connectionDialog = (XulDialog) document.getElementById(CONNECTION_DIALOG);
        connectionDialog.show();
    }

    @RequestHandler
    public void hideConnectionDialog() {
        XulDialog connectionDialog = (XulDialog) document.getElementById(CONNECTION_DIALOG);
        connectionDialog.hide();
    }

    private List<String> cubeNames = null;

    /**
     * Applies the schema provided by the {@link SchemaProviderUiExtension} and populates
     * the cube selector widget with a list of available cubes in the schema.
     * @throws XulException
     */
    @RequestHandler
    public void apply() throws XulException {
        final XulDialog waitDialog = (XulDialog) document.getElementById(ANON_WAIT_DIALOG);

        logger.debug("starting thread");
        new Thread() {
            @Override
            public void run() {
                // don't proceed until the wait dialog is shown
                while (waitDialog.isHidden()) {
                    try {
                        logger.debug("waiting for wait dialog to show");
                        sleep(500);
                    } catch (InterruptedException e) {
                        logger.error("an exception occurred", e);
                        return;
                    }
                }

                logger.debug("apply is running in separate thread");
                try {
                    setSelectedSchemaProvider();
                    if (selectedSchemaProvider == null) {
                        throw new AggDesignerException(Messages.getString("select_olap_model"));
                    }
                    cubeNames = selectedSchemaProvider.getCubeNames();

                } catch (AggDesignerException e) {
                    logger.error("Error loading OLAP schema", e);

                    try {
                        XulMessageBox box = (XulMessageBox) document.createElement("messagebox");
                        box.setTitle("Error");
                        box.setMessage(Messages.getString("Olap.apply.error"));
                        box.open();
                    } catch (XulException ex) {
                    }

                } finally {
                    logger.debug("hiding dialog if it isn't already hidden");
                    waitDialog.hide();
                }

            }

        }.start();
        logger.debug("showing wait dialog");
        waitDialog.show();

        if (selectedSchemaProvider == null) {
            XulMessageBox box = (XulMessageBox) document.createElement("messagebox");
            box.setTitle("Error");
            box.setMessage("Error applying OLAP schema");
            box.open();
            return;
        }
        connectionModel.setCubeNames(cubeNames);
        connectionModel.setSelectedSchemaModel(selectedSchemaProvider.getSchemaModel());

    }
}