0001: /*
0002: * <copyright>
0003: *
0004: * Copyright 2000-2004 BBNT Solutions, LLC
0005: * under sponsorship of the Defense Advanced Research Projects
0006: * Agency (DARPA).
0007: *
0008: * You can redistribute this software and/or modify it under the
0009: * terms of the Cougaar Open Source License as published on the
0010: * Cougaar Open Source Website (www.cougaar.org).
0011: *
0012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0023: *
0024: * </copyright>
0025: */
0026:
0027: package org.cougaar.tools.csmart.ui.experiment;
0028:
0029: import org.cougaar.tools.csmart.core.property.BaseComponent;
0030: import org.cougaar.tools.csmart.core.property.Property;
0031: import org.cougaar.tools.csmart.core.property.name.ComponentName;
0032: import org.cougaar.tools.csmart.experiment.DBExperiment;
0033: import org.cougaar.tools.csmart.experiment.HostComponent;
0034: import org.cougaar.tools.csmart.experiment.NodeComponent;
0035: import org.cougaar.tools.csmart.experiment.Experiment;
0036: import org.cougaar.tools.csmart.society.AgentComponent;
0037: import org.cougaar.tools.csmart.society.SocietyComponent;
0038: import org.cougaar.tools.csmart.ui.tree.ConsoleDNDTree;
0039: import org.cougaar.tools.csmart.ui.tree.ConsoleTreeObject;
0040: import org.cougaar.tools.csmart.ui.tree.DNDTree;
0041: import org.cougaar.tools.csmart.ui.util.Util;
0042: import org.cougaar.tools.csmart.ui.viewer.CSMART;
0043: import org.cougaar.util.log.Logger;
0044:
0045: import javax.swing.*;
0046: import javax.swing.border.BevelBorder;
0047: import javax.swing.event.TreeModelEvent;
0048: import javax.swing.event.TreeModelListener;
0049: import javax.swing.event.TreeSelectionListener;
0050: import javax.swing.tree.DefaultMutableTreeNode;
0051: import javax.swing.tree.DefaultTreeCellRenderer;
0052: import javax.swing.tree.DefaultTreeModel;
0053: import javax.swing.tree.TreePath;
0054: import java.awt.*;
0055: import java.awt.event.ActionEvent;
0056: import java.awt.event.ActionListener;
0057: import java.awt.event.MouseAdapter;
0058: import java.awt.event.MouseEvent;
0059: import java.awt.event.MouseListener;
0060: import java.io.IOException;
0061: import java.io.RandomAccessFile;
0062: import java.util.*;
0063: import java.util.List;
0064:
0065: /**
0066: * Tabbed pane for assigning Hosts to Nodes to Agents
0067: **/
0068: public class HostConfigurationBuilder extends JPanel implements
0069: TreeModelListener {
0070: Experiment experiment;
0071: ExperimentBuilder experimentBuilder;
0072: boolean isEditable;
0073: SocietyComponent societyComponent;
0074: JPopupMenu hostRootMenu;
0075: JPopupMenu hostHostMenu;
0076: JPopupMenu hostNodeMenu;
0077: JPopupMenu hostAgentMenu;
0078: JPopupMenu nodeRootMenu;
0079: JPopupMenu nodeNodeMenu;
0080: JPopupMenu nodeAgentMenu;
0081: JPopupMenu agentAgentMenu;
0082: JPopupMenu viewOnlyHostMenu;
0083: JPopupMenu viewOnlyNodeMenu;
0084: JMenuItem cmdLineNodeMenuItem;
0085: JMenuItem cmdLineNodeInHostMenuItem;
0086: JMenuItem newNodeInHostMenuItem;
0087: public JMenuItem showComponentsHostMenuItem;
0088: public JMenuItem showComponentsNodeMenuItem;
0089: public JMenuItem showComponentsHostAMenuItem;
0090: public JMenuItem showComponentsNodeAMenuItem;
0091: public JMenuItem showComponentsAgentMenuItem;
0092: DNDTree hostTree;
0093: DNDTree nodeTree;
0094: DNDTree agentTree;
0095:
0096: private transient Logger log;
0097:
0098: // menu items for popup menu in hostTree and for
0099: // File menu in ExperimentBuilder
0100: public static final String NEW_HOST_MENU_ITEM = "New Host...";
0101: public static final String NEW_NODE_MENU_ITEM = "New Node...";
0102: public static final String DELETE_MENU_ITEM = "Delete";
0103: public static final String DELETE_HOST_MENU_ITEM = "Delete Host";
0104: public static final String DELETE_NODE_MENU_ITEM = "Delete Node";
0105: public static final String DESCRIBE_MENU_ITEM = "Describe...";
0106: public static final String DESCRIBE_HOST_MENU_ITEM = "Describe Host...";
0107: public static final String DESCRIBE_NODE_MENU_ITEM = "Describe Node...";
0108: public static final String NODE_COMMAND_LINE_MENU_ITEM = "Command Line Arguments...";
0109: public static final String GLOBAL_COMMAND_LINE_MENU_ITEM = "Global Command Line Arguments...";
0110: public static final String HOST_TYPE_MENU_ITEM = "Type...";
0111: public static final String HOST_LOCATION_MENU_ITEM = "Location...";
0112: public static final String DISPLAY_ARGS_ACTION = "Display Command Line Arguments";
0113: private static final String SHOW_COMPONENTS_MENU_ITEM = "Show Components";
0114: private JPanel hostConfigurationBuilder;
0115: // map agent component to node component
0116: private Hashtable agentToNode = new Hashtable();
0117: // map node component to host component
0118: private Hashtable nodeToHost = new Hashtable();
0119:
0120: public HostConfigurationBuilder(Experiment experiment,
0121: ExperimentBuilder experimentBuilder) {
0122: createLogger();
0123: this .experiment = experiment;
0124: this .experimentBuilder = experimentBuilder;
0125: hostConfigurationBuilder = this ; // for inner class dialogs
0126: if (experimentBuilder == null)
0127: isEditable = false; // not editable if we're not in experiment builder
0128: else
0129: isEditable = true;
0130: initDisplay();
0131: }
0132:
0133: private void createLogger() {
0134: log = CSMART.createLogger(this .getClass().getName());
0135: }
0136:
0137: private void initDisplay() {
0138: // host split pane contains host tree and
0139: // the bottom split pane which contains the node and agent trees
0140: JSplitPane hostPane = new JSplitPane(
0141: JSplitPane.HORIZONTAL_SPLIT);
0142:
0143: // tree of hosts and assigned nodes and agents
0144: DefaultMutableTreeNode root = new DefaultMutableTreeNode(
0145: new ConsoleTreeObject("Hosts", HostComponent.class
0146: .getName()));
0147: // setting "askAllowsChildren" forces empty nodes that can have
0148: // children to be displayed as "folders" rather than leaf nodes
0149: DefaultTreeModel model = createModel(experiment, root, true);
0150: hostTree = new ConsoleDNDTree(model);
0151: hostTree.setExpandsSelectedPaths(true);
0152: // cell editor returns false if user tries to edit root node
0153: DefaultCellEditor myEditor = new DefaultCellEditor(
0154: new JTextField()) {
0155: public boolean isCellEditable(EventObject e) {
0156: if (super .isCellEditable(e) && e instanceof MouseEvent) {
0157: TreePath path = hostTree.getPathForLocation(
0158: ((MouseEvent) e).getX(), ((MouseEvent) e)
0159: .getY());
0160: if (path == null)
0161: return false;
0162: Object o = path.getLastPathComponent();
0163: DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) o;
0164: if (treeNode.isRoot()
0165: || ((ConsoleTreeObject) treeNode
0166: .getUserObject()).isAgent())
0167: return false;
0168: }
0169: return super .isCellEditable(e);
0170: }
0171:
0172: public boolean stopCellEditing() {
0173: TreePath path = hostTree.getEditingPath();
0174: DefaultMutableTreeNode node = (DefaultMutableTreeNode) path
0175: .getLastPathComponent();
0176: int result = 0;
0177: if (node.getUserObject() instanceof ConsoleTreeObject) {
0178: ConsoleTreeObject cto = (ConsoleTreeObject) node
0179: .getUserObject();
0180: if (cto.isHost()) {
0181: // stop cell editing, accept new unique value
0182: if (isHostNameUnique((String) getCellEditorValue()))
0183: return super .stopCellEditing();
0184: // tell user that value isn't unique
0185: result = JOptionPane.showConfirmDialog(
0186: hostConfigurationBuilder,
0187: "Use an unique name",
0188: "Host Name Not Unique",
0189: JOptionPane.OK_CANCEL_OPTION,
0190: JOptionPane.ERROR_MESSAGE);
0191: } else if (cto.isNode()) {
0192: // stop cell editing, accept new unique value
0193: if (isNodeNameUnique((String) getCellEditorValue()))
0194: return super .stopCellEditing();
0195: // tell user that value isn't unique
0196: result = JOptionPane.showConfirmDialog(
0197: hostConfigurationBuilder,
0198: "Use an unique name",
0199: "Node Name Not Unique",
0200: JOptionPane.OK_CANCEL_OPTION,
0201: JOptionPane.ERROR_MESSAGE);
0202: }
0203: } else
0204: return super .stopCellEditing();
0205: // user cancelled the message dialog, so cancel the editing
0206: if (result != JOptionPane.OK_OPTION) {
0207: cancelCellEditing();
0208: return true;
0209: }
0210: // user entered non-unique value, not done editing
0211: return false;
0212: }
0213: };
0214: hostTree.setCellEditor(myEditor);
0215:
0216: JScrollPane hostTreeScrollPane = new JScrollPane(hostTree);
0217: hostTreeScrollPane.setBorder(BorderFactory
0218: .createBevelBorder(BevelBorder.LOWERED));
0219: hostPane.setTopComponent(hostTreeScrollPane);
0220: // hostTree.getModel().addTreeModelListener(this);
0221:
0222: // create popup menus for host tree
0223: hostRootMenu = new JPopupMenu();
0224: hostHostMenu = new JPopupMenu();
0225: hostNodeMenu = new JPopupMenu();
0226: hostAgentMenu = new JPopupMenu();
0227: viewOnlyHostMenu = new JPopupMenu();
0228: viewOnlyNodeMenu = new JPopupMenu();
0229:
0230: JMenuItem newHostMenuItem = new JMenuItem(NEW_HOST_MENU_ITEM);
0231: newHostMenuItem.addActionListener(new ActionListener() {
0232: public void actionPerformed(ActionEvent e) {
0233: createHost();
0234: }
0235: });
0236:
0237: JMenuItem deleteHostMenuItem = new JMenuItem(DELETE_MENU_ITEM);
0238: deleteHostMenuItem.addActionListener(new ActionListener() {
0239: public void actionPerformed(ActionEvent e) {
0240: deleteHost();
0241: }
0242: });
0243:
0244: newNodeInHostMenuItem = new JMenuItem(NEW_NODE_MENU_ITEM);
0245: newNodeInHostMenuItem.addActionListener(new ActionListener() {
0246: public void actionPerformed(ActionEvent e) {
0247: createAssignedNode();
0248: }
0249: });
0250:
0251: JMenuItem hostDescriptionMenuItem = new JMenuItem(
0252: DESCRIBE_MENU_ITEM);
0253: hostDescriptionMenuItem.addActionListener(new ActionListener() {
0254: public void actionPerformed(ActionEvent e) {
0255: setHostDescription();
0256: }
0257: });
0258:
0259: JMenuItem hostLocationMenuItem = new JMenuItem(
0260: HOST_LOCATION_MENU_ITEM);
0261: hostLocationMenuItem.addActionListener(new ActionListener() {
0262: public void actionPerformed(ActionEvent e) {
0263: setHostLocation();
0264: }
0265: });
0266:
0267: JMenuItem hostTypeMenuItem = new JMenuItem(HOST_TYPE_MENU_ITEM);
0268: hostTypeMenuItem.addActionListener(new ActionListener() {
0269: public void actionPerformed(ActionEvent e) {
0270: setHostType();
0271: }
0272: });
0273:
0274: JMenuItem describeNodeInHostMenuItem = new JMenuItem(
0275: DESCRIBE_MENU_ITEM);
0276: describeNodeInHostMenuItem
0277: .addActionListener(new ActionListener() {
0278: public void actionPerformed(ActionEvent e) {
0279: setNodeDescription(hostTree);
0280: }
0281: });
0282:
0283: cmdLineNodeInHostMenuItem = new JMenuItem(
0284: NODE_COMMAND_LINE_MENU_ITEM);
0285: cmdLineNodeInHostMenuItem
0286: .addActionListener(new ActionListener() {
0287: public void actionPerformed(ActionEvent e) {
0288: setNodeCommandLine((DefaultMutableTreeNode) hostTree
0289: .getLastSelectedPathComponent());
0290: }
0291: });
0292: cmdLineNodeInHostMenuItem.setEnabled(true);
0293:
0294: Action globalCmdLineAction = new AbstractAction(
0295: GLOBAL_COMMAND_LINE_MENU_ITEM) {
0296: public void actionPerformed(ActionEvent e) {
0297: setGlobalCommandLine();
0298: }
0299: };
0300:
0301: JMenuItem deleteNodeInHostMenuItem = new JMenuItem(
0302: DELETE_MENU_ITEM);
0303: deleteNodeInHostMenuItem
0304: .addActionListener(new ActionListener() {
0305: public void actionPerformed(ActionEvent e) {
0306: deleteNodesFromTree(hostTree);
0307: }
0308: });
0309:
0310: showComponentsHostMenuItem = new JMenuItem(
0311: SHOW_COMPONENTS_MENU_ITEM);
0312: showComponentsHostMenuItem
0313: .addActionListener(new ActionListener() {
0314: public void actionPerformed(ActionEvent e) {
0315: showAgentComponents(hostTree);
0316: }
0317: });
0318:
0319: showComponentsHostAMenuItem = new JMenuItem(
0320: SHOW_COMPONENTS_MENU_ITEM);
0321: showComponentsHostAMenuItem
0322: .addActionListener(new ActionListener() {
0323: public void actionPerformed(ActionEvent e) {
0324: showAgentComponents(hostTree);
0325: }
0326: });
0327:
0328: // init pop-up menus
0329: hostRootMenu.add(newHostMenuItem);
0330: hostRootMenu.add(globalCmdLineAction);
0331:
0332: hostHostMenu.add(hostDescriptionMenuItem);
0333: hostHostMenu.add(hostTypeMenuItem);
0334: hostHostMenu.add(hostLocationMenuItem);
0335: hostHostMenu.add(newNodeInHostMenuItem);
0336: hostHostMenu.add(globalCmdLineAction);
0337: hostHostMenu.add(deleteHostMenuItem);
0338:
0339: hostNodeMenu.add(describeNodeInHostMenuItem);
0340: hostNodeMenu.add(cmdLineNodeInHostMenuItem);
0341: hostNodeMenu.add(globalCmdLineAction);
0342: hostNodeMenu.add(deleteNodeInHostMenuItem);
0343: hostNodeMenu.add(showComponentsHostMenuItem);
0344:
0345: hostAgentMenu.add(showComponentsHostAMenuItem);
0346:
0347: Action viewArgumentsHostAction = new AbstractAction(
0348: DISPLAY_ARGS_ACTION) {
0349: public void actionPerformed(ActionEvent e) {
0350: displayArguments(viewOnlyHostMenu.getInvoker());
0351: }
0352: };
0353: viewOnlyHostMenu.add(viewArgumentsHostAction);
0354:
0355: // Can't add this directly - must be a copy
0356: // viewOnlyHostMenu.add(showComponentsHostMenuItem);
0357:
0358: // attach a mouse listener to the host tree to display menu
0359: MouseListener hostTreeMouseListener = new MouseAdapter() {
0360: public void mouseClicked(MouseEvent e) {
0361: if (e.isPopupTrigger())
0362: displayHostTreeMenu(e);
0363: }
0364:
0365: public void mousePressed(MouseEvent e) {
0366: if (e.isPopupTrigger())
0367: displayHostTreeMenu(e);
0368: }
0369:
0370: public void mouseReleased(MouseEvent e) {
0371: if (e.isPopupTrigger())
0372: displayHostTreeMenu(e);
0373: }
0374: };
0375: hostTree.addMouseListener(hostTreeMouseListener);
0376:
0377: // bottom split pane contains the node and agent trees
0378: JSplitPane bottomPane = new JSplitPane(
0379: JSplitPane.HORIZONTAL_SPLIT);
0380: // tree of unassigned nodes
0381: ConsoleTreeObject cto = new ConsoleTreeObject(
0382: "Nodes (unassigned)", NodeComponent.class.getName());
0383: root = new DefaultMutableTreeNode(cto, true);
0384: model = createModel(experiment, root, true);
0385: nodeTree = new ConsoleDNDTree(model);
0386: // cell editor returns false if try to edit agent names or root name
0387: DefaultCellEditor nodeEditor = new DefaultCellEditor(
0388: new JTextField()) {
0389: public boolean isCellEditable(EventObject e) {
0390: if (super .isCellEditable(e) && e instanceof MouseEvent) {
0391: TreePath path = hostTree.getPathForLocation(
0392: ((MouseEvent) e).getX(), ((MouseEvent) e)
0393: .getY());
0394: if (path == null)
0395: return false;
0396: Object o = path.getLastPathComponent();
0397: DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) o;
0398: if (treeNode.isRoot()
0399: || ((ConsoleTreeObject) treeNode
0400: .getUserObject()).isAgent())
0401: return false;
0402: }
0403: return super .isCellEditable(e);
0404: }
0405:
0406: public boolean stopCellEditing() {
0407: // stop cell editing, accept new unique value
0408: if (isNodeNameUnique((String) getCellEditorValue()))
0409: return super .stopCellEditing();
0410: // tell user that value isn't unique
0411: int ok = JOptionPane.showConfirmDialog(
0412: hostConfigurationBuilder, "Use an unique name",
0413: "Node Name Not Unique",
0414: JOptionPane.OK_CANCEL_OPTION,
0415: JOptionPane.ERROR_MESSAGE);
0416: // user cancelled the message dialog, so cancel the editing
0417: if (ok != JOptionPane.OK_OPTION) {
0418: cancelCellEditing();
0419: return true;
0420: }
0421: // user entered non-unique value, not done editing
0422: return false;
0423: }
0424: };
0425: nodeTree.setCellEditor(nodeEditor);
0426: nodeTree.setExpandsSelectedPaths(true);
0427: JScrollPane nodeTreeScrollPane = new JScrollPane(nodeTree);
0428: nodeTreeScrollPane.setBorder(BorderFactory
0429: .createBevelBorder(BevelBorder.LOWERED));
0430: bottomPane.setTopComponent(nodeTreeScrollPane);
0431:
0432: // popup menu for creating and deleting nodes
0433: nodeRootMenu = new JPopupMenu();
0434: nodeNodeMenu = new JPopupMenu();
0435: nodeAgentMenu = new JPopupMenu();
0436:
0437: JMenuItem newNodeMenuItem = new JMenuItem(NEW_NODE_MENU_ITEM);
0438: newNodeMenuItem.addActionListener(new ActionListener() {
0439: public void actionPerformed(ActionEvent e) {
0440: createUnassignedNode();
0441: }
0442: });
0443: nodeRootMenu.add(newNodeMenuItem);
0444: nodeRootMenu.add(globalCmdLineAction);
0445: JMenuItem describeNodeMenuItem = new JMenuItem(
0446: DESCRIBE_MENU_ITEM);
0447: describeNodeMenuItem.addActionListener(new ActionListener() {
0448: public void actionPerformed(ActionEvent e) {
0449: setNodeDescription(nodeTree);
0450: }
0451: });
0452: cmdLineNodeMenuItem = new JMenuItem(NODE_COMMAND_LINE_MENU_ITEM);
0453: cmdLineNodeMenuItem.addActionListener(new ActionListener() {
0454: public void actionPerformed(ActionEvent e) {
0455: setNodeCommandLine((DefaultMutableTreeNode) nodeTree
0456: .getLastSelectedPathComponent());
0457: }
0458: });
0459: cmdLineNodeMenuItem.setEnabled(true);
0460: JMenuItem globalCmdLineMenuItem = new JMenuItem(
0461: GLOBAL_COMMAND_LINE_MENU_ITEM);
0462: globalCmdLineMenuItem.addActionListener(new ActionListener() {
0463: public void actionPerformed(ActionEvent e) {
0464: setGlobalCommandLine();
0465: }
0466: });
0467: globalCmdLineMenuItem.setEnabled(true);
0468: JMenuItem deleteNodeMenuItem = new JMenuItem(DELETE_MENU_ITEM);
0469: deleteNodeMenuItem.addActionListener(new ActionListener() {
0470: public void actionPerformed(ActionEvent e) {
0471: deleteNodesFromTree(nodeTree);
0472: }
0473: });
0474:
0475: showComponentsNodeMenuItem = new JMenuItem(
0476: SHOW_COMPONENTS_MENU_ITEM);
0477: showComponentsNodeMenuItem
0478: .addActionListener(new ActionListener() {
0479: public void actionPerformed(ActionEvent e) {
0480: showAgentComponents(nodeTree);
0481: }
0482: });
0483:
0484: showComponentsNodeAMenuItem = new JMenuItem(
0485: SHOW_COMPONENTS_MENU_ITEM);
0486: showComponentsNodeAMenuItem
0487: .addActionListener(new ActionListener() {
0488: public void actionPerformed(ActionEvent e) {
0489: showAgentComponents(nodeTree);
0490: }
0491: });
0492:
0493: nodeNodeMenu.add(describeNodeMenuItem);
0494: nodeNodeMenu.add(cmdLineNodeMenuItem);
0495: nodeNodeMenu.add(globalCmdLineAction);
0496: nodeNodeMenu.add(deleteNodeMenuItem);
0497: nodeNodeMenu.add(showComponentsNodeMenuItem);
0498:
0499: nodeAgentMenu.add(showComponentsNodeAMenuItem);
0500:
0501: Action viewArgumentsNodeAction = new AbstractAction(
0502: DISPLAY_ARGS_ACTION) {
0503: public void actionPerformed(ActionEvent e) {
0504: displayArguments(viewOnlyNodeMenu.getInvoker());
0505: }
0506: };
0507: viewOnlyNodeMenu.add(viewArgumentsNodeAction);
0508:
0509: // Can't add this directly, must be a copy
0510: // viewOnlyNodeMenu.add(showComponentsNodeMenuItem);
0511:
0512: // attach a mouse listener to the node tree to display menu
0513: MouseListener nodeTreeMouseListener = new MouseAdapter() {
0514: public void mouseClicked(MouseEvent e) {
0515: if (e.isPopupTrigger())
0516: displayNodeTreeMenu(e);
0517: }
0518:
0519: public void mousePressed(MouseEvent e) {
0520: if (e.isPopupTrigger())
0521: displayNodeTreeMenu(e);
0522: }
0523:
0524: public void mouseReleased(MouseEvent e) {
0525: if (e.isPopupTrigger())
0526: displayNodeTreeMenu(e);
0527: }
0528: };
0529: nodeTree.addMouseListener(nodeTreeMouseListener);
0530:
0531: // tree of unassigned agents
0532: cto = new ConsoleTreeObject("Agents (unassigned)",
0533: AgentComponent.class.getName());
0534: root = new DefaultMutableTreeNode(cto, true);
0535: model = createModel(experiment, root, true);
0536: agentTree = new ConsoleDNDTree(model);
0537:
0538: // attach a mouse listener to the agent tree to display menu
0539: MouseListener agentTreeMouseListener = new MouseAdapter() {
0540: public void mouseClicked(MouseEvent e) {
0541: if (e.isPopupTrigger())
0542: displayAgentTreeMenu(e);
0543: }
0544:
0545: public void mousePressed(MouseEvent e) {
0546: if (e.isPopupTrigger())
0547: displayAgentTreeMenu(e);
0548: }
0549:
0550: public void mouseReleased(MouseEvent e) {
0551: if (e.isPopupTrigger())
0552: displayAgentTreeMenu(e);
0553: }
0554: };
0555: agentTree.addMouseListener(agentTreeMouseListener);
0556:
0557: showComponentsAgentMenuItem = new JMenuItem(
0558: SHOW_COMPONENTS_MENU_ITEM);
0559: showComponentsAgentMenuItem
0560: .addActionListener(new ActionListener() {
0561: public void actionPerformed(ActionEvent e) {
0562: showAgentComponents(agentTree);
0563: }
0564: });
0565:
0566: agentAgentMenu = new JPopupMenu();
0567: agentAgentMenu.add(showComponentsAgentMenuItem);
0568:
0569: // cell editor returns false; can't edit agent names or root name
0570: DefaultCellEditor agentEditor = new DefaultCellEditor(
0571: new JTextField()) {
0572: public boolean isCellEditable(EventObject e) {
0573: return false;
0574: }
0575: };
0576: agentTree.setCellEditor(agentEditor);
0577: agentTree.setExpandsSelectedPaths(true);
0578: JScrollPane agentTreeScrollPane = new JScrollPane(agentTree);
0579: agentTreeScrollPane.setBorder(BorderFactory
0580: .createBevelBorder(BevelBorder.LOWERED));
0581: bottomPane.setBottomComponent(agentTreeScrollPane);
0582: hostPane.setBottomComponent(bottomPane);
0583: setLayout(new BorderLayout());
0584: add(hostPane, BorderLayout.CENTER);
0585: hostPane.setDividerLocation(220);
0586: bottomPane.setDividerLocation(220);
0587: }
0588:
0589: /**
0590: * Ensure that display is up-to-date before showing it.
0591: */
0592:
0593: public void setVisible(boolean visible) {
0594: if (visible)
0595: update();
0596: super .setVisible(visible);
0597: }
0598:
0599: /**
0600: * Set display to show a new experiment.
0601: */
0602:
0603: public void reinit(Experiment newExperiment) {
0604: experiment = newExperiment;
0605: // if this pane is being displayed, then bring it up-to-date
0606: if (isShowing())
0607: update();
0608: }
0609:
0610: /**
0611: * Bring the display up-to-date by re-reading host/node/agent information
0612: * from the experiment.
0613: */
0614: public void update() {
0615: societyComponent = experiment.getSocietyComponent(); // may return null
0616: hostTree.getModel().removeTreeModelListener(this );
0617: nodeTree.getModel().removeTreeModelListener(this );
0618: agentTree.getModel().removeTreeModelListener(this );
0619: removeAllChildren(hostTree);
0620: removeAllChildren(nodeTree);
0621: removeAllChildren(agentTree);
0622: DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
0623: if (!isEditable) {
0624: renderer.setTextNonSelectionColor(Color.gray);
0625: renderer.setTextSelectionColor(Color.gray);
0626: }
0627: hostTree.setCellRenderer(renderer);
0628: nodeTree.setCellRenderer(renderer);
0629: agentTree.setCellRenderer(renderer);
0630: hostTree.setEditable(isEditable);
0631: nodeTree.setEditable(isEditable);
0632: agentTree.setEditable(isEditable);
0633:
0634: // This next set of operations is time-consuming. Lots of looping
0635: // over all Hosts, Nodes, Agents, and string compares and things.
0636: // Slow!
0637:
0638: if (log.isDebugEnabled())
0639: log.debug("update: About to add Host, Nodes, Agents");
0640:
0641: // get hosts, agents and nodes from experiment
0642: addHostsFromExperiment();
0643: // create new host components for hosts named in config file
0644: addHostsFromFile();
0645: // add unassigned nodes to nodes tree
0646: addUnassignedNodesFromExperiment();
0647: // add unassigned agents to agents tree
0648: addUnassignedAgentsFromExperiment();
0649:
0650: if (log.isDebugEnabled())
0651: log.debug("update: Finished adding Hosts, Nodes, Agents");
0652:
0653: // fully expand trees
0654: expandTree(hostTree);
0655: expandTree(nodeTree);
0656: expandTree(agentTree);
0657: hostTree.getModel().addTreeModelListener(this );
0658: nodeTree.getModel().addTreeModelListener(this );
0659: agentTree.getModel().addTreeModelListener(this );
0660: }
0661:
0662: /**
0663: * Remove all children from a tree; called in update.
0664: */
0665: private void removeAllChildren(JTree tree) {
0666: DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
0667: DefaultMutableTreeNode root = (DefaultMutableTreeNode) model
0668: .getRoot();
0669: root.removeAllChildren();
0670: model.nodeStructureChanged(root);
0671: }
0672:
0673: /**
0674: * Fully expand the tree; called in initialization
0675: * so that the initial view of the tree is fully expanded.
0676: */
0677: private void expandTree(JTree tree) {
0678: Enumeration nodes = ((DefaultMutableTreeNode) tree.getModel()
0679: .getRoot()).depthFirstEnumeration();
0680: while (nodes.hasMoreElements()) {
0681: DefaultMutableTreeNode node = (DefaultMutableTreeNode) nodes
0682: .nextElement();
0683: tree.expandPath(new TreePath(node.getPath()));
0684: }
0685: }
0686:
0687: /**
0688: * Add hosts and their nodes and agents from an experiment.
0689: */
0690: private void addHostsFromExperiment() {
0691: DefaultMutableTreeNode root = (DefaultMutableTreeNode) hostTree
0692: .getModel().getRoot();
0693: DefaultTreeModel model = (DefaultTreeModel) hostTree.getModel();
0694: HostComponent[] hosts = experiment.getHostComponents();
0695: for (int i = 0; i < hosts.length; i++) {
0696: HostComponent hostComponent = hosts[i];
0697: ConsoleTreeObject cto = new ConsoleTreeObject(hostComponent);
0698: DefaultMutableTreeNode hostNode = new DefaultMutableTreeNode(
0699: cto, true);
0700: model.insertNodeInto(hostNode, root, root.getChildCount());
0701: NodeComponent[] nodes = hostComponent.getNodes();
0702: for (int j = 0; j < nodes.length; j++) {
0703: NodeComponent nodeComponent = nodes[j];
0704: cto = new ConsoleTreeObject(nodeComponent);
0705: DefaultMutableTreeNode nodeTreeNode = new DefaultMutableTreeNode(
0706: cto, true);
0707: model.insertNodeInto(nodeTreeNode, hostNode, hostNode
0708: .getChildCount());
0709: nodeToHost.put(nodeComponent, hostComponent);
0710: AgentComponent[] agents = nodeComponent.getAgents();
0711: for (int k = 0; k < agents.length; k++) {
0712: AgentComponent agentComponent = agents[k];
0713: cto = new ConsoleTreeObject(agentComponent);
0714: DefaultMutableTreeNode agentNode = new DefaultMutableTreeNode(
0715: cto, false);
0716: model.insertNodeInto(agentNode, nodeTreeNode,
0717: nodeTreeNode.getChildCount());
0718: agentToNode.put(agentComponent, nodeComponent);
0719: }
0720: }
0721: }
0722: }
0723:
0724: /**
0725: * Create host components for hosts read from a text file.
0726: */
0727: private void addHostsFromFile() {
0728: // this may silently fail, but that's ok, cause the file is optional
0729: String pathName = Util.getPath("hosts.txt");
0730: if (pathName == null)
0731: return;
0732:
0733: java.util.List hosts = new ArrayList();
0734: RandomAccessFile hostFile = null;
0735: // read hosts, one per line
0736: try {
0737: hostFile = new RandomAccessFile(pathName, "r");
0738: while (true) {
0739: String ihost = hostFile.readLine(); // get their name
0740: if (ihost == null) {
0741: break;
0742: }
0743: ihost = ihost.trim();
0744: // Do other checking for reasonable host names here...
0745: // Maybe skip "localhost" here?
0746: if (ihost != null && !ihost.equals("")
0747: && !hosts.contains(ihost))
0748: hosts.add(ihost);
0749: }
0750: hostFile.close();
0751: } catch (IOException e) {
0752: if (log.isErrorEnabled()) {
0753: log.error("Error during read/open from file: "
0754: + pathName + " ", e);
0755: }
0756: return;
0757: }
0758: DefaultMutableTreeNode root = (DefaultMutableTreeNode) hostTree
0759: .getModel().getRoot();
0760: DefaultTreeModel model = (DefaultTreeModel) hostTree.getModel();
0761: DefaultMutableTreeNode hostNode = null;
0762: HostComponent[] hostsInExperiment = experiment
0763: .getHostComponents();
0764: Vector hostNames = new Vector(hostsInExperiment.length);
0765: for (int i = 0; i < hostsInExperiment.length; i++)
0766: hostNames.add(hostsInExperiment[i].toString());
0767: for (int i = 0; i < hosts.size(); i++) {
0768: if (hostNames.contains((String) hosts.get(i)))
0769: continue; // this host already exists in the experiment
0770: HostComponent hostComponent = experiment
0771: .addHost((String) hosts.get(i));
0772: ConsoleTreeObject cto = new ConsoleTreeObject(hostComponent);
0773: hostNode = new DefaultMutableTreeNode(cto, true);
0774: model.insertNodeInto(hostNode, root, root.getChildCount());
0775: }
0776: if (hostNode != null)
0777: hostTree.scrollPathToVisible(new TreePath(hostNode
0778: .getPath()));
0779: }
0780:
0781: /**
0782: * Add unassigned nodes from experiment to unassigned nodes tree.
0783: */
0784: private void addUnassignedNodesFromExperiment() {
0785: Set unassignedNodes;
0786: unassignedNodes = new TreeSet(dbBaseComponentComparator);
0787: // This _will_ do a Node/Agent reconciliation
0788: NodeComponent[] nodes = experiment.getNodeComponents();
0789: // so this does not need to
0790: HostComponent[] hosts = experiment
0791: .getHostComponentsNoReconcile();
0792: unassignedNodes.addAll(Arrays.asList(nodes));
0793: for (int i = 0; i < hosts.length; i++)
0794: unassignedNodes.removeAll(Arrays
0795: .asList(hosts[i].getNodes()));
0796: DefaultMutableTreeNode root = (DefaultMutableTreeNode) nodeTree
0797: .getModel().getRoot();
0798: DefaultTreeModel model = (DefaultTreeModel) nodeTree.getModel();
0799: Iterator iter = unassignedNodes.iterator();
0800: while (iter.hasNext()) {
0801: NodeComponent nodeComponent = (NodeComponent) iter.next();
0802: ConsoleTreeObject cto = new ConsoleTreeObject(nodeComponent);
0803: DefaultMutableTreeNode newNodeTreeNode = new DefaultMutableTreeNode(
0804: cto, true);
0805: model.insertNodeInto(newNodeTreeNode, root, root
0806: .getChildCount());
0807: AgentComponent[] agents = nodeComponent.getAgents();
0808: for (int j = 0; j < agents.length; j++) {
0809: AgentComponent agentComponent = agents[j];
0810: cto = new ConsoleTreeObject(agentComponent);
0811: DefaultMutableTreeNode newAgentNode = new DefaultMutableTreeNode(
0812: cto, false);
0813: model.insertNodeInto(newAgentNode, newNodeTreeNode,
0814: newNodeTreeNode.getChildCount());
0815: agentToNode.put(agentComponent, nodeComponent);
0816: }
0817: }
0818: }
0819:
0820: // In general, agent names from built in societies are complex
0821: // and those from the db are short
0822: // The complex ones should be compared in full,
0823: // while the DB ones should only be compared in short versions
0824: // And Nodes are also short only
0825: // Failing to compare only the short names when using DB societies
0826: // results in agents erroneously appearing 2x, once unassigned
0827:
0828: private static Comparator dbBaseComponentComparator = new Comparator() {
0829: public int compare(Object o1, Object o2) {
0830: BaseComponent c1 = (BaseComponent) o1;
0831: BaseComponent c2 = (BaseComponent) o2;
0832: // System.out.println("dbBaseComponentComparator:" +
0833: // c1.getShortName() + ";" +
0834: // c2.getShortName() + ";" +
0835: // c1.getShortName().compareTo(c2.getShortName()));
0836: return c1.getShortName().compareTo(c2.getShortName());
0837: }
0838: };
0839:
0840: // private static Comparator builtInBaseComponentComparator = new Comparator() {
0841: // public int compare(Object o1, Object o2) {
0842: // BaseComponent c1 = (BaseComponent) o1;
0843: // BaseComponent c2 = (BaseComponent) o2;
0844:
0845: // if (c1 instanceof NodeComponent || c2 instanceof NodeComponent)
0846: // return c1.getShortName().compareTo(c2.getShortName());
0847: // else // agent name comparison
0848: // return c1.getFullName().compareTo(c2.getFullName());
0849: // }
0850: // };
0851:
0852: /**
0853: * Add unassigned agents to unassigned agents tree.
0854: */
0855: private void addUnassignedAgentsFromExperiment() {
0856: // // get all agents in the experiment and put them in unassigned list
0857: // AgentComponent[] agents = experiment.getAgents();
0858: // ArrayList unassignedAgentNames = new ArrayList();
0859: // ArrayList unassignedAgents = new ArrayList();
0860: // unassignedAgents.addAll(Arrays.asList(agents));
0861: // for (int i = 0; i < agents.length; i++) {
0862: // System.out.println("Adding:" + agents[i].getShortName() + ".");
0863: // unassignedAgentNames.add(agents[i].getShortName());
0864: // }
0865: // NodeComponent[] nodes = experiment.getNodes();
0866: // // get agents in each node and take them out of the unassigned list
0867: // for (int i = 0; i < nodes.length; i++) {
0868: // AgentComponent[] agentsInNodes = nodes[i].getAgents();
0869: // for (int j = 0; j < agentsInNodes.length; j++) {
0870: // BaseComponent agentInNode = agentsInNodes[j];
0871: // System.out.println("Checking:" + agentInNode.getShortName() + ".");
0872: // int index = unassignedAgentNames.indexOf(agentInNode.getShortName());
0873: // if (index != -1) {
0874: // System.out.println("Removing");
0875: // unassignedAgentNames.remove(index);
0876: // unassignedAgents.remove(index);
0877: // }
0878: // }
0879: // }
0880: Set unassignedAgents;
0881: unassignedAgents = new TreeSet(dbBaseComponentComparator);
0882: AgentComponent[] agents = experiment.getAgents();
0883: // This will do a Node/Agent comparison
0884: NodeComponent[] nodes = experiment.getNodeComponents();
0885: // this must then do a lot of agent name comparisons
0886: unassignedAgents.addAll(Arrays.asList(agents));
0887: for (int i = 0; i < nodes.length; i++) {
0888: // System.out.println("Remove all in: " + nodes[i].getShortName() +
0889: // nodes[i].getAgents().length);
0890: List assignedAgents = Arrays.asList(nodes[i].getAgents());
0891: // this too does a lot of agent name comparisons
0892: unassignedAgents.removeAll(assignedAgents);
0893: }
0894: DefaultTreeModel model = (DefaultTreeModel) agentTree
0895: .getModel();
0896: DefaultMutableTreeNode root = (DefaultMutableTreeNode) model
0897: .getRoot();
0898: Iterator iter = unassignedAgents.iterator();
0899: while (iter.hasNext()) {
0900: AgentComponent agentComponent = (AgentComponent) iter
0901: .next();
0902: ConsoleTreeObject cto = new ConsoleTreeObject(
0903: agentComponent);
0904: DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(
0905: cto, false);
0906: model.insertNodeInto(newNode, root, root.getChildCount());
0907: }
0908: }
0909:
0910: /**
0911: * Display the popup menu for the host tree.
0912: * Displays different menus if pointing to root, host or node.
0913: * If pointing to different types of nodes, does not display a menu.
0914: */
0915: private void displayHostTreeMenu(MouseEvent e) {
0916: // the path to the node the mouse is pointing at
0917: TreePath selPath = hostTree.getPathForLocation(e.getX(), e
0918: .getY());
0919: if (selPath == null)
0920: return;
0921: // if the mouse is pointing at a selected node
0922: // and all selected nodes are of the same type, then act on all of them
0923: TreePath[] selectedPaths = hostTree.getSelectionPaths();
0924: if (hostTree.isPathSelected(selPath)
0925: && selectedPaths.length > 1) {
0926: boolean haveHosts = false;
0927: boolean haveNodes = false;
0928: for (int i = 0; i < selectedPaths.length; i++) {
0929: DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) selectedPaths[i]
0930: .getLastPathComponent();
0931: ConsoleTreeObject selected = (ConsoleTreeObject) selNode
0932: .getUserObject();
0933: if (selected.isHost()) {
0934: if (!haveHosts && !haveNodes)
0935: haveHosts = true;
0936: else if (haveNodes) {
0937: haveNodes = false;
0938: break;
0939: }
0940: } else if (selected.isNode()) {
0941: if (!haveHosts && !haveNodes)
0942: haveNodes = true;
0943: else if (haveHosts) {
0944: haveHosts = false;
0945: break;
0946: }
0947: } else {
0948: haveHosts = false;
0949: haveNodes = false;
0950: break;
0951: }
0952: }
0953: if (haveHosts) {
0954: newNodeInHostMenuItem.setEnabled(false);
0955: showComponentsHostMenuItem.setEnabled(false);
0956: showComponentsHostAMenuItem.setEnabled(false);
0957: if (hostTree.isEditable())
0958: hostHostMenu.show(hostTree, e.getX(), e.getY());
0959: else
0960: viewOnlyHostMenu.show(hostTree, e.getX(), e.getY());
0961: return;
0962: } else if (haveNodes) {
0963: cmdLineNodeInHostMenuItem.setEnabled(false);
0964: showComponentsHostMenuItem.setEnabled(false);
0965: showComponentsHostAMenuItem.setEnabled(false);
0966: if (hostTree.isEditable())
0967: hostNodeMenu.show(hostTree, e.getX(), e.getY());
0968: else
0969: viewOnlyHostMenu.show(hostTree, e.getX(), e.getY());
0970: return;
0971: }
0972: } else {
0973: // else set the selected node to be the node the mouse is pointing at
0974: hostTree.setSelectionPath(selPath);
0975: DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) selPath
0976: .getLastPathComponent();
0977: ConsoleTreeObject selected = (ConsoleTreeObject) selNode
0978: .getUserObject();
0979: // display popup menu
0980: if (selected.isRoot()) {
0981: if (hostTree.isEditable())
0982: hostRootMenu.show(hostTree, e.getX(), e.getY());
0983: else
0984: viewOnlyHostMenu.show(hostTree, e.getX(), e.getY());
0985: } else if (selected.isHost()) {
0986: newNodeInHostMenuItem.setEnabled(true);
0987: if (hostTree.isEditable())
0988: hostHostMenu.show(hostTree, e.getX(), e.getY());
0989: else
0990: viewOnlyHostMenu.show(hostTree, e.getX(), e.getY());
0991: } else if (selected.isNode()) {
0992: // Allow showAgentComponents here!
0993: cmdLineNodeInHostMenuItem.setEnabled(true);
0994: showComponentsHostMenuItem.setEnabled(true);
0995: showComponentsHostAMenuItem.setEnabled(false);
0996: if (hostTree.isEditable())
0997: hostNodeMenu.show(hostTree, e.getX(), e.getY());
0998: else {
0999: viewOnlyHostMenu.show(hostTree, e.getX(), e.getY());
1000: }
1001: } else if (selected.isAgent()) {
1002: showComponentsHostMenuItem.setEnabled(false);
1003: showComponentsHostAMenuItem.setEnabled(true);
1004: hostAgentMenu.show(hostTree, e.getX(), e.getY());
1005: }
1006: }
1007: }
1008:
1009: /**
1010: * Display global command line arguments.
1011: * If a node is selected, also display command line arguments for that node.
1012: */
1013: private void displayArguments(Component c) {
1014: if (!(c instanceof JTree))
1015: return;
1016: NodeArgumentDialog dialog;
1017: DefaultMutableTreeNode[] selectedNodes = getSelectedItemsInTree(
1018: (JTree) c, NodeComponent.class);
1019: if (selectedNodes != null && selectedNodes.length == 1) {
1020: ConsoleTreeObject cto = (ConsoleTreeObject) (selectedNodes[0])
1021: .getUserObject();
1022: NodeComponent nodeComponent = (NodeComponent) cto
1023: .getComponent();
1024: dialog = new NodeArgumentDialog("Node "
1025: + nodeComponent.getShortName() + " Command Line",
1026: nodeComponent.getArguments(), true, false);
1027: } else
1028: dialog = new NodeArgumentDialog("Global Command Line",
1029: experiment.getDefaultNodeArguments(), false, false);
1030: dialog.setVisible(true);
1031: }
1032:
1033: /**
1034: * Add new host to host tree.
1035: */
1036: public void createHost() {
1037: String hostName = null;
1038: while (true) {
1039: hostName = JOptionPane.showInputDialog("New host name: ");
1040: // FIXME: Forbid localhost here?
1041: if (hostName == null || hostName.trim().length() == 0)
1042: return;
1043: hostName = hostName.trim();
1044: HostComponent[] hc = experiment.getHostComponents();
1045: boolean isUnique = true;
1046: for (int i = 0; i < hc.length; i++)
1047: if (hostName.equalsIgnoreCase(hc[i].getShortName())) {
1048: isUnique = false;
1049: break;
1050: }
1051: if (isUnique)
1052: break;
1053: int ok = JOptionPane.showConfirmDialog(this ,
1054: "Use an unique name", "Host Name Not Unique",
1055: JOptionPane.OK_CANCEL_OPTION,
1056: JOptionPane.ERROR_MESSAGE);
1057: if (ok != JOptionPane.OK_OPTION)
1058: return;
1059: }
1060: DefaultTreeModel model = (DefaultTreeModel) hostTree.getModel();
1061: DefaultMutableTreeNode hostTreeRoot = (DefaultMutableTreeNode) model
1062: .getRoot();
1063: HostComponent hostComponent = experiment.addHost(hostName);
1064: ConsoleTreeObject cto = new ConsoleTreeObject(hostComponent);
1065: DefaultMutableTreeNode hostNode = new DefaultMutableTreeNode(
1066: cto);
1067: model.insertNodeInto(hostNode, hostTreeRoot, hostTreeRoot
1068: .getChildCount());
1069: hostTree.scrollPathToVisible(new TreePath(hostNode.getPath()));
1070: }
1071:
1072: private boolean isHostNameUnique(String name) {
1073: HostComponent[] hc = experiment.getHostComponents();
1074: for (int i = 0; i < hc.length; i++)
1075: if (name.equalsIgnoreCase(hc[i].getShortName()))
1076: return false;
1077: return true;
1078: }
1079:
1080: /**
1081: * Display the popup menus for the node tree, either the node menu
1082: * or the root menu.
1083: */
1084: private void displayNodeTreeMenu(MouseEvent e) {
1085: // the path to the node the mouse is pointing at
1086: TreePath selPath = nodeTree.getPathForLocation(e.getX(), e
1087: .getY());
1088: if (selPath == null)
1089: return;
1090: // if the mouse is pointing at a selected node
1091: // and all selected nodes are of the same type, then act on all of them
1092: TreePath[] selectedPaths = nodeTree.getSelectionPaths();
1093: if (nodeTree.isPathSelected(selPath)
1094: && selectedPaths.length > 1) {
1095: boolean haveNodes = false;
1096: for (int i = 0; i < selectedPaths.length; i++) {
1097: DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) selectedPaths[i]
1098: .getLastPathComponent();
1099: ConsoleTreeObject selected = (ConsoleTreeObject) selNode
1100: .getUserObject();
1101: if (selected.isNode())
1102: haveNodes = true;
1103: else {
1104: haveNodes = false;
1105: break;
1106: }
1107: }
1108: // handle multiple selected nodes
1109: // disable menu command to set individual node command line arguments
1110: if (haveNodes) {
1111: cmdLineNodeMenuItem.setEnabled(false);
1112: showComponentsNodeMenuItem.setEnabled(false);
1113: showComponentsNodeAMenuItem.setEnabled(false);
1114: if (nodeTree.isEditable())
1115: nodeNodeMenu.show(nodeTree, e.getX(), e.getY());
1116: else
1117: viewOnlyNodeMenu.show(nodeTree, e.getX(), e.getY());
1118: return;
1119: }
1120: } else {
1121: // set the selected node to be the node the mouse is pointing at
1122: nodeTree.setSelectionPath(selPath);
1123: DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) selPath
1124: .getLastPathComponent();
1125: ConsoleTreeObject selected = (ConsoleTreeObject) selNode
1126: .getUserObject();
1127: // display popup menu
1128: if (selected.isRoot()) {
1129: if (nodeTree.isEditable())
1130: nodeRootMenu.show(nodeTree, e.getX(), e.getY());
1131: else
1132: viewOnlyNodeMenu.show(nodeTree, e.getX(), e.getY());
1133: } else if (selected.isNode()) {
1134: // allow showAgentComponents here
1135: // Also, what if it's the Agent inside the Host?
1136: cmdLineNodeMenuItem.setEnabled(true);
1137: showComponentsNodeMenuItem.setEnabled(true);
1138: showComponentsNodeAMenuItem.setEnabled(false);
1139: if (nodeTree.isEditable())
1140: nodeNodeMenu.show(nodeTree, e.getX(), e.getY());
1141: else {
1142: viewOnlyNodeMenu.show(nodeTree, e.getX(), e.getY());
1143: }
1144: } else if (selected.isAgent()) {
1145: showComponentsNodeMenuItem.setEnabled(false);
1146: showComponentsNodeAMenuItem.setEnabled(true);
1147: nodeAgentMenu.show(nodeTree, e.getX(), e.getY());
1148: }
1149: }
1150: }
1151:
1152: /**
1153: * Display the popup menus for the aget tree, either the agentt menu
1154: * or none.
1155: */
1156: private void displayAgentTreeMenu(MouseEvent e) {
1157: // the path to the agent the mouse is pointing at
1158: TreePath selPath = agentTree.getPathForLocation(e.getX(), e
1159: .getY());
1160: if (selPath == null)
1161: return;
1162:
1163: // if the mouse is pointing at a selected node
1164: // and all selected nodes are of the same type, then act on all of them
1165: TreePath[] selectedPaths = agentTree.getSelectionPaths();
1166: if (agentTree.isPathSelected(selPath)
1167: && selectedPaths.length > 1) {
1168: // Don't allow multiple actions at once
1169: } else {
1170: // set the selected node to be the node the mouse is pointing at
1171: agentTree.setSelectionPath(selPath);
1172: DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) selPath
1173: .getLastPathComponent();
1174: ConsoleTreeObject selected = (ConsoleTreeObject) selNode
1175: .getUserObject();
1176: // display popup menu
1177: if (selected.isRoot()) {
1178: // no menu for the root node
1179: } else if (selected.isAgent()) {
1180: showComponentsAgentMenuItem.setEnabled(true);
1181: agentAgentMenu.show(agentTree, e.getX(), e.getY());
1182: }
1183: }
1184: }
1185:
1186: /**
1187: * Display agent components for the agent in the selected node.
1188: */
1189: private void showAgentComponents(JTree tree) {
1190: DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree
1191: .getSelectionPath().getLastPathComponent();
1192: ConsoleTreeObject cto = (ConsoleTreeObject) selectedNode
1193: .getUserObject();
1194: String agentName = cto.getName();
1195: JOptionPane.showMessageDialog(this , new AgentInfoPanel(
1196: experiment, agentName), "Information: " + agentName,
1197: JOptionPane.PLAIN_MESSAGE);
1198: }
1199:
1200: /**
1201: * Listener for adding new nodes to host tree.
1202: */
1203:
1204: public void createAssignedNode() {
1205: newNodeInTree(hostTree);
1206: // setRunButtonEnabled();
1207: }
1208:
1209: public void createUnassignedNode() {
1210: // FIXME: If nothing in nodeTree selected, select the root
1211: // That way can create an unassigned Node without
1212: // selecting anything
1213: newNodeInTree(nodeTree);
1214: }
1215:
1216: // create a new node component in either the host or nodes tree
1217: private void newNodeInTree(JTree tree) {
1218: TreePath path = tree.getSelectionPath();
1219: if (path == null) {
1220: if (log.isWarnEnabled()) {
1221: log
1222: .warn("HostConfigurationBuilder newNodeInTree called with null path; ignoring");
1223: }
1224: return;
1225: }
1226: DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) path
1227: .getLastPathComponent();
1228: String nodeName = null;
1229: while (true) {
1230: nodeName = JOptionPane.showInputDialog("New node name: ");
1231: if (nodeName == null || nodeName.trim().length() == 0)
1232: return;
1233: nodeName = nodeName.trim();
1234: // don't allow node names that are the same as node or agent names
1235: if (isNodeNameUnique(nodeName))
1236: break;
1237: int ok = JOptionPane.showConfirmDialog(this ,
1238: "Use an unique name", "Node Name Not Unique",
1239: JOptionPane.OK_CANCEL_OPTION,
1240: JOptionPane.ERROR_MESSAGE);
1241: if (ok != JOptionPane.OK_OPTION)
1242: return;
1243: }
1244: DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
1245: NodeComponent nodeComponent = experiment.addNode(nodeName);
1246: DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(
1247: new ConsoleTreeObject(nodeComponent));
1248: model.insertNodeInto(newNode, selectedNode, selectedNode
1249: .getChildCount());
1250: if (tree.equals(hostTree)) { // added node to host
1251: nodeToHost.put(nodeComponent, selectedNode.getUserObject());
1252: }
1253: tree.scrollPathToVisible(new TreePath(newNode.getPath()));
1254: }
1255:
1256: // check all trees and return false if there's a node or agent
1257: // with the same name
1258:
1259: private boolean isNodeNameUnique(String name) {
1260: if (isNodeNameUniqueInTree(hostTree, name)
1261: && isNodeNameUniqueInTree(nodeTree, name)
1262: && isNodeNameUniqueInTree(agentTree, name))
1263: return true;
1264: else
1265: return false;
1266: }
1267:
1268: private boolean isNodeNameUniqueInTree(JTree tree, String name) {
1269: DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
1270: DefaultMutableTreeNode root = (DefaultMutableTreeNode) model
1271: .getRoot();
1272: Enumeration nodes = root.breadthFirstEnumeration();
1273: while (nodes.hasMoreElements()) {
1274: DefaultMutableTreeNode node = (DefaultMutableTreeNode) nodes
1275: .nextElement();
1276: if (node.getUserObject() instanceof ConsoleTreeObject) {
1277: ConsoleTreeObject cto = (ConsoleTreeObject) node
1278: .getUserObject();
1279: if ((cto.isNode() || cto.isAgent())
1280: && cto.getName().equalsIgnoreCase(name))
1281: return false;
1282: }
1283: }
1284: return true;
1285: }
1286:
1287: public void deleteNode() {
1288: if (getSelectedNodesInHostTree() != null)
1289: deleteNodesFromTree(hostTree);
1290: if (getSelectedNodesInNodeTree() != null)
1291: deleteNodesFromTree(nodeTree);
1292: }
1293:
1294: /**
1295: * Listener for deleting nodes from host tree.
1296: */
1297: private void deleteNodesFromTree(JTree tree) {
1298: TreePath[] selectedPaths = tree.getSelectionPaths();
1299: for (int i = 0; i < selectedPaths.length; i++)
1300: deleteNodeFromTree(tree, selectedPaths[i]);
1301: // setRunButtonEnabled();
1302: }
1303:
1304: /**
1305: * Delete node component from either host or unassigned nodes tree.
1306: */
1307: private void deleteNodeFromTree(JTree tree, TreePath path) {
1308: DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) path
1309: .getLastPathComponent();
1310: ConsoleTreeObject nodeCTO = (ConsoleTreeObject) selectedNode
1311: .getUserObject();
1312: NodeComponent nodeComponent = (NodeComponent) nodeCTO
1313: .getComponent();
1314: BaseComponent parentComponent = getComponentFromTreeNode((DefaultMutableTreeNode) selectedNode
1315: .getParent());
1316: // get any agents that are descendants of the node being deleted
1317: // and return them to the unassigned agents tree
1318: DefaultTreeModel agentModel = (DefaultTreeModel) agentTree
1319: .getModel();
1320: DefaultMutableTreeNode root = (DefaultMutableTreeNode) agentModel
1321: .getRoot();
1322: int n = selectedNode.getChildCount();
1323: for (int i = 0; i < n; i++) {
1324: DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectedNode
1325: .getChildAt(0);
1326: ConsoleTreeObject cto = (ConsoleTreeObject) node
1327: .getUserObject();
1328: if (cto.isAgent()) {
1329: agentModel.insertNodeInto(node, root, root
1330: .getChildCount());
1331: agentTree.scrollPathToVisible(new TreePath(node
1332: .getPath()));
1333: agentToNode.remove(cto.getComponent());
1334: }
1335: }
1336: DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
1337: model.removeNodeFromParent(selectedNode);
1338: experiment.removeNode(nodeComponent);
1339: if (parentComponent instanceof HostComponent) {
1340: nodeToHost.remove(nodeComponent);
1341: ((HostComponent) parentComponent).removeNode(nodeComponent);
1342: }
1343: }
1344:
1345: /**
1346: * TreeModelListener interface.
1347: */
1348:
1349: /**
1350: * Called when user drags nodes on to the host or node tree;
1351: * dispatches to a tree specific method.
1352: */
1353: public void treeNodesInserted(TreeModelEvent e) {
1354: Object source = e.getSource();
1355: if (hostTree.getModel().equals(source)) {
1356: treeNodesInsertedInHostTree(e.getTreePath(), e
1357: .getChildren());
1358: } else if (nodeTree.getModel().equals(source)) {
1359: treeNodesInsertedInNodeTree(e.getTreePath(), e
1360: .getChildren());
1361: } else if (agentTree.getModel().equals(source)) {
1362: treeNodesInsertedInAgentTree(e.getChildren());
1363: }
1364: }
1365:
1366: /**
1367: * Called when user drags nodes on to the host tree (as opposed to
1368: * creating new nodes from the pop-up menu) or when user drags
1369: * agents on to a node in the host tree.
1370: * Notify host component if nodes are added to the host tree.
1371: * Notify node component if agents are added to a node in the host tree.
1372: * This also removes the component from its previous parent,
1373: * i.e. both the add and remove of the configurable component
1374: * are done on the "inserted" message and the "removed message" is ignored.
1375: */
1376: private void treeNodesInsertedInHostTree(TreePath path,
1377: Object[] children) {
1378: BaseComponent component = getComponentFromPath(path);
1379: if (component instanceof NodeComponent)
1380: addAgentsToNode((NodeComponent) component, children);
1381: else if (component instanceof HostComponent)
1382: addNodesToHost((HostComponent) component, children);
1383: }
1384:
1385: /**
1386: * Update agent component to node component mapping
1387: * when agents are dragged onto the Unassigned Nodes tree.
1388: * Remove node component from host component
1389: * when nodes are dragged onto the Unassigned Nodes tree.
1390: */
1391: private void treeNodesInsertedInNodeTree(TreePath path,
1392: Object[] children) {
1393: BaseComponent component = getComponentFromPath(path);
1394: if (component == null) { // add nodes to Unassigned Nodes tree
1395: for (int i = 0; i < children.length; i++) {
1396: NodeComponent nodeComponent = (NodeComponent) getComponentFromTreeNode((DefaultMutableTreeNode) children[i]);
1397: HostComponent previousParent = (HostComponent) nodeToHost
1398: .get(nodeComponent);
1399: if (previousParent != null)
1400: previousParent.removeNode(nodeComponent);
1401: nodeToHost.remove(nodeComponent);
1402: }
1403: } else
1404: addAgentsToNode((NodeComponent) component, children);
1405: }
1406:
1407: /**
1408: * Update agent component to node component mapping
1409: * when agents are dragged onto the Unassigned Agents tree.
1410: * Just remove agents from previous node component.
1411: */
1412: private void treeNodesInsertedInAgentTree(Object[] children) {
1413: for (int i = 0; i < children.length; i++) {
1414: AgentComponent agent = (AgentComponent) getComponentFromTreeNode((DefaultMutableTreeNode) children[i]);
1415: NodeComponent previousParent = (NodeComponent) agentToNode
1416: .get(agent);
1417: if (previousParent != null)
1418: previousParent.removeAgent(agent);
1419: agentToNode.remove(agent); // update mapping
1420: }
1421: }
1422:
1423: /**
1424: * Tell host component to add node components.
1425: * Remove node components from previous host component.
1426: */
1427: private void addNodesToHost(HostComponent hostComponent,
1428: Object[] newChildren) {
1429: for (int i = 0; i < newChildren.length; i++) {
1430: NodeComponent nodeComponent = (NodeComponent) getComponentFromTreeNode((DefaultMutableTreeNode) newChildren[i]);
1431: HostComponent previousParent = (HostComponent) nodeToHost
1432: .get(nodeComponent);
1433: // ignore moving nodes within the same host
1434: if (previousParent != null
1435: && previousParent.equals(hostComponent))
1436: return;
1437: hostComponent.addNode(nodeComponent);
1438: if (previousParent != null)
1439: previousParent.removeNode(nodeComponent);
1440: nodeToHost.put(nodeComponent, hostComponent);
1441: }
1442: }
1443:
1444: /**
1445: * Tell node component to add agent components.
1446: * Remove agent components from previous node component.
1447: */
1448: private void addAgentsToNode(NodeComponent nodeComponent,
1449: Object[] newChildren) {
1450: for (int i = 0; i < newChildren.length; i++) {
1451: AgentComponent agentComponent = (AgentComponent) getComponentFromTreeNode((DefaultMutableTreeNode) newChildren[i]);
1452: NodeComponent previousParent = (NodeComponent) agentToNode
1453: .get(agentComponent);
1454: // ignore moving agents within the same node
1455: if (previousParent != null
1456: && previousParent.equals(nodeComponent))
1457: return;
1458: nodeComponent.addAgent(agentComponent);
1459: if (previousParent != null)
1460: previousParent.removeAgent(agentComponent);
1461: agentToNode.put(agentComponent, nodeComponent); // update mapping
1462: }
1463: }
1464:
1465: /**
1466: * Called when user drags nodes off the host or node tree;
1467: * does nothing as updating the components is done at insertion.
1468: */
1469: public void treeNodesRemoved(TreeModelEvent e) {
1470: }
1471:
1472: /**
1473: * Called if user edits the name of a host or a node.
1474: * Does nothing because the host or node is updated
1475: * in the tree model when the user makes the change.
1476: */
1477: public void treeNodesChanged(TreeModelEvent e) {
1478: // Object source = e.getSource();
1479: // // handle user editing the name of a host in the host tree
1480: // if (hostTree.getModel().equals(source)) {
1481: // DefaultMutableTreeNode parent =
1482: // (DefaultMutableTreeNode)e.getTreePath().getLastPathComponent();
1483: // if (((ConsoleTreeObject)parent.getUserObject()).isRoot()) {
1484: // experimentBuilder.setModified(true);
1485: // return;
1486: // }
1487: // }
1488: // // handle user editing the name of a node in the host or node tree
1489: // if (hostTree.getModel().equals(source) ||
1490: // nodeTree.getModel().equals(source)) {
1491: // Object[] children = e.getChildren();
1492: // if (children != null && children.length > 0) {
1493: // DefaultMutableTreeNode firstChild =
1494: // (DefaultMutableTreeNode)children[0];
1495: // ConsoleTreeObject changedNode =
1496: // (ConsoleTreeObject)firstChild.getUserObject();
1497: // if (changedNode.isNode()) {
1498: // ((ExperimentNode)changedNode.getComponent()).rename(changedNode.getName());
1499: // experimentBuilder.setModified(true);
1500: // return;
1501: // }
1502: // }
1503: // }
1504: }
1505:
1506: /**
1507: * TreeModelListener interface -- unused.
1508: */
1509: public void treeStructureChanged(TreeModelEvent e) {
1510: }
1511:
1512: /**
1513: * Listener for deleting items from host tree.
1514: * Called when user selects "Delete" from popup menu.
1515: * This just takes care of the tree; the treeNodesRemoved method
1516: * updates the Society and Node components.
1517: */
1518: public void deleteHost() {
1519: TreePath[] selectedPaths = hostTree.getSelectionPaths();
1520: for (int i = 0; i < selectedPaths.length; i++) {
1521: DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) selectedPaths[i]
1522: .getLastPathComponent();
1523: ConsoleTreeObject hostCTO = (ConsoleTreeObject) selectedNode
1524: .getUserObject();
1525: // get any nodes that are descendants of the host being deleted
1526: // and return them to the unassigned nodes tree
1527: DefaultTreeModel nodeModel = (DefaultTreeModel) nodeTree
1528: .getModel();
1529: DefaultMutableTreeNode root = (DefaultMutableTreeNode) nodeModel
1530: .getRoot();
1531: int n = selectedNode.getChildCount();
1532: for (int j = 0; j < n; j++) {
1533: DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectedNode
1534: .getChildAt(0);
1535: ConsoleTreeObject cto = (ConsoleTreeObject) node
1536: .getUserObject();
1537: if (cto.isNode()) {
1538: nodeModel.insertNodeInto(node, root, root
1539: .getChildCount());
1540: nodeTree.scrollPathToVisible(new TreePath(node
1541: .getPath()));
1542: }
1543: }
1544: DefaultTreeModel hostModel = (DefaultTreeModel) hostTree
1545: .getModel();
1546: hostModel.removeNodeFromParent(selectedNode);
1547: experiment.removeHost((HostComponent) hostCTO
1548: .getComponent());
1549: // setRunButtonEnabled();
1550: }
1551: }
1552:
1553: /**
1554: * Helper method to get value of property of selected node in specified tree.
1555: */
1556: private String getPropertyOfNode(JTree tree, String name) {
1557: DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree
1558: .getSelectionPath().getLastPathComponent();
1559: ConsoleTreeObject cto = (ConsoleTreeObject) selectedNode
1560: .getUserObject();
1561: BaseComponent component = cto.getComponent();
1562: Property prop = component.getProperty(new ComponentName(
1563: component, name));
1564: if (prop == null)
1565: return null;
1566: return (String) prop.getValue();
1567: }
1568:
1569: /**
1570: * Helper method to set value of property of selected nodes
1571: * in specified tree.
1572: */
1573: private void setPropertyOfNode(JTree tree, String name, String value) {
1574: TreePath[] selectedPaths = tree.getSelectionPaths();
1575: for (int i = 0; i < selectedPaths.length; i++) {
1576: DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) selectedPaths[i]
1577: .getLastPathComponent();
1578: ConsoleTreeObject cto = (ConsoleTreeObject) selectedNode
1579: .getUserObject();
1580: BaseComponent component = cto.getComponent();
1581: component.addProperty(name, value);
1582: }
1583: }
1584:
1585: public void setHostDescription() {
1586: String description = getPropertyOfNode(hostTree, "Description");
1587: String s = (String) JOptionPane.showInputDialog(this ,
1588: "Enter Host Description", "Host Description",
1589: JOptionPane.QUESTION_MESSAGE, null, null, description);
1590: if (s != null && s.trim().length() != 0)
1591: setPropertyOfNode(hostTree, "Description", s.trim());
1592: }
1593:
1594: public void setHostType() {
1595: String machineType = getPropertyOfNode(hostTree, "MachineType");
1596: String[] machineTypes = { "Linux", "Solaris", "Windows" };
1597: String s = (String) JOptionPane.showInputDialog(this ,
1598: "Enter Host Machine Type", "Host Machine Type",
1599: JOptionPane.QUESTION_MESSAGE, null, machineTypes,
1600: machineType);
1601: if (s != null && s.trim().length() != 0)
1602: setPropertyOfNode(hostTree, "MachineType", s.trim());
1603: }
1604:
1605: public void setHostLocation() {
1606: String location = getPropertyOfNode(hostTree, "Location");
1607: String s = (String) JOptionPane.showInputDialog(this ,
1608: "Enter Host Location", "Host Location",
1609: JOptionPane.QUESTION_MESSAGE, null, null, location);
1610: if (s != null && s.trim().length() != 0)
1611: setPropertyOfNode(hostTree, "Location", s.trim());
1612: }
1613:
1614: /**
1615: * Get description of nodes from user and set in all nodes
1616: * selected in the host or node trees.
1617: */
1618: public void setNodeDescription() {
1619: boolean askedUser = false;
1620: String description = "";
1621: if (getSelectedNodesInHostTree() != null) {
1622: description = getPropertyOfNode(hostTree, "Description");
1623: description = (String) JOptionPane.showInputDialog(this ,
1624: "Enter Node Description", "Node Description",
1625: JOptionPane.QUESTION_MESSAGE, null, null,
1626: description);
1627: askedUser = true;
1628: if (description != null && description.trim().length() != 0)
1629: setPropertyOfNode(hostTree, "Description", description
1630: .trim());
1631: }
1632: if (getSelectedNodesInNodeTree() != null) {
1633: if (!askedUser) {
1634: description = getPropertyOfNode(nodeTree, "Description");
1635: description = (String) JOptionPane.showInputDialog(
1636: this , "Enter Node Description",
1637: "Node Description",
1638: JOptionPane.QUESTION_MESSAGE, null, null,
1639: description);
1640: }
1641: if (description != null && description.trim().length() != 0)
1642: setPropertyOfNode(nodeTree, "Description", description
1643: .trim());
1644: }
1645: }
1646:
1647: /**
1648: * Pop-up input dialog to get node description from user.
1649: * Called with the tree from which this menu item was invoked.
1650: */
1651: private void setNodeDescription(JTree tree) {
1652: String description = getPropertyOfNode(tree, "Description");
1653: String s = (String) JOptionPane.showInputDialog(this ,
1654: "Enter Node Description", "Node Description",
1655: JOptionPane.QUESTION_MESSAGE, null, null, description);
1656: if (s != null && s.trim().length() != 0)
1657: setPropertyOfNode(tree, "Description", s.trim());
1658: }
1659:
1660: /**
1661: * Pop-up input dialog to get node command line arguments from user.
1662: * Called with the tree from which this menu item was invoked.
1663: */
1664: public void setNodeCommandLine() {
1665: DefaultMutableTreeNode[] nodes = getSelectedNodesInHostTree();
1666: if (nodes != null) {
1667: setNodeCommandLine(nodes[0]);
1668: return;
1669: }
1670: nodes = getSelectedNodesInNodeTree();
1671: if (nodes != null)
1672: setNodeCommandLine(nodes[0]);
1673: }
1674:
1675: private void setNodeCommandLine(DefaultMutableTreeNode selectedNode) {
1676: experiment.updateNameServerHostName(); // Be sure this is up-do-date
1677: ConsoleTreeObject cto = (ConsoleTreeObject) selectedNode
1678: .getUserObject();
1679: NodeComponent nodeComponent = (NodeComponent) cto
1680: .getComponent();
1681: // node component level properties
1682: NodeArgumentDialog dialog = new NodeArgumentDialog("Node "
1683: + nodeComponent.getShortName() + " Command Line",
1684: nodeComponent.getArguments(), true, true);
1685: dialog.setVisible(true);
1686: if (dialog.getValue() != JOptionPane.OK_OPTION)
1687: return; // user cancelled
1688: dialog.updateProperties();
1689: }
1690:
1691: /**
1692: * Pop-up input dialog to get global command line arguments from user.
1693: */
1694: public void setGlobalCommandLine() {
1695: experiment.updateNameServerHostName(); // Be sure this is up-do-date
1696: NodeArgumentDialog dialog = new NodeArgumentDialog(
1697: "Global Command Line", experiment
1698: .getDefaultNodeArguments(), false, true);
1699: dialog.setVisible(true);
1700: if (dialog.getValue() != JOptionPane.OK_OPTION)
1701: return; // user cancelled
1702: dialog.updateProperties();
1703: }
1704:
1705: /**
1706: * Select a node in the host tree.
1707: */
1708: public void selectNodeInHostTree(String nodeName) {
1709: selectNodeInTree(hostTree, NodeComponent.class, nodeName);
1710: }
1711:
1712: private boolean selectNodeInTree(JTree tree, Class componentClass,
1713: String name) {
1714: DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
1715: DefaultMutableTreeNode root = (DefaultMutableTreeNode) model
1716: .getRoot();
1717: TreePath path = null;
1718: Enumeration nodes = root.breadthFirstEnumeration();
1719: while (nodes.hasMoreElements()) {
1720: DefaultMutableTreeNode node = (DefaultMutableTreeNode) nodes
1721: .nextElement();
1722: if (node.getUserObject() instanceof ConsoleTreeObject) {
1723: ConsoleTreeObject cto = (ConsoleTreeObject) node
1724: .getUserObject();
1725: if (cto.getComponent() != null
1726: && componentClass
1727: .isInstance(cto.getComponent())
1728: && cto.getName().equalsIgnoreCase(name)) {
1729: path = new TreePath(node.getPath());
1730: tree.setSelectionPath(path);
1731: tree.scrollPathToVisible(path);
1732: return true;
1733: }
1734: }
1735: }
1736: return false;
1737: }
1738:
1739: public void addHostTreeSelectionListener(
1740: TreeSelectionListener listener) {
1741: hostTree.addTreeSelectionListener(listener);
1742: }
1743:
1744: public void removeHostTreeSelectionListener(
1745: TreeSelectionListener listener) {
1746: hostTree.removeTreeSelectionListener(listener);
1747: }
1748:
1749: private DefaultTreeModel createModel(final Experiment experiment,
1750: DefaultMutableTreeNode node, boolean askKids) {
1751: return new DefaultTreeModel(node, askKids) {
1752: public void valueForPathChanged(TreePath path,
1753: Object newValue) {
1754: if (newValue == null || newValue.toString().equals(""))
1755: return;
1756: // Allow renaming hosts or Nodes only
1757: DefaultMutableTreeNode aNode = (DefaultMutableTreeNode) path
1758: .getLastPathComponent();
1759: ConsoleTreeObject cto = (ConsoleTreeObject) aNode
1760: .getUserObject();
1761: String name = newValue.toString();
1762: if (cto.isHost()) {
1763: experiment.renameHost((HostComponent) cto
1764: .getComponent(), name);
1765: cto.setName(name);
1766: nodeChanged(aNode);
1767: } else if (cto.isNode()) {
1768: experiment.renameNode((NodeComponent) cto
1769: .getComponent(), name);
1770: cto.setName(name);
1771: nodeChanged(aNode);
1772: }
1773: }
1774: };
1775: }
1776:
1777: /**
1778: * Display dialog of component names and ask user to select one.
1779: * Search the trees for the component the user selected and select it.
1780: * @param trees trees to search (i.e. hostTree, nodeTree, agentTree)
1781: * @param components list of components from which user should select
1782: * @param label to use in dialog boxes (i.e. Host, Node, Agent)
1783: */
1784: private void findWorker(JTree[] trees, BaseComponent[] components,
1785: String label) {
1786: if (components.length == 0) {
1787: JOptionPane.showMessageDialog(this , "No " + label + "s.");
1788: return;
1789: }
1790: Vector names = new Vector(components.length);
1791: for (int i = 0; i < components.length; i++)
1792: names.add(components[i].getShortName());
1793: Collections.sort(names);
1794: String[] choices = (String[]) names.toArray(new String[names
1795: .size()]);
1796: Object answer = JOptionPane.showInputDialog(this , "Select "
1797: + label, "Find " + label, JOptionPane.QUESTION_MESSAGE,
1798: null, choices, null);
1799: if (answer == null)
1800: return;
1801: for (int i = 0; i < trees.length; i++)
1802: if (selectNodeInTree(trees[i], components[0].getClass(),
1803: (String) answer))
1804: return;
1805:
1806: // If get here, couldnt find it.
1807: // say something?
1808: if (log.isWarnEnabled())
1809: log.warn("findWorker couldnt find " + label + ": "
1810: + (String) answer);
1811: }
1812:
1813: public void findHost() {
1814: JTree[] trees = new JTree[1];
1815: trees[0] = hostTree;
1816: findWorker(trees, experiment.getHostComponents(), "Host");
1817: }
1818:
1819: public void findNode() {
1820: JTree[] trees = new JTree[2];
1821: trees[0] = hostTree;
1822: trees[1] = nodeTree;
1823: findWorker(trees, experiment.getNodeComponents(), "Node");
1824: }
1825:
1826: public void findAgent() {
1827: JTree[] trees = new JTree[3];
1828: trees[0] = hostTree;
1829: trees[1] = nodeTree;
1830: trees[2] = agentTree;
1831: findWorker(trees, experiment.getAgents(), "Agent");
1832: }
1833:
1834: private boolean isOnlyRootSelected(JTree tree) {
1835: TreePath[] selectedPaths = tree.getSelectionPaths();
1836: if (selectedPaths == null || selectedPaths.length > 1)
1837: return false;
1838: DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) tree
1839: .getLastSelectedPathComponent();
1840: return selNode.isRoot();
1841: }
1842:
1843: /**
1844: * Returns true if the host tree root is selected and nothing
1845: * else in the host tree is selected.
1846: * @return true if the Host Tree root and only that is selected
1847: */
1848: public boolean isHostTreeRootSelected() {
1849: return isOnlyRootSelected(hostTree);
1850: }
1851:
1852: /**
1853: * Returns true if the unassigned Nodes tree root is selected and nothing
1854: * else in that tree is selected.
1855: * @return true if the Node Tree root and only that is selected
1856: */
1857: public boolean isNodeTreeRootSelected() {
1858: return isOnlyRootSelected(nodeTree);
1859: }
1860:
1861: private DefaultMutableTreeNode[] getSelectedItemsInTree(JTree tree,
1862: Class desiredClass) {
1863: ArrayList nodes = new ArrayList();
1864: TreePath[] selectedPaths = tree.getSelectionPaths();
1865: if (selectedPaths == null)
1866: return null;
1867: for (int i = 0; i < selectedPaths.length; i++) {
1868: DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) selectedPaths[i]
1869: .getLastPathComponent();
1870: ConsoleTreeObject selected = (ConsoleTreeObject) selNode
1871: .getUserObject();
1872: if (desiredClass.isInstance(selected.getComponent()))
1873: nodes.add(selNode);
1874: else
1875: return null;
1876: }
1877: if (nodes.size() == 0)
1878: return null;
1879: return (DefaultMutableTreeNode[]) nodes
1880: .toArray(new DefaultMutableTreeNode[nodes.size()]);
1881: }
1882:
1883: /**
1884: * Returns an array of selected Hosts in the Host tree, if and only
1885: * if at least one Host, and only Hosts are selected, else returns null.
1886: * @return array of tree nodes representing Hosts
1887: */
1888: public DefaultMutableTreeNode[] getSelectedHostsInHostTree() {
1889: return getSelectedItemsInTree(hostTree, HostComponent.class);
1890: }
1891:
1892: /**
1893: * Returns an array of selected Nodes in the Host tree, if and only
1894: * if at least one Node, and only Nodes are selected, else returns null.
1895: * @return array of tree nodes representing Nodes
1896: */
1897: public DefaultMutableTreeNode[] getSelectedNodesInHostTree() {
1898: return getSelectedItemsInTree(hostTree, NodeComponent.class);
1899: }
1900:
1901: /**
1902: * Returns an array of selected Nodes in the Node tree, if and only
1903: * if at least one Node, and only Nodes are selected, else returns null.
1904: * @return array of tree nodes representing Nodes
1905: */
1906: public DefaultMutableTreeNode[] getSelectedNodesInNodeTree() {
1907: return getSelectedItemsInTree(nodeTree, NodeComponent.class);
1908: }
1909:
1910: private BaseComponent getComponentFromPath(TreePath path) {
1911: DefaultMutableTreeNode node = (DefaultMutableTreeNode) path
1912: .getLastPathComponent();
1913: ConsoleTreeObject cto = (ConsoleTreeObject) (node
1914: .getUserObject());
1915: return cto.getComponent();
1916: }
1917:
1918: private BaseComponent getComponentFromTreeNode(
1919: DefaultMutableTreeNode treeNode) {
1920: ConsoleTreeObject cto = (ConsoleTreeObject) treeNode
1921: .getUserObject();
1922: return cto.getComponent();
1923: }
1924: }
|