org.apache.oodt.cas.workflow.gui.perspective.view.impl.DefaultTreeView.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.oodt.cas.workflow.gui.perspective.view.impl.DefaultTreeView.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.apache.oodt.cas.workflow.gui.perspective.view.impl;

//JDK imports
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.concurrent.ConcurrentHashMap;
import java.util.List;
import java.util.Stack;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;

//Apache imports
import org.apache.commons.lang.StringUtils;

//OODT imports
import org.apache.oodt.cas.metadata.Metadata;
import org.apache.oodt.cas.workflow.gui.model.ModelGraph;
import org.apache.oodt.cas.workflow.gui.perspective.view.View;
import org.apache.oodt.cas.workflow.gui.perspective.view.ViewChange;
import org.apache.oodt.cas.workflow.gui.perspective.view.ViewState;
import org.apache.oodt.cas.workflow.gui.util.GuiUtils;

/**
 * 
 * The default Workflow GUI editor view shell.
 * 
 * @author bfoster
 * @author mattmann
 * 
 */
public class DefaultTreeView extends View {

    private static final long serialVersionUID = -8295070597651190576L;

    private JTree tree;
    private PopupMenu actionsMenu, orderSubMenu;
    private JScrollPane scrollPane;

    private static final String EXPAND_STATIC_METADATA = "DefaultTreeView/expand/static-metadata";
    private static final String EXPAND_PRECONDITIONS = "DefaultTreeView/expand/pre-conditions";
    private static final String EXPAND_POSTCONDITIONS = "DefaultTreeView/expand/post-conditions";

    public DefaultTreeView(String name) {
        super(name);
        this.setLayout(new BorderLayout());
    }

    public TreePath getTreePath(DefaultMutableTreeNode node, ModelGraph graph) {
        if (node.getUserObject().equals(graph)) {
            return new TreePath(node.getPath());
        } else {
            for (int i = 0; i < node.getChildCount(); i++) {
                // System.out.println("i: " + ((DefaultMutableTreeNode)
                // node.getChildAt(i)).getUserObject());
                TreePath treePath = this.getTreePath((DefaultMutableTreeNode) node.getChildAt(i), graph);
                if (treePath != null) {
                    return treePath;
                }
            }
            return null;
        }
    }

    private TreePath getTreePath(TreePath currentPath, ViewState state) {
        String lookingForPath = state.getCurrentMetGroup();
        Stack<DefaultMutableTreeNode> stack = new Stack<DefaultMutableTreeNode>();
        DefaultMutableTreeNode baseNode = (DefaultMutableTreeNode) currentPath.getLastPathComponent();
        for (int i = 0; i < baseNode.getChildCount(); i++) {
            stack.push((DefaultMutableTreeNode) baseNode.getChildAt(i));
        }
        while (!stack.empty()) {
            DefaultMutableTreeNode node = stack.pop();
            if (node.getUserObject().equals("static-metadata")) {
                for (int i = 0; i < node.getChildCount(); i++) {
                    stack.push((DefaultMutableTreeNode) node.getChildAt(i));
                }
            } else if (node.getUserObject() instanceof ConcurrentHashMap) {
                String key = (String) ((ConcurrentHashMap<String, String>) node.getUserObject()).keySet().iterator()
                        .next();
                if (lookingForPath.equals(key)) {
                    return new TreePath(node.getPath());
                } else if (lookingForPath.startsWith(key + "/")) {
                    lookingForPath = lookingForPath.substring(lookingForPath.indexOf("/") + 1);
                    stack.clear();
                    for (int i = 0; i < node.getChildCount(); i++) {
                        stack.add((DefaultMutableTreeNode) node.getChildAt(i));
                    }
                }
            }
        }
        return currentPath;
    }

    private void resetProperties(ViewState state) {
        state.setProperty(EXPAND_STATIC_METADATA, "false");
        state.setProperty(EXPAND_PRECONDITIONS, "false");
        state.setProperty(EXPAND_POSTCONDITIONS, "false");
    }

