io.pelle.mango.client.web.module.ModuleHandler.java Source code

Java tutorial

Introduction

Here is the source code for io.pelle.mango.client.web.module.ModuleHandler.java

Source

/**
 * Copyright (c) 2013 Christian Pelster.
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Christian Pelster - initial API and implementation
 */
package io.pelle.mango.client.web.module;

import io.pelle.mango.client.base.layout.IModuleUI;
import io.pelle.mango.client.base.module.BaseModule;
import io.pelle.mango.client.base.module.IModule;
import io.pelle.mango.client.web.MangoClientWeb;
import io.pelle.mango.client.web.util.BaseAsyncCallback;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Stack;
import java.util.logging.Logger;

import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DockLayoutPanel;

/**
 * Handler for module loading
 * 
 * @author pelle
 * @version $Rev$, $Date$
 * 
 */
@SuppressWarnings("rawtypes")
public final class ModuleHandler {

    final static Logger LOG = Logger.getLogger("ModuleHandler");

    public static EventBus MODULE_EVENT_BUS = new SimpleEventBus();

    private int moduleCounter = 0;

    private static ModuleHandler instance;

    public static String DEFAULT_LOCATION = DockLayoutPanel.Direction.CENTER.toString();

    private final LinkedHashMap<String, Stack<IModuleUI>> currentModules = new LinkedHashMap<String, Stack<IModuleUI>>();

    private final LinkedHashMap<IModule, Stack<IModuleUI>> modules2ModuleUI = new LinkedHashMap<IModule, Stack<IModuleUI>>();

    public static ModuleHandler getInstance() {
        if (instance == null) {
            instance = new ModuleHandler();
        }

        return instance;
    }

    private ModuleHandler() {
    }

    private String getLocation(String location) {
        if (location == null || location.trim().isEmpty()) {
            return DEFAULT_LOCATION;
        } else {
            return location;
        }
    }

    private Stack<IModuleUI> getModuleStack(String location) {
        if (!this.currentModules.containsKey(location)) {
            this.currentModules.put(location, new Stack<IModuleUI>());
        }

        return this.currentModules.get(location);
    }

    public void startUIModule(final String moduleUrl, String location) {
        startUIModule(moduleUrl, location, new HashMap<String, Object>(),
                Optional.<AsyncCallback<IModuleUI>>absent());
    }

    public void startUIModule(final String moduleUrl) {
        startUIModule(moduleUrl, null, new HashMap<String, Object>(), Optional.<AsyncCallback<IModuleUI>>absent());
    }

    public void startUIModule(final String moduleUrl, Map<String, Object> parameters) {
        startUIModule(moduleUrl, null, parameters, Optional.<AsyncCallback<IModuleUI>>absent());
    }

    private class MouldeUrlPredicate implements Predicate<IModuleUI> {
        private String moduleUrl;

        public MouldeUrlPredicate(String moduleUrl) {
            super();
            this.moduleUrl = moduleUrl;
        }

        @Override
        public boolean apply(IModuleUI input) {
            return input.isInstanceOf(this.moduleUrl);
        }

    };

    @SuppressWarnings("unchecked")
    public void startUIModule(final String moduleUrl, final String location1, final Map<String, Object> parameters,
            final Optional<AsyncCallback<IModuleUI>> callback) {

        final String location = getLocation(location1);

        LOG.info("starting ui module for url '" + moduleUrl + "'");

        Optional<IModuleUI> moduleUI = Iterables.tryFind(getModuleStack(location),
                new MouldeUrlPredicate(moduleUrl));

        if (moduleUI.isPresent()) {

            LOG.info("ui module for url '" + moduleUrl + "' already started (" + moduleUI.get().toString() + ")");

            moduleUI.get().updateUrl(moduleUrl);

            if (callback.isPresent()) {
                callback.get().onSuccess(moduleUI.get());
            }

            MangoClientWeb.getInstance().getLayoutFactory().showModuleUI(moduleUI.get(), location);

        } else {

            if (ModuleUIFactoryRegistry.getInstance().supports(moduleUrl)) {

                ModuleUIFactoryRegistry.getInstance().getModuleFactory(moduleUrl).getNewInstance(moduleUrl,
                        new BaseAsyncCallback<IModuleUI, IModuleUI>(callback) {

                            @Override
                            public void onSuccess(IModuleUI moduleUI) {

                                if (moduleUI.contributesToBreadCrumbs()) {
                                    stashCurrentAndShow(moduleUI, location);
                                } else {
                                    closeCurrentAndShow(moduleUI, location);
                                }

                                onModuleUIAdd(moduleUI, location);

                                if (callback.isPresent()) {
                                    callback.get().onSuccess(moduleUI);
                                }
                            }

                        }, parameters, peekCurrentModule(location));
            } else {
                throw new RuntimeException("unsupported module url '" + moduleUrl + "'");
            }
        }
    }

