org.opentravel.schemas.controllers.MainController.java Source code

Java tutorial

Introduction

Here is the source code for org.opentravel.schemas.controllers.MainController.java

Source

/**
 * Copyright (C) 2014 OpenTravel Alliance (info@opentravel.org)
 *
 * 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.
 */
package org.opentravel.schemas.controllers;

import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.IHandlerService;
import org.opentravel.schemacompiler.model.TLFacetType;
import org.opentravel.schemacompiler.repository.RepositoryException;
import org.opentravel.schemacompiler.repository.RepositoryFileManager;
import org.opentravel.schemacompiler.repository.RepositoryManager;
import org.opentravel.schemas.actions.ImportObjectToLibraryAction;
import org.opentravel.schemas.commands.AddNodeHandler;
import org.opentravel.schemas.node.BusinessObjectNode;
import org.opentravel.schemas.node.ComponentNode;
import org.opentravel.schemas.node.FacetNode;
import org.opentravel.schemas.node.INode;
import org.opentravel.schemas.node.LibraryChainNode;
import org.opentravel.schemas.node.LibraryNode;
import org.opentravel.schemas.node.ModelNode;
import org.opentravel.schemas.node.Node;
import org.opentravel.schemas.node.NodeFactory;
import org.opentravel.schemas.node.NodeModelController;
import org.opentravel.schemas.node.ProjectNode;
import org.opentravel.schemas.node.properties.PropertyNode;
import org.opentravel.schemas.properties.Messages;
import org.opentravel.schemas.stl2developer.Activator;
import org.opentravel.schemas.stl2developer.DialogUserNotifier;
import org.opentravel.schemas.stl2developer.MainWindow;
import org.opentravel.schemas.stl2developer.OtmRegistry;
import org.opentravel.schemas.views.NavigatorView;
import org.opentravel.schemas.views.OtmView;
import org.opentravel.schemas.widgets.ErrorWithExceptionDialog;
import org.opentravel.schemas.widgets.OtmHandlers;
import org.opentravel.schemas.widgets.OtmSections;
import org.opentravel.schemas.widgets.OtmTextFields;
import org.opentravel.schemas.widgets.OtmWidgets;
import org.opentravel.schemas.wizards.ChangeWizard;
import org.opentravel.schemas.wizards.NewFacetValidator;
import org.opentravel.schemas.wizards.NewFacetWizard;
import org.opentravel.schemas.wizards.NewPropertiesWizard;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Main Controller. Receives events from the view and workbench, drives user interactions then executes commands to
 * update/manipulate the models.
 * 
 * - This class provides access to controller that do not rely upon the workbench. - It can be used for junit tests. -
 * Provides and manages registry of the various view specific controllers. - Provides access to selected nodes.
 * 
 * @author Dave Hollander
 */

public class MainController {
    private static final Logger LOGGER = LoggerFactory.getLogger(MainController.class);

    public static final String WARNING_MSG = "Warning";
    public static final String NO_VALID_SELECTION_MSG = "No valid selection";

    private ModelNode modelNode;

    private MainWindow mainWindow = null;

    private OtmHandlers handlers;
    private OtmActions actions;
    private OtmWidgets widgets;
    private final OtmSections sections;
    private final OtmTextFields fields;

    private final LibraryController libraryController;
    private final ModelController modelController;
    private final ContextController contextController;
    private final NodeModelController nodeModelController;
    private ProjectController projectController;
    private RepositoryController repositoryController;

    private final OtmView defaultView;

    private IHandlerService handlerService;
    private IWorkbenchPartSite site = null;
    private final String CopyNameSuffix = "_Copy";

    private ListenerList refreshList = new ListenerList();

    public MainController() {
        this(getDefaultRepositoryManager());
    }