    @Override
    public void refreshView(final ViewState state) {
        Rectangle visibleRect = null;
        if (this.tree != null) {
            visibleRect = this.tree.getVisibleRect();
        }

        this.removeAll();

        this.actionsMenu = this.createPopupMenu(state);

        DefaultMutableTreeNode root = new DefaultMutableTreeNode("WORKFLOWS");
        for (ModelGraph graph : state.getGraphs()) {
            root.add(this.buildTree(graph, state));
        }
        tree = new JTree(root);
        tree.setShowsRootHandles(true);
        tree.setRootVisible(false);
        tree.add(this.actionsMenu);

        if (state.getSelected() != null) {
            // System.out.println("SELECTED: " + state.getSelected());
            TreePath treePath = this.getTreePath(root, state.getSelected());
            if (state.getCurrentMetGroup() != null) {
                treePath = this.getTreePath(treePath, state);
            } else if (Boolean.parseBoolean(state.getFirstPropertyValue(EXPAND_STATIC_METADATA))) {
                DefaultMutableTreeNode baseNode = (DefaultMutableTreeNode) treePath.getLastPathComponent();
                for (int i = 0; i < baseNode.getChildCount(); i++) {
                    if (((DefaultMutableTreeNode) baseNode.getChildAt(i)).getUserObject()
                            .equals("static-metadata")) {
                        treePath = new TreePath(((DefaultMutableTreeNode) baseNode.getChildAt(i)).getPath());
                        break;
                    }
                }
            } else if (Boolean.parseBoolean(state.getFirstPropertyValue(EXPAND_PRECONDITIONS))) {
                if (treePath == null) {
                    treePath = this.getTreePath(root, state.getSelected().getPreConditions());
                }
                DefaultMutableTreeNode baseNode = (DefaultMutableTreeNode) treePath.getLastPathComponent();
                for (int i = 0; i < baseNode.getChildCount(); i++) {
                    if (((DefaultMutableTreeNode) baseNode.getChildAt(i)).getUserObject()
                            .equals("pre-conditions")) {
                        treePath = new TreePath(((DefaultMutableTreeNode) baseNode.getChildAt(i)).getPath());
                        break;
                    }
                }
            } else if (Boolean.parseBoolean(state.getFirstPropertyValue(EXPAND_POSTCONDITIONS))) {
                if (treePath == null) {
                    treePath = this.getTreePath(root, state.getSelected().getPostConditions());
                }
                DefaultMutableTreeNode baseNode = (DefaultMutableTreeNode) treePath.getLastPathComponent();
                for (int i = 0; i < baseNode.getChildCount(); i++) {
                    if (((DefaultMutableTreeNode) baseNode.getChildAt(i)).getUserObject()
                            .equals("post-conditions")) {
                        treePath = new TreePath(((DefaultMutableTreeNode) baseNode.getChildAt(i)).getPath());
                        break;
                    }
                }
            }
            this.tree.expandPath(treePath);
            this.tree.setSelectionPath(treePath);
        }

        tree.addTreeSelectionListener(new TreeSelectionListener() {

            public void valueChanged(TreeSelectionEvent e) {
                if (e.getPath().getLastPathComponent() instanceof DefaultMutableTreeNode) {
                    DefaultTreeView.this.resetProperties(state);
                    DefaultMutableTreeNode node = (DefaultMutableTreeNode) e.getPath().getLastPathComponent();
                    if (node.getUserObject() instanceof ModelGraph) {
                        state.setSelected((ModelGraph) node.getUserObject());
                        state.setCurrentMetGroup(null);
                        DefaultTreeView.this.notifyListeners();
                    } else if (node.getUserObject().equals("static-metadata")
                            || node.getUserObject().equals("pre-conditions")
                            || node.getUserObject().equals("post-conditions")) {
                        state.setSelected((ModelGraph) ((DefaultMutableTreeNode) node.getParent()).getUserObject());
                        state.setCurrentMetGroup(null);
                        state.setProperty(EXPAND_STATIC_METADATA,
                                Boolean.toString(node.getUserObject().equals("static-metadata")));
                        state.setProperty(EXPAND_PRECONDITIONS,
                                Boolean.toString(node.getUserObject().equals("pre-conditions")));
                        state.setProperty(EXPAND_POSTCONDITIONS,
                                Boolean.toString(node.getUserObject().equals("post-conditions")));
                        DefaultTreeView.this.notifyListeners();
                    } else if (node.getUserObject() instanceof ConcurrentHashMap) {
                        DefaultMutableTreeNode metNode = null;
                        String group = null;
                        Object[] path = e.getPath().getPath();
                        for (int i = path.length - 1; i >= 0; i--) {
                            if (((DefaultMutableTreeNode) path[i]).getUserObject() instanceof ModelGraph) {
                                metNode = (DefaultMutableTreeNode) path[i];
                                break;
                            } else if (((DefaultMutableTreeNode) path[i])
                                    .getUserObject() instanceof ConcurrentHashMap) {
                                if (group == null) {
                                    group = (String) ((ConcurrentHashMap<String, String>) ((DefaultMutableTreeNode) path[i])
                                            .getUserObject()).keySet().iterator().next();
                                } else {
                                    group = (String) ((ConcurrentHashMap<String, String>) ((DefaultMutableTreeNode) path[i])
                                            .getUserObject()).keySet().iterator().next() + "/" + group;
                                }
                            }
                        }
                        ModelGraph graph = (ModelGraph) metNode.getUserObject();
                        state.setSelected(graph);
                        state.setCurrentMetGroup(group);
                        DefaultTreeView.this.notifyListeners();
                    } else {
                        state.setSelected(null);
                        DefaultTreeView.this.notifyListeners();
                    }
                }
            }

        });
        tree.setCellRenderer(new TreeCellRenderer() {

            public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected,
                    boolean expanded, boolean leaf, int row, boolean hasFocus) {
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
                if (node.getUserObject() instanceof String) {
                    JPanel panel = new JPanel();
                    panel.setLayout(new BorderLayout());
                    JLabel label = new JLabel((String) node.getUserObject());
                    label.setForeground(Color.blue);
                    panel.add(label, BorderLayout.CENTER);
                    panel.setBackground(selected ? Color.lightGray : Color.white);
                    return panel;
                } else if (node.getUserObject() instanceof ModelGraph) {
                    JPanel panel = new JPanel();
                    panel.setLayout(new BorderLayout());
                    JLabel iconLabel = new JLabel(
                            ((ModelGraph) node.getUserObject()).getModel().getExecutionType() + ": ");
                    iconLabel.setForeground(((ModelGraph) node.getUserObject()).getModel().getColor());
                    iconLabel.setBackground(Color.white);
                    JLabel idLabel = new JLabel(((ModelGraph) node.getUserObject()).getModel().getModelName());
                    idLabel.setBackground(Color.white);
                    panel.add(iconLabel, BorderLayout.WEST);
                    panel.add(idLabel, BorderLayout.CENTER);
                    panel.setBackground(selected ? Color.lightGray : Color.white);
                    return panel;
                } else if (node.getUserObject() instanceof ConcurrentHashMap) {
                    JPanel panel = new JPanel();
                    panel.setLayout(new BorderLayout());
                    String group = (String) ((ConcurrentHashMap<String, String>) node.getUserObject()).keySet()
                            .iterator().next();
                    JLabel nameLabel = new JLabel(group + " : ");
                    nameLabel.setForeground(Color.blue);
                    nameLabel.setBackground(Color.white);
                    JLabel valueLabel = new JLabel(
                            ((ConcurrentHashMap<String, String>) node.getUserObject()).get(group));
                    valueLabel.setForeground(Color.darkGray);
                    valueLabel.setBackground(Color.white);
                    panel.add(nameLabel, BorderLayout.WEST);
                    panel.add(valueLabel, BorderLayout.EAST);
                    panel.setBackground(selected ? Color.lightGray : Color.white);
                    return panel;
                } else {
                    return new JLabel();
                }
            }

        });
        tree.addMouseListener(new MouseListener() {
            public void mouseClicked(MouseEvent e) {
                if (e.getButton() == MouseEvent.BUTTON3 && DefaultTreeView.this.tree.getSelectionPath() != null) {
                    DefaultMutableTreeNode node = (DefaultMutableTreeNode) DefaultTreeView.this.tree
                            .getSelectionPath().getLastPathComponent();
                    if (node.getUserObject() instanceof String && !(node.getUserObject().equals("pre-conditions")
                            || node.getUserObject().equals("post-conditions"))) {
                        return;
                    }
                    orderSubMenu.setEnabled(node.getUserObject() instanceof ModelGraph
                            && !((ModelGraph) node.getUserObject()).isCondition()
                            && ((ModelGraph) node.getUserObject()).getParent() != null);
                    DefaultTreeView.this.actionsMenu.show(DefaultTreeView.this.tree, e.getX(), e.getY());
                }
            }

            public void mouseEntered(MouseEvent e) {
            }

            public void mouseExited(MouseEvent e) {
            }

            public void mousePressed(MouseEvent e) {
            }

            public void mouseReleased(MouseEvent e) {
            }
        });
        this.scrollPane = new JScrollPane(tree, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        this.add(this.scrollPane, BorderLayout.CENTER);
        if (visibleRect != null) {
            this.tree.scrollRectToVisible(visibleRect);
        }

        this.revalidate();
    }