    private void onModuleUIAdd(IModuleUI moduleUI, final String location) {
        modules2ModuleUI.get(moduleUI.getModule()).push(moduleUI);
        ModuleHandler.this.getModuleStack(location).add(moduleUI);
    }

    private Optional<IModuleUI> peekCurrentModule(String location) {
        if (getModuleStack(location).isEmpty()) {
            return Optional.absent();
        } else {
            return Optional.of(getModuleStack(location).peek());
        }
    }

    private Optional<IModuleUI> popCurrentModule(String location) {
        if (getModuleStack(location).isEmpty()) {
            return Optional.absent();
        } else {
            return Optional.of(getModuleStack(location).pop());
        }
    }

    public void startModule(final String moduleUrl, Map<String, Object> parameters,
            final AsyncCallback<IModule> moduleCallback) {

        LOG.info("starting module for url '" + moduleUrl + "'");

        if (ModuleFactoryRegistry.getInstance().supports(moduleUrl)) {
            this.moduleCounter++;
            parameters.put(BaseModule.MODULE_COUNTER_PARAMETER_ID, this.moduleCounter);

            ModuleFactoryRegistry.getInstance().getModuleFactory(moduleUrl).getNewInstance(moduleUrl,
                    new AsyncCallback<IModule>() {

                        @Override
                        public void onSuccess(IModule result) {
                            modules2ModuleUI.put(result, new Stack<IModuleUI>());
                            moduleCallback.onSuccess(result);
                        }

                        @Override
                        public void onFailure(Throwable caught) {
                            moduleCallback.onFailure(caught);

                        }
                    }, parameters);
        } else {
            moduleCallback.onFailure(new RuntimeException("unsupported module url '" + moduleUrl + "'"));
        }
    }

    private String getModuleLocation(IModuleUI moduleUI) {
        for (Map.Entry<String, Stack<IModuleUI>> currentModuleEntry : this.currentModules.entrySet()) {
            if (currentModuleEntry.getValue().contains(moduleUI)) {
                return currentModuleEntry.getKey();
            }

        }

        throw new RuntimeException("module ui '" + moduleUI.toString() + "' not found");
    }

    private void onModuleUIClose(IModuleUI moduleUI) {

        Stack<IModuleUI> moduleUIs = modules2ModuleUI.get(moduleUI.getModule());

        moduleUIs.remove(moduleUI);

        if (moduleUIs.isEmpty()) {
            moduleUI.getModule().onClose();
        }

        for (Map.Entry<String, Stack<IModuleUI>> currentModuleEntry : this.currentModules.entrySet()) {
            currentModuleEntry.getValue().remove(moduleUI);
        }

    }

    public void closeCurrentAndShow(IModuleUI moduleUI, String location) {

        Optional<IModuleUI> currentModuleUI = popCurrentModule(location);

        if (currentModuleUI.isPresent()) {
            MangoClientWeb.getInstance().getLayoutFactory().closeModuleUI(currentModuleUI.get());
            onModuleUIClose(moduleUI);
        }

        MangoClientWeb.getInstance().getLayoutFactory().showModuleUI(moduleUI, location);
    }

    public void stashCurrentAndShow(IModuleUI moduleUI, String location) {

        Optional<IModuleUI> currentModuleUI = peekCurrentModule(location);

        if (currentModuleUI.isPresent()) {
            MangoClientWeb.getInstance().getLayoutFactory().closeModuleUI(currentModuleUI.get());
        }

        MangoClientWeb.getInstance().getLayoutFactory().showModuleUI(moduleUI, location);
    }

    public void closeCurrentAndShow(IModuleUI moduleUI) {

        LOG.info("closing module ui '" + moduleUI.toString() + "'");

        String location = getModuleLocation(moduleUI);
        Optional<IModuleUI> currentModuleUI = popCurrentModule(location);

        if (currentModuleUI.isPresent()) {
            MangoClientWeb.getInstance().getLayoutFactory().closeModuleUI(currentModuleUI.get());
            onModuleUIClose(currentModuleUI.get());
        }

        MangoClientWeb.getInstance().getLayoutFactory().showModuleUI(moduleUI, location);
    }
}