    public static RepositoryManager getDefaultRepositoryManager() {
        RepositoryManager defaultManager = null;
        try {
            defaultManager = RepositoryManager.getDefault();
        } catch (RepositoryException ex) {
            IStatus ss = new Status(IStatus.ERROR, Activator.PLUGIN_ID, ex.getMessage(), ex);
            ErrorWithExceptionDialog.openError(PlatformUI.getWorkbench().getDisplay().getActiveShell(),
                    JFaceResources.getString("error"),
                    MessageFormat.format(Messages.getString("dialog.localRepository.error.message"),
                            RepositoryFileManager.getDefaultRepositoryLocation()),
                    ss);
            LOGGER.error("Invalid local repository", ex);
            PlatformUI.getWorkbench().close();
        }
        return defaultManager;
    }

    public MainController(final RepositoryManager repositoryManager) {
        // LOGGER.info("Initializing: " + this.getClass());

        OtmRegistry.registerMainController(this);
        mainWindow = OtmRegistry.getMainWindow(); // if headless it will be null
        defaultView = new NavigatorView(); // Always have one view.

        handlers = new OtmHandlers();
        actions = new OtmActions(this);
        widgets = new OtmWidgets(getActions(), getHandlers());
        sections = new OtmSections(getActions(), getHandlers());
        fields = new OtmTextFields(getActions(), getHandlers());

        libraryController = new DefaultLibraryController(this);
        modelController = new DefaultModelController(this, libraryController);
        modelNode = modelController.getModel();
        nodeModelController = new NodeModelController(this);
        contextController = new DefaultContextController(this);
        repositoryController = new DefaultRepositoryController(this, repositoryManager);
        projectController = new DefaultProjectController(this, repositoryManager);
    }

    /** ************************ Model Controller Access ***************************** **/

    public ContextController getContextController() {
        return contextController;
    }

    public LibraryController getLibraryController() {
        return libraryController;
    }

    /**
     * @return the repositoryController
     */
    public RepositoryController getRepositoryController() {
        return repositoryController;
    }

    /**
     * @param repositoryController
     *            the repositoryController to set
     */
    public void setRepositoryController(DefaultRepositoryController defaultRepositoryController) {
        this.repositoryController = defaultRepositoryController;
    }

    public MainWindow getMainWindow() {
        return mainWindow;
    }

    public ModelController getModelController() {
        return modelController;
    }

    public NodeModelController getNodeModelController() {
        return nodeModelController;
    }

    /**
     * @return the projectController
     */
    public ProjectController getProjectController() {
        return projectController;
    }

    /**
     * @param projectController
     *            the projectController to set
     */
    public void setProjectController(ProjectController projectController) {
        this.projectController = projectController;
    }

    public OtmHandlers getHandlers() {
        return handlers;
    }

    public void setHandlers(final OtmHandlers handlers) {
        this.handlers = handlers;
    }

    public OtmActions getActions() {
        return actions;
    }

    public void setActions(final OtmActions actions) {
        this.actions = actions;
    }

    public OtmWidgets getWidgets() {
        return widgets;
    }

    public void setWidgets(final OtmWidgets widgets) {
        this.widgets = widgets;
    }

    public OtmSections getSections() {
        return sections;
    }

    public OtmTextFields getFields() {
        return fields;
    }

    /**
     * @return the defaultView
     */
    public OtmView getDefaultView() {
        return defaultView;
    }

    /** ************************ Current Item Access ***************************** **/

    /**
     * @return the current node displayed in the type view facet table.
     */
    public INode getCurrentNode_TypeView() {
        return (INode) (OtmRegistry.getTypeView() != null ? OtmRegistry.getTypeView().getCurrentNode() : null);
    }

    public INode getCurrentNode_FacetView() {
        return (INode) (OtmRegistry.getFacetView() != null ? OtmRegistry.getFacetView().getCurrentNode() : null);
    }

    /**
     * @return the node currently be viewed in the properties view.
     */
    public INode getCurrentNode_PropertiesView() {
        return (INode) (OtmRegistry.getPropertiesView() != null ? OtmRegistry.getPropertiesView().getCurrentNode()
                : null);
    }