    private DefaultMutableTreeNode buildTree(ModelGraph graph, ViewState state) {
        DefaultMutableTreeNode node = new DefaultMutableTreeNode(graph);
        DefaultMutableTreeNode metadataNode = new DefaultMutableTreeNode("static-metadata");
        Metadata staticMetadata = new Metadata();
        if (graph.getInheritedStaticMetadata(state) != null) {
            staticMetadata.replaceMetadata(graph.getInheritedStaticMetadata(state));
        }
        if (graph.getModel().getStaticMetadata() != null) {
            staticMetadata.replaceMetadata(graph.getModel().getStaticMetadata());
        }
        this.addMetadataNodes(metadataNode, staticMetadata);
        if (!metadataNode.isLeaf()) {
            node.add(metadataNode);
        }

        if (graph.getPreConditions() != null) {
            DefaultMutableTreeNode preConditions = new DefaultMutableTreeNode("pre-conditions");
            List<ModelGraph> leafNodes = graph.getPreConditions().getLeafNodes();
            for (ModelGraph cond : leafNodes) {
                DefaultMutableTreeNode condNode = new DefaultMutableTreeNode(cond);
                preConditions.add(condNode);
            }
            node.add(preConditions);
        }
        if (graph.getPostConditions() != null) {
            DefaultMutableTreeNode postConditions = new DefaultMutableTreeNode("post-conditions");
            List<ModelGraph> leafNodes = graph.getPostConditions().getLeafNodes();
            for (ModelGraph cond : leafNodes) {
                DefaultMutableTreeNode condNode = new DefaultMutableTreeNode(cond);
                postConditions.add(condNode);
            }
            node.add(postConditions);
        }
        for (ModelGraph child : graph.getChildren()) {
            if (!GuiUtils.isDummyNode(child.getModel())) {
                node.add(this.buildTree(child, state));
            }
        }
        return node;
    }

