blob: b8ac2f58721fb66e33e547165ceb06097a3b25b2 [file] [log] [blame]
/**
* 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.HashMap;
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 HashMap) {
String key = (String) ((HashMap<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 HashMap) {
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 HashMap) {
if (group == null)
group = (String) ((HashMap<String, String>) ((DefaultMutableTreeNode) path[i])
.getUserObject()).keySet().iterator().next();
else
group = (String) ((HashMap<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 HashMap) {
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
String group = (String) ((HashMap<String, String>) node
.getUserObject()).keySet().iterator().next();
JLabel nameLabel = new JLabel(group + " : ");
nameLabel.setForeground(Color.blue);
nameLabel.setBackground(Color.white);
JLabel valueLabel = new JLabel(((HashMap<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 = null;
if (staticMetadata.getMetadata(group) != null) {
HashMap<String, String> map = new HashMap<String, String>();
map.put(group,
StringUtils.join(staticMetadata.getAllMetadata(group), ","));
userObj = map;
} else {
HashMap<String, String> map = new HashMap<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;
}
}