    /**
     * @return the current navigator view (treeView) node or null if none selected.
     */
    public Node getCurrentNode_NavigatorView() {
        return (Node) (OtmRegistry.getNavigatorView() != null ? OtmRegistry.getNavigatorView().getCurrentNode()
                : null);
    }

    /**
     * Set the current node displayed in the type view facet table.
     */
    public void setCurrentNode_TypeView(Node node) {
        final OtmView view = OtmRegistry.getTypeView();
        if (view != null) {
            view.setCurrentNode(node);
        }
    }

    /**
     * Set the node currently be viewed in the properties view.
     */
    public void setCurrentNode_PropertiesView(Node node) {
        final OtmView view = OtmRegistry.getPropertiesView();
        if (view != null) {
            view.setCurrentNode(node);
        }
    }

    /**
     * Set the current navigator view (treeView) node.
     */
    public void setCurrentNode_NavigatorView(Node node) {
        final OtmView view = OtmRegistry.getNavigatorView();
        if (view != null) {
            view.setCurrentNode(node);
        }
    }

    /**
     * @return the catalogRoot
     */
    public ModelNode getModelNode() {
        return modelNode;
    }

    /** ************************ Selected Item Access ***************************** **/

    /**
     * Gets the navigator selected libraries. All libraries of selected projects are also returned.
     * 
     * @return new list of selected navigator view nodes, possibly empty.
     */
    public List<LibraryNode> getSelectedLibraries() {
        final List<LibraryNode> libraries = new ArrayList<LibraryNode>();
        final List<Node> nodes = getSelectedNodes_NavigatorView();
        for (final Node node : nodes) {
            if (node != null) {
                final LibraryNode library = node.getLibrary();
                if (!libraries.contains(library)) {
                    libraries.add(library);
                } else if (node instanceof ProjectNode) {
                    for (INode n : node.getChildren())
                        if (n instanceof LibraryNode && !libraries.contains(n))
                            libraries.add((LibraryNode) n);
                        else if (node instanceof LibraryChainNode)
                            libraries.addAll(((LibraryChainNode) node).getLibraries());
                } else if (node instanceof LibraryChainNode)
                    libraries.addAll(((LibraryChainNode) node).getLibraries());
            }
        }
        return libraries;
    }

    /**
     * Gets the navigator selected nodes and filters out non-user libraries.
     * 
     * @return new list of selected navigator view nodes, possibly empty.
     */
    public List<LibraryNode> getSelectedUserLibraries() {
        final List<LibraryNode> libraries = new ArrayList<LibraryNode>();
        for (final LibraryNode lib : getSelectedLibraries()) {
            if (lib != null && lib.isTLLibrary()) {
                libraries.add(lib);
            }
        }
        return libraries;
    }

    /**
     * Get the current facet node or first node selected from facet table in type View.
     * 
     * @return selected node or null.
     */
    public Node getSelectedNode_TypeView() {
        Node n = null;
        OtmView view = OtmRegistry.getTypeView();
        if (view == null)
            return null;

        final List<Node> selectedNodes = getSelectedNodes_TypeView();
        if (selectedNodes == null || selectedNodes.isEmpty()) {
            n = (Node) view.getCurrentNode();
        } else {
            n = selectedNodes.get(0);
        }
        return n;
    }

    /**
     * Get the first node selected from navigator view.
     * 
     * @return selected node or null.
     */
    public Node getSelectedNode_NavigatorView() {
        final List<Node> selected = getSelectedNodes_NavigatorView();
        if (selected.size() > 0) {
            return selected.get(0);
        }
        return null;
    }

    /**
     * Gets the navigator selected nodes and filters out non-component nodes.
     * 
     * @return new list of selected navigator view nodes, possibly empty.
     */
    public List<ComponentNode> getSelectedComponents_NavigatorView() {
        final List<ComponentNode> componentNodes = new ArrayList<ComponentNode>();
        final List<Node> sourceNodes = getSelectedNodes_NavigatorView();
        for (final INode node : sourceNodes) {
            if (node instanceof ComponentNode) {
                componentNodes.add((ComponentNode) node);
            }
        }
        return componentNodes;
    }