    private void addMetadataNodes(DefaultMutableTreeNode metadataNode, Metadata staticMetadata) {
        for (String group : staticMetadata.getGroups()) {
            Object userObj;
            if (staticMetadata.getMetadata(group) != null) {
                ConcurrentHashMap<String, String> map = new ConcurrentHashMap<String, String>();
                map.put(group, StringUtils.join(staticMetadata.getAllMetadata(group), ","));
                userObj = map;
            } else {
                ConcurrentHashMap<String, String> map = new ConcurrentHashMap<String, String>();
                map.put(group, null);
                userObj = map;
            }
            DefaultMutableTreeNode groupNode = new DefaultMutableTreeNode(userObj);
            metadataNode.add(groupNode);
            this.addMetadataNodes(groupNode, staticMetadata.getSubMetadata(group));
        }
    }

    private PopupMenu createPopupMenu(final ViewState state) {
        final String ACTIONS_POP_MENU_NAME = "Actions";
        final String VIEW_CONDITION_MAP = "View...";
        PopupMenu actionsMenu = new PopupMenu(ACTIONS_POP_MENU_NAME);
        actionsMenu.add(new MenuItem(VIEW_CONDITION_MAP));
        actionsMenu.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                if (e.getActionCommand().equals(VIEW_CONDITION_MAP)) {
                    DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getSelectionPath()
                            .getLastPathComponent();
                    ModelGraph graphToFocus = null;
                    if (Boolean.parseBoolean(state.getFirstPropertyValue(EXPAND_PRECONDITIONS))
                            || Boolean.parseBoolean(state.getFirstPropertyValue(EXPAND_POSTCONDITIONS))) {
                        // if (node.getUserObject() instanceof String &&
                        // (node.getUserObject().equals("pre-conditions") ||
                        // node.getUserObject().equals("post-conditions"))) {
                        ModelGraph graph = state.getSelected();
                        if (Boolean.parseBoolean(state.getFirstPropertyValue(EXPAND_PRECONDITIONS))) {
                            graphToFocus = graph.getPreConditions();
                        } else {
                            graphToFocus = graph.getPostConditions();
                        }
                    } else if (node.getUserObject() instanceof ModelGraph) {
                        graphToFocus = (ModelGraph) node.getUserObject();
                    }
                    DefaultTreeView.this
                            .notifyListeners(new ViewChange.NEW_VIEW(graphToFocus, DefaultTreeView.this));
                }
            }

        });

        final String ORDER_SUB_POP_MENU_NAME = "Order";
        final String TO_FRONT_ITEM_NAME = "Move To Front";
        final String TO_BACK_ITEM_NAME = "Move To Back";
        final String FORWARD_ITEM_NAME = "Move Forward";
        final String BACKWARDS_ITEM_NAME = "Move Backwards";
        actionsMenu.add(orderSubMenu = new PopupMenu(ORDER_SUB_POP_MENU_NAME));
        orderSubMenu.add(new MenuItem(TO_FRONT_ITEM_NAME));
        orderSubMenu.add(new MenuItem(TO_BACK_ITEM_NAME));
        orderSubMenu.add(new MenuItem(FORWARD_ITEM_NAME));
        orderSubMenu.add(new MenuItem(BACKWARDS_ITEM_NAME));
        orderSubMenu.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                ModelGraph graph = state.getSelected();
                ModelGraph parent = graph.getParent();
                if (e.getActionCommand().equals(TO_FRONT_ITEM_NAME)) {
                    if (parent.getChildren().remove(graph)) {
                        parent.getChildren().add(0, graph);
                    }
                } else if (e.getActionCommand().equals(TO_BACK_ITEM_NAME)) {
                    if (parent.getChildren().remove(graph)) {
                        parent.getChildren().add(graph);
                    }
                } else if (e.getActionCommand().equals(FORWARD_ITEM_NAME)) {
                    int index = parent.getChildren().indexOf(graph);
                    if (index != -1) {
                        parent.getChildren().remove(index);
                        parent.getChildren().add(Math.max(0, index + 1), graph);
                    }
                } else if (e.getActionCommand().equals(BACKWARDS_ITEM_NAME)) {
                    int index = parent.getChildren().indexOf(graph);
                    if (index != -1) {
                        parent.getChildren().remove(index);
                        parent.getChildren().add(Math.max(0, index - 1), graph);
                    }
                }
                DefaultTreeView.this.notifyListeners();
                DefaultTreeView.this.refreshView(state);
            }

        });
        return actionsMenu;
    }

}