    /**
     * The navigator selected nodes.
     * 
     * @return new list of selected navigator view nodes, possibly empty.
     */
    public List<Node> getSelectedNodes_NavigatorView() {
        final OtmView view = OtmRegistry.getNavigatorView();
        if (view != null) {
            return view.getSelectedNodes();
        }
        return Collections.emptyList();
    }

    public List<Node> getSelectedNodes_TypeView() {
        final OtmView view = OtmRegistry.getTypeView();
        if (view != null) {
            return view.getSelectedNodes();
        }
        return Collections.emptyList();
    }

    /**
     * Refresh all views convenience method.
     */
    public void refresh() {
        OtmRegistry.getNavigatorView().refreshAllViews();
        fireRefreshNotyfication(null);
    }

    public void addRefreshListener(IRefreshListener listener) {
        refreshList.add(listener);
    }

    public void removeRefreshListener(IRefreshListener listener) {
        refreshList.remove(listener);
    }

    public interface IRefreshListener {
        public void refresh(INode node);

        public void refresh();
    }

    public void refresh(final INode node) {
        Display.getDefault().syncExec(new Runnable() {

            @Override
            public void run() {
                OtmRegistry.getNavigatorView().refreshAllViews(node);
                fireRefreshNotyfication(node);
            }
        });
    }

    private void fireRefreshNotyfication(INode node) {
        for (Object lis : refreshList.getListeners()) {
            IRefreshListener ref = (IRefreshListener) lis;
            if (node == null) {
                ref.refresh();
            } else {
                ref.refresh(node);
            }
        }
    }

    /** *********************************** Command and Action methods ****************** **/

    /**
     * Run the
     */
    public void runAddProperties(Event event) {
        String cmd = AddNodeHandler.COMMAND_ID;
        runCommand(cmd, event);
    }

    /**
     * Run the
     */
    public void runDeleteNode(Event event) {
        String cmd = "org.opentravel.schemas.commands.DeleteNode";
        runCommand(cmd, event);
    }

    /**
     * Run the
     */
    public void runSaveLibraries(Event event) {
        String cmd = "org.opentravel.schemas.commands.SaveLibraries";
        runCommand(cmd, event);
    }

    /**
     * Run a command handler.
     * 
     * @param cmd
     *            = COMMAND_ID from handler
     * @param node
     *            to pass in command event.
     */
    public void runCommand(String cmd, Node node) {
        Event event = new Event();
        event.data = node;
        runCommand(cmd, event);
    }

    public void runCommand(String cmd, Event event) {
        if (mainWindow != null && mainWindow.hasDisplay()) {
            if (site == null)
                site = mainWindow.getSite();
            // TODO - TEST - used to get site from navigator window
            if (handlerService == null)
                handlerService = (IHandlerService) site.getService(IHandlerService.class);
            try {
                // LOGGER.debug("Ready to execute command: "+cmd+" with event: "+event);
                handlerService.executeCommand(cmd, event);
            } catch (Exception ex) {
                LOGGER.error("Command error: " + ex.getLocalizedMessage());
                // DialogUserNotifier.openWarning(WARNING_MSG, "Could not execute command.");
            }
        } else {
            // LOGGER.debug("TODO - add non-workbench command dispatch");
        }
    }

    /**
     * Post a message on the status line. Preferred method for status as it is safe to include in code that can be run
     * in junit tests.
     * 
     * @param msg
     */
    public void postStatus(String msg) {
        if (mainWindow != null)
            mainWindow.postStatus(msg);
        else
            LOGGER.debug(msg);
    }

    /**
     * Show that the system is busy.
     */
    public void showBusy(boolean state) {
        if (mainWindow.hasDisplay())
            mainWindow.showBusy(state);
    }

    /** ********************* LEGACY BUSINESS LOGIC *************************** **/

    public void addQueryFacet() {
        addFacet(TLFacetType.QUERY);
    }

    public void addCustomFacet() {
        addFacet(TLFacetType.CUSTOM);
    }

    // TODO - make into command. Have the two actions use a parameter so that there can be just one.
    private void addFacet(final TLFacetType facetType) {
        if (!(getSelectedNode_NavigatorView() instanceof ComponentNode))
            return;

        final ComponentNode current = (ComponentNode) getSelectedNode_NavigatorView();

        if (current != null && current.isBusinessObject()) {
            if (!current.getLibrary().isMajorVersion()) {
                // New facets can only be added in major versions.
                // TODO - consider allowing them in minor and use createMinorVersionOfComponent()
                LOGGER.debug("Tried to add facet to a minor or patch version.");
                return;
            }

            // Custom facets can only have properties that are also in the detail while query can
            // have others.
            // custom can now have any property set!
            final ComponentNode propertyOwner = facetType.equals(TLFacetType.CUSTOM) ? current.getDetailFacet()
                    : current;

            // Set up the wizard
            // FIXME - not getting all the newly created contexts!
            String defaultContext = contextController.getDefaultContextId(current.getLibrary());
            String defaultName = "";
            boolean canBeEmpty = TLFacetType.QUERY.equals(facetType);
            if (TLFacetType.CUSTOM.equals(facetType)) {
                defaultName = defaultContext;
            }
            final NewFacetWizard wizard = new NewFacetWizard(propertyOwner, defaultName);
            wizard.setValidator(new NewFacetValidator(current, facetType, wizard));

            wizard.run(OtmRegistry.getActiveShell());
            if (!wizard.wasCanceled()) {
                // LOGGER.info("Creating new custom facet of type " + facetType + " and properties "
                // + wizard.getSelectedProperties());
                // Get the name from the wizard (enhance wizard)

                BusinessObjectNode bo = (BusinessObjectNode) current;
                if (TLFacetType.QUERY.equals(facetType)
                        && (wizard.getName() == null || wizard.getName().isEmpty())) {
                    defaultContext = null;
                }
                FacetNode newFacet = bo.addFacet(wizard.getName(), defaultContext, facetType);
                for (final PropertyNode n : wizard.getSelectedProperties()) {
                    NodeFactory.newComponentMember(newFacet, n.cloneTLObj());
                }
                refresh(bo);
            }
        } else {
            DialogUserNotifier.openWarning("Add Custom Facet",
                    "Custom Facets can only be added to Business Objects");
            // LOGGER.warn("New custom facet can be added only to Business Objects, tried to add to: " + current);
        }
    }

    /**
     * Runs change wizard on the selected component.
     */
    public void changeTreeSelection() {
        final Node n = getCurrentNode_NavigatorView();
        if (n != null) {
            changeNode((ComponentNode) n.getOwningComponent());
        }
    }

    /**
     * Change the selected type view node. Used by change object action. 1) clones node 2) replaces everything that uses
     * the selected node as a type to use the clone 3) runs wizard with the cloned node. Wizard is responsible for
     * making any model changes directed by the user. 4a) original node replaced back into the model if the wizard is
     * cancelled. 4b) original node deleted if wizard completes normally. 5) clone moved to new library if necessary
     * (TODO -- wizard should do this)
     */
    public void changeSelection() {
        final Node selected = getSelectedNode_TypeView();
        if (selected != null) {
            final ComponentNode n = (ComponentNode) selected.getOwningComponent();
            if (n != null) {
                changeNode(n);
            }
        }
    }

    private void changeNode(final ComponentNode nodeToReplace) {

        if (nodeToReplace == null || nodeToReplace.getLibrary() == null) {
            LOGGER.error("Null in change node.");
            return;
        }
        if (nodeToReplace.isService() || !nodeToReplace.isInTLLibrary()) {
            LOGGER.warn("Invalid state. Cannot change " + nodeToReplace);
            return;
        }

        // LOGGER.debug("Changing selected component: " + nodeToReplace.getName() + " with "
        // + nodeToReplace.getTypeUsersCount() + " users.");

        LibraryNode srcLib = nodeToReplace.getLibrary();
        ComponentNode editedNode = nodeToReplace;

        // LOGGER.debug("Changing Edited component: " + editedNode.getName() + " with "
        // + editedNode.getTypeUsersCount() + " users.");

        // Wizard must maintain the editedComponent active in the library.
        final ChangeWizard wizard = new ChangeWizard(editedNode);
        wizard.run(OtmRegistry.getActiveShell());
        if (wizard.wasCanceled()) {
            selectNavigatorNodeAndRefresh(nodeToReplace);
        } else {
            editedNode = wizard.getEditedComponent();
            // If the library is different than the srcLib, the object needs to be moved.
            // The library in the object is only an indicator of the library to move to.
            // The edited node will be in the src Library.
            if (!editedNode.getLibrary().equals(srcLib)) {
                LibraryNode destLib = editedNode.getLibrary();
                editedNode.setLibrary(srcLib);
                srcLib.moveMember(editedNode, destLib);
            }
            if (editedNode != nodeToReplace)
                nodeToReplace.delete();
            selectNavigatorNodeAndRefresh(editedNode);
            refresh(editedNode);

            // LOGGER.info("Component after change: " + editedComponent + " with "
            // + editedComponent.getTypeUsersCount() + " users.");
        }
        // LOGGER.debug("library has " + ln.getChildren_NamedTypes().size() + " children.");

        // Test Result
        // NodeModelTestUtils.testNodeModel();
        // Validate the library after doing change.
        checkModelCounts(srcLib);
        checkModelCounts(editedNode.getLibrary());
        // }
    }

    public static boolean checkModelCounts(final LibraryNode lib) {
        int tlCount = 0, guiCount = 0;
        guiCount = lib.getDescendants_NamedTypes().size();
        tlCount = lib.getTLaLib().getNamedMembers().size();
        if (guiCount != tlCount) {
            LOGGER.error("GUI member count " + guiCount + " is out of sync with TL model " + tlCount + ".");
            return false;
        }
        // LOGGER.debug(lib + " has " + guiCount + " children.");
        return true;
    }

    public void cloneSelectedFacetNodes() {
        // get the action list from the facet table. If none selected, use
        // facets current node.
        final List<Node> facetCloneList = getSelectedNodes_TypeView();
        final List<Node> treeCloneList = getSelectedNodes_NavigatorView();
        final Node cn = getSelectedNode_TypeView();

        if (facetCloneList.isEmpty()) {
            if (treeCloneList.isEmpty()) {
                facetCloneList.add(cn);
            } else {
                facetCloneList.addAll(treeCloneList);
            }
        }
        cloneNodes(facetCloneList);
    }

    /**
     * Implements the Copy action.
     */
    public void copySelectedNodes() {
        cloneNodes(getSelectedNodes_NavigatorView());
    }

    private void cloneNodes(List<Node> nodes) {
        // LOGGER.debug("Cloning " + nodes.size() + " selected components. ");

        Node lastCloned = null;
        for (Node n : nodes) {
            Node clone = n.clone(CopyNameSuffix);
            if (clone != null)
                lastCloned = clone;
        }
        if (lastCloned != null) {
            selectNavigatorNodeAndRefresh(lastCloned);
        }
    }

    public void importSelectedToDragTarget(boolean isCopy) {
        if (modelNode != null) {
            final Node target = handlers.getDragTargetNode();
            if (target != null && target.getLibrary() != null) {
                final LibraryNode library = target.getLibrary();
                // LOGGER.debug("Importing selected nodes to drag target library: " + library.getName());
                ImportObjectToLibraryAction action = new ImportObjectToLibraryAction(mainWindow, library);
                action.importSelectedToLibrary(library);
            } else {
                LOGGER.error("Cannot import - drag target is null");
            }
        } else {
            LOGGER.error("Cannot import - source ( model ) is null");
        }
    }

    public NewPropertiesWizard initializeNewPropertiesWizard(final INode component) {
        NewPropertiesWizard newPropertiesWizard = null;
        // code migrated to AddPropertytoComponent handler.
        return newPropertiesWizard;
    }

    /**
     *
     */
    // /TODO - move
    public void setExtendable(final boolean extendable) {
        // final Node facetNode = getSelectedNode_TypeView();
        // if (facetNode != null) {
        // LOGGER.debug("Changing extendable property of " + facetNode + " to " + extendable);
        // facetNode.setExtendable(extendable);
        // defaultView.refreshAllViews();
        // }
    }

    public void clearSelection() {
        final OtmView view = OtmRegistry.getNavigatorView();
        if (view != null) {
            view.clearSelection();
        }
    }

    public Node getPrevTreeNode() {
        final OtmView view = OtmRegistry.getNavigatorView();
        if (view != null) {
            return (Node) view.getPreviousNode();
        }
        return null;
    }

    /**
     * @param modelNode
     *            - the catalogRoot to set
     */
    public void setModelNode(final ModelNode modelNode) {
        // this.curNode = modelNode;
        // LOGGER.debug("setting catalog root node.");
        this.modelNode = modelNode;
        final OtmView mnView = OtmRegistry.getNavigatorView();
        if (mnView != null) {
            mnView.setCurrentNode(modelNode);
            mnView.setInput(modelNode);
            if (!Node.getAllUserLibraries().isEmpty())
                mnView.select(Node.getAllUserLibraries().get(0));
        }
        defaultView.refreshAllViews();
        defaultView.setCurrentNode(modelNode);
    }

    /**
     *
     */
    public void openLibraryInSystemEditor() {
        final List<LibraryNode> libs = this.getSelectedLibraries();
        final Desktop desktop = Desktop.getDesktop();
        for (final LibraryNode lib : libs) {
            final String path = lib.getPath();
            final File file = new File(path);
            try {
                if (!file.exists()) {
                    if (path.startsWith("http")) {
                        desktop.browse(new URI(path));
                    } else {
                        DialogUserNotifier.openError("Open file",
                                "Could not find the file associated to the library " + lib.getName() + " (" + path
                                        + ")");
                    }
                } else {
                    desktop.open(file);
                }
            } catch (final IOException e) {
                LOGGER.error("While opening library file in system editor " + e.getMessage(), e);
                DialogUserNotifier.openError("Open file",
                        "Could not open the file, an error occurred: " + e.getMessage());
            } catch (final URISyntaxException e) {
                LOGGER.error("While opening library file in system editor " + e.getMessage(), e);
                DialogUserNotifier.openError("Open file",
                        "Could not open the file, its URI is malformed: " + e.getMessage());
            }
        }
    }

    /**
     * Change current selection in NavigatorView.
     * 
     * @param node
     *            - node to select
     */
    public void selectNavigatorNodeAndRefresh(INode node) {
        if (OtmRegistry.getNavigatorView() != null) {
            OtmRegistry.getNavigatorView().setCurrentNode(node); // sets IView current node
            OtmRegistry.getNavigatorView().select(node); // throws section event.
        }
        // OtmRegistry.getNavigatorView().refresh(); // updates tree contents
        // in some cases NavigatorView is selecting parent of node but FacetView should select node.
        if (OtmRegistry.getTypeView() != null)
            OtmRegistry.getTypeView().setCurrentNode(node);
    }

    /**
     * @return First node selected in TypeView. If selection of TypeView is empty then return first selected node from
     *         NavigatorView otherwise return null;
     */
    public Node getGloballySelectNode() {
        Node node = getSelectedNode_TypeView();
        if (node != null) {
            return node;
        }
        node = getSelectedNode_NavigatorView();
        return node;
    }

    /**
     * @return Selected nodes in TypeView. If selection of TypeView is empty then return selected nodes from
     *         NavigatorView otherwise return empty list;
     */
    public List<Node> getGloballySelectNodes() {
        List<Node> nodes = getSelectedNodes_TypeView();
        if (nodes == null || nodes.isEmpty()) {
            nodes = getSelectedNodes_NavigatorView();
        }
        if (nodes == null) {
            nodes = Collections.emptyList();
        }
        return nodes;
    }

}