001: /*
002: * <copyright>
003: *
004: * Copyright 2001-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.tools.csmart.ui.experiment;
028:
029: import org.cougaar.tools.csmart.core.db.DBConflictHandler;
030: import org.cougaar.tools.csmart.core.db.DBUtils;
031: import org.cougaar.tools.csmart.core.db.ExperimentDB;
032: import org.cougaar.tools.csmart.experiment.DBExperiment;
033: import org.cougaar.tools.csmart.experiment.Experiment;
034: import org.cougaar.tools.csmart.ui.Browser;
035: import org.cougaar.tools.csmart.ui.community.CommunityPanel;
036: import org.cougaar.tools.csmart.ui.util.NamedFrame;
037: import org.cougaar.tools.csmart.ui.viewer.CSMART;
038: import org.cougaar.tools.csmart.ui.viewer.GUIUtils;
039: import org.cougaar.tools.csmart.ui.viewer.Organizer;
040: import org.cougaar.util.log.Logger;
041:
042: import javax.swing.*;
043: import javax.swing.event.ChangeEvent;
044: import javax.swing.event.ChangeListener;
045: import javax.swing.event.MenuEvent;
046: import javax.swing.event.MenuListener;
047: import javax.swing.tree.DefaultMutableTreeNode;
048: import java.awt.*;
049: import java.awt.event.ActionEvent;
050: import java.awt.event.ActionListener;
051: import java.awt.event.WindowAdapter;
052: import java.awt.event.WindowEvent;
053: import java.io.File;
054: import java.io.IOException;
055: import java.io.ObjectInputStream;
056: import java.net.MalformedURLException;
057: import java.net.URL;
058:
059: /**
060: * The Experiment Builder is the tool for assigning society Agents to resources,
061: * configuring communities, etc.
062: **/
063: public class ExperimentBuilder extends JFrame {
064: private static final String FILE_MENU = "File";
065: private static final String COMMUNITY_MENU = "Community";
066: private static final String CONFIGURE_MENU = "Configure";
067: private static final String SAVE_MENU_ITEM = "Save";
068: private static final String SAVE_AS_MENU_ITEM = "Save As...";
069: private static final String DUMP_INI_ITEM = "Debug: Dump .ini files";
070: private static final String EXPORT_HNA_ITEM = "Export HNA Mapping";
071: private static final String IMPORT_HNA_ITEM = "Import HNA Mapping";
072: private static final String EXIT_MENU_ITEM = "Close";
073: private static final String FIND_MENU = "Find";
074: private static final String FIND_HOST_MENU_ITEM = "Find Host...";
075: private static final String FIND_NODE_MENU_ITEM = "Find Node...";
076: private static final String FIND_AGENT_MENU_ITEM = "Find Agent...";
077: private static final String HELP_MENU = "Help";
078: protected static final String HELP_DOC = "help.html";
079: private static final String PROPERTIES_MENU_ITEM = "Cougaar Properties";
080: protected static String PROPERTIES_DOC = "doc" + File.separatorChar
081: + "api" + File.separatorChar + "Parameters.html";
082: static {
083: if (System.getProperty("org.cougaar.install.path").endsWith(
084: File.separator))
085: PROPERTIES_DOC = System
086: .getProperty("org.cougaar.install.path")
087: + PROPERTIES_DOC;
088: else
089: PROPERTIES_DOC = System
090: .getProperty("org.cougaar.install.path")
091: + File.separatorChar + PROPERTIES_DOC;
092: }
093:
094: protected static final String ABOUT_CSMART_ITEM = "About CSMART";
095: protected static final String ABOUT_DOC = "/org/cougaar/tools/csmart/ui/help/about-csmart.html";
096: protected static final String HELP_MENU_ITEM = "About Experiment Builder";
097: private Experiment experiment;
098: private CSMART csmart;
099: private JTabbedPane tabbedPane;
100: private UnboundPropertyBuilder propertyBuilder;
101: private HostConfigurationBuilder hcb;
102: private ThreadBuilder threadBuilder;
103: private CommunityPanel communityPanel;
104: private JMenu findMenu;
105: private JMenu communityMenu;
106: private JMenu configureMenu;
107: private DBConflictHandler saveToDbConflictHandler = GUIUtils
108: .createSaveToDbConflictHandler(this );
109: private JMenuItem newCommunityMenuItem;
110: private JMenuItem viewCommunityMenuItem;
111: // items in file menu specific to selected node in HostConfigurationBuilder
112: private JMenuItem globalCommandLineMenuItem;
113: private JMenuItem newHostMenuItem;
114: private JMenu newNodeMenu;
115: private JMenuItem newUnassignedNodeMenuItem;
116: private JMenuItem newAssignedNodeMenuItem;
117: private JMenuItem commandLineMenuItem;
118: private JMenuItem describeHostMenuItem;
119: private JMenuItem describeNodeMenuItem;
120: private JMenuItem hostTypeMenuItem;
121: private JMenuItem hostLocationMenuItem;
122: private JMenuItem deleteHostMenuItem;
123: private JMenuItem deleteNodeMenuItem;
124:
125: private transient Logger log;
126:
127: private Action helpAction = new AbstractAction(HELP_MENU_ITEM) {
128: public void actionPerformed(ActionEvent e) {
129: URL help = (URL) this .getClass().getResource(HELP_DOC);
130: if (help != null)
131: Browser.setPage(help);
132: }
133: };
134: private Action propertiesAction = new AbstractAction(
135: PROPERTIES_MENU_ITEM) {
136: // Warning: The Parameters.html file is only available
137: // if you have the Cougaar Javadoc ZIP file installed
138: // in your COUGAAR_INSTALL_PATH.
139: // In addition, it includes some SCRIPT tags that make things
140: // look ugly in the HTML renderer Browser uses.
141: public void actionPerformed(ActionEvent e) {
142: URL help = null;
143: try {
144: File f = new File(PROPERTIES_DOC);
145: if (f.exists())
146: help = f.toURI().toURL();
147: } catch (IllegalArgumentException iae) {
148: } catch (MalformedURLException mue) {
149: }
150: if (help != null)
151: Browser.setPage(help);
152: }
153: };
154: private Action aboutAction = new AbstractAction(ABOUT_CSMART_ITEM) {
155: public void actionPerformed(ActionEvent e) {
156: URL help = (URL) this .getClass().getResource(ABOUT_DOC);
157: if (help != null)
158: Browser.setPage(help);
159: }
160: };
161: private Action[] fileActions = {
162: new AbstractAction(SAVE_MENU_ITEM) {
163: public void actionPerformed(ActionEvent e) {
164: save();
165: }
166: }, new AbstractAction(SAVE_AS_MENU_ITEM) {
167: public void actionPerformed(ActionEvent e) {
168: saveAs();
169: }
170: }, new AbstractAction(DUMP_INI_ITEM) {
171: public void actionPerformed(ActionEvent e) {
172: dumpINIs();
173: }
174: }, new AbstractAction(EXIT_MENU_ITEM) {
175: public void actionPerformed(ActionEvent e) {
176: exit();
177: NamedFrame.getNamedFrame().removeFrame(
178: ExperimentBuilder.this );
179: dispose();
180: }
181: } };
182: private Action[] hnaActions = {
183: new AbstractAction(EXPORT_HNA_ITEM) {
184: public void actionPerformed(ActionEvent e) {
185: dumpHNA();
186: }
187: }, new AbstractAction(IMPORT_HNA_ITEM) {
188: public void actionPerformed(ActionEvent e) {
189: importHNAMap();
190: }
191: } };
192:
193: private Action[] findActions = {
194: new AbstractAction(FIND_HOST_MENU_ITEM) {
195: public void actionPerformed(ActionEvent e) {
196: hcb.findHost();
197: }
198: }, new AbstractAction(FIND_NODE_MENU_ITEM) {
199: public void actionPerformed(ActionEvent e) {
200: hcb.findNode();
201: }
202: }, new AbstractAction(FIND_AGENT_MENU_ITEM) {
203: public void actionPerformed(ActionEvent e) {
204: hcb.findAgent();
205: }
206: } };
207:
208: private Action[] helpActions = { helpAction, propertiesAction,
209: aboutAction };
210:
211: /**
212: * Construct an <code>ExperimentBuilder</code> which is used
213: * to edit experiments (add/remove societies and recipes) and
214: * specify hosts, nodes and agents.
215: * @param csmart The <code>CSMART</code> object from which this is invoked
216: * @param experiment The <code>Experiment</code> to edit
217: */
218: public ExperimentBuilder(CSMART csmart, Experiment experiment) {
219: this .csmart = csmart;
220: createLogger();
221: setExperiment(experiment);
222: communityPanel = new CommunityPanel(experiment);
223: JMenuBar menuBar = new JMenuBar();
224: getRootPane().setJMenuBar(menuBar);
225:
226: // Set up Configure menu
227: configureMenu = new JMenu(CONFIGURE_MENU);
228: configureMenu.setToolTipText("Configure hosts and nodes");
229: newHostMenuItem = new JMenuItem(
230: HostConfigurationBuilder.NEW_HOST_MENU_ITEM);
231: newHostMenuItem.addActionListener(new ActionListener() {
232: public void actionPerformed(ActionEvent e) {
233: hcb.createHost();
234: }
235: });
236: newHostMenuItem.setToolTipText("Add new Host to experiment");
237: configureMenu.add(newHostMenuItem);
238: describeHostMenuItem = new JMenuItem(
239: HostConfigurationBuilder.DESCRIBE_HOST_MENU_ITEM);
240: describeHostMenuItem.addActionListener(new ActionListener() {
241: public void actionPerformed(ActionEvent e) {
242: hcb.setHostDescription();
243: }
244: });
245: describeHostMenuItem
246: .setToolTipText("Add user only host description");
247: configureMenu.add(describeHostMenuItem);
248: hostTypeMenuItem = new JMenuItem(
249: HostConfigurationBuilder.HOST_TYPE_MENU_ITEM);
250: hostTypeMenuItem.addActionListener(new ActionListener() {
251: public void actionPerformed(ActionEvent e) {
252: hcb.setHostType();
253: }
254: });
255: hostTypeMenuItem
256: .setToolTipText("Specify the host platform for user information");
257: configureMenu.add(hostTypeMenuItem);
258: hostLocationMenuItem = new JMenuItem(
259: HostConfigurationBuilder.HOST_LOCATION_MENU_ITEM);
260: hostLocationMenuItem.addActionListener(new ActionListener() {
261: public void actionPerformed(ActionEvent e) {
262: hcb.setHostLocation();
263: }
264: });
265: hostLocationMenuItem
266: .setToolTipText("Specify host location for user use");
267: configureMenu.add(hostLocationMenuItem);
268: deleteHostMenuItem = new JMenuItem(
269: HostConfigurationBuilder.DELETE_HOST_MENU_ITEM);
270: deleteHostMenuItem.addActionListener(new ActionListener() {
271: public void actionPerformed(ActionEvent e) {
272: hcb.deleteHost();
273: }
274: });
275: deleteHostMenuItem
276: .setToolTipText("Remove host from experiment");
277: configureMenu.add(deleteHostMenuItem);
278:
279: configureMenu.addSeparator();
280:
281: globalCommandLineMenuItem = new JMenuItem(
282: HostConfigurationBuilder.GLOBAL_COMMAND_LINE_MENU_ITEM);
283: globalCommandLineMenuItem
284: .addActionListener(new ActionListener() {
285: public void actionPerformed(ActionEvent e) {
286: hcb.setGlobalCommandLine();
287: }
288: });
289: globalCommandLineMenuItem
290: .setToolTipText("Specify Command Line Arguments common to all Nodes");
291: configureMenu.add(globalCommandLineMenuItem);
292:
293: commandLineMenuItem = new JMenuItem(
294: HostConfigurationBuilder.NODE_COMMAND_LINE_MENU_ITEM);
295: commandLineMenuItem.addActionListener(new ActionListener() {
296: public void actionPerformed(ActionEvent e) {
297: hcb.setNodeCommandLine();
298: }
299: });
300: commandLineMenuItem
301: .setToolTipText("Specify Command Line Arguments specific to this Node");
302: configureMenu.add(commandLineMenuItem);
303:
304: configureMenu.addSeparator();
305:
306: newNodeMenu = new JMenu(
307: HostConfigurationBuilder.NEW_NODE_MENU_ITEM);
308: newNodeMenu.setToolTipText("Create a new Node....");
309: newUnassignedNodeMenuItem = new JMenuItem("Unassigned");
310: newUnassignedNodeMenuItem
311: .setToolTipText("Create new Node in unassigned list");
312: newUnassignedNodeMenuItem
313: .addActionListener(new ActionListener() {
314: public void actionPerformed(ActionEvent e) {
315: hcb.createUnassignedNode();
316: }
317: });
318: newNodeMenu.add(newUnassignedNodeMenuItem);
319: newAssignedNodeMenuItem = new JMenuItem("On Host");
320: newAssignedNodeMenuItem
321: .setToolTipText("Create new Node assigned to this Host");
322: newAssignedNodeMenuItem.addActionListener(new ActionListener() {
323: public void actionPerformed(ActionEvent e) {
324: hcb.createAssignedNode();
325: }
326: });
327: newNodeMenu.add(newAssignedNodeMenuItem);
328: configureMenu.add(newNodeMenu);
329: describeNodeMenuItem = new JMenuItem(
330: HostConfigurationBuilder.DESCRIBE_NODE_MENU_ITEM);
331: describeNodeMenuItem.addActionListener(new ActionListener() {
332: public void actionPerformed(ActionEvent e) {
333: hcb.setNodeDescription();
334: }
335: });
336: describeNodeMenuItem
337: .setToolTipText("Add user readable description of the Node");
338: configureMenu.add(describeNodeMenuItem);
339: deleteNodeMenuItem = new JMenuItem(
340: HostConfigurationBuilder.DELETE_NODE_MENU_ITEM);
341: deleteNodeMenuItem.addActionListener(new ActionListener() {
342: public void actionPerformed(ActionEvent e) {
343: hcb.deleteNode();
344: }
345: });
346: deleteNodeMenuItem
347: .setToolTipText("Remove this Node from the Experiment");
348: configureMenu.add(deleteNodeMenuItem);
349:
350: configureMenu.addSeparator();
351:
352: // If these HNAs werent abstract actions, I'd set ToolTips on them
353: // However, the add method returns a menu item on which
354: // I can call setToolTipText
355: for (int i = 0; i < hnaActions.length; i++) {
356: configureMenu
357: .add(hnaActions[i])
358: .setToolTipText(
359: "Save and reuse host-node-agent mappings between experiments");
360: }
361:
362: configureMenu.addMenuListener(myMenuListener);
363:
364: // End of Configure menu setup. Now File Menu
365:
366: JMenu fileMenu = new JMenu(FILE_MENU);
367: fileMenu.setToolTipText("Save, export configuration, or quit");
368:
369: for (int i = 0; i < fileActions.length; i++) {
370: fileMenu.add(fileActions[i]);
371: }
372:
373: fileMenu.addMenuListener(myMenuListener);
374:
375: // Now set up the Community menu
376:
377: communityMenu = new JMenu(COMMUNITY_MENU);
378: communityMenu.setToolTipText("Configure communities");
379: newCommunityMenuItem = new JMenuItem(
380: communityPanel.newCommunityAction);
381: newCommunityMenuItem
382: .setToolTipText("Create new community for this Experiment");
383: communityMenu.add(newCommunityMenuItem);
384: viewCommunityMenuItem = new JMenuItem(
385: communityPanel.viewCommunityAction);
386: viewCommunityMenuItem
387: .setToolTipText("Display details for one community in the Experiment");
388: communityMenu.add(viewCommunityMenuItem);
389: communityMenu.addMenuListener(myMenuListener);
390:
391: // Now the Find Menu
392:
393: findMenu = new JMenu(FIND_MENU);
394: findMenu.setToolTipText("Find a host, node, or agent.");
395: for (int i = 0; i < findActions.length; i++) {
396: findMenu.add(findActions[i]);
397: }
398:
399: // Finally the Help menu
400: JMenu helpMenu = new JMenu(HELP_MENU);
401: helpMenu.setToolTipText("Display documentation.");
402: for (int i = 0; i < helpActions.length; i++) {
403: helpMenu.add(helpActions[i]);
404: }
405:
406: menuBar.add(fileMenu);
407: menuBar.add(configureMenu);
408: menuBar.add(findMenu);
409: menuBar.add(communityMenu);
410: menuBar.add(helpMenu);
411: setJMenuBar(menuBar);
412:
413: tabbedPane = new JTabbedPane();
414: tabbedPane.addChangeListener(new ChangeListener() {
415: public void stateChanged(ChangeEvent e) {
416: if (tabbedPane.getSelectedComponent().equals(hcb)) {
417: findMenu.setEnabled(true);
418: configureMenu.setEnabled(true);
419: } else {
420: findMenu.setEnabled(false);
421: configureMenu.setEnabled(false);
422: }
423: if (tabbedPane.getSelectedComponent().equals(
424: communityPanel))
425: communityMenu.setEnabled(true);
426: else
427: communityMenu.setEnabled(false);
428: }
429: });
430: propertyBuilder = new UnboundPropertyBuilder(experiment, this );
431: tabbedPane.add("Properties", propertyBuilder);
432: hcb = new HostConfigurationBuilder(experiment, this );
433: tabbedPane.add("Configurations", hcb);
434:
435: tabbedPane.add("Communities", communityPanel);
436:
437: // Only need to add the ThreadBuilder if there are threads
438: // FIXME: This does not entirely cover the cases where
439: // putting this up would be useful -- a CSA assembly
440: // could also have legitimate threads
441: if (DBUtils.containsCMTAssembly(experiment.getExperimentID())) {
442: threadBuilder = new ThreadBuilder(experiment);
443: } else {
444: threadBuilder = new ThreadBuilder(null);
445: }
446: tabbedPane.add("Threads", threadBuilder);
447:
448: // after starting all the editors, set experiment editability to false
449: experiment.setEditInProgress(true);
450: getContentPane().add(tabbedPane);
451: pack();
452: setSize(660, 600);
453:
454: setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
455: addWindowListener(new WindowAdapter() {
456: public void windowClosing(WindowEvent e) {
457: if (!ExperimentBuilder.this .getGlassPane().isVisible()) {
458: exit();
459: }
460: }
461: });
462: show();
463: }
464:
465: private void createLogger() {
466: log = CSMART.createLogger(this .getClass().getName());
467: }
468:
469: private void setExperiment(Experiment newExperiment) {
470: experiment = newExperiment;
471: }
472:
473: private void exit() {
474: saveHelper(false); // if experiment from database was modified, save it
475: experiment.setEditInProgress(false);
476: // display experiment components in organizer
477: Organizer organizer = CSMART.getOrganizer();
478: organizer.addChildren(experiment);
479: }
480:
481: /**
482: * Set experiment to edit; used to re-use a running editor
483: * to edit a different experiment. Set the new experiment in all
484: * the user interfaces (tabbed panes).
485: * Silently save the previous experiment if it was modified.
486: * @param newExperiment the new experiment to edit
487: */
488: public void reinit(Experiment newExperiment) {
489: saveHelper(false);
490: // restore editable flag on previous experiment
491: experiment.setEditInProgress(false);
492: experiment = newExperiment;
493: propertyBuilder.reinit(experiment);
494: hcb.reinit(experiment);
495: communityPanel.reinit(experiment);
496: // only display trial builder for non-database experiments
497: // trialBuilder.reinit(experiment);
498: // only display thread builder for database experiments
499: threadBuilder.reinit(experiment);
500: experiment.setEditInProgress(true);
501: }
502:
503: /**
504: * If the experiment was from the database and
505: * components were either added or removed or
506: * the host-node-agent mapping was modified, then save it,
507: * otherwise display a dialog indicating that no modifications were made.
508: */
509:
510: private void save() {
511: if (!experiment.isModified()) {
512: String[] msg = { "No modifications were made.",
513: "Do you want to save this experiment anyway?" };
514: int answer = JOptionPane.showConfirmDialog(this , msg,
515: "No Modifications", JOptionPane.YES_NO_OPTION,
516: JOptionPane.WARNING_MESSAGE);
517: if (answer != JOptionPane.YES_OPTION)
518: return;
519: }
520: saveHelper(true);
521: }
522:
523: private void saveAs() {
524: // get unique name in both database and CSMART or
525: // reuse existing name
526: String name = null;
527: if (ExperimentDB.isExperimentNameInDatabase(experiment
528: .getShortName())) {
529: name = CSMART.getOrganizer().getUniqueExperimentName(
530: experiment.getShortName(), true);
531: if (name == null)
532: return;
533: experiment.setName(name);
534: }
535: saveHelper(false);
536: // reset title on the window here?
537: if (name != null)
538: setTitle(CSMART.EXPERIMENT_BUILDER + ": " + name);
539: }
540:
541: // Dump out the ini files for the first trial to the local results directory
542: private void dumpINIs() {
543: experiment.dumpINIFiles();
544: }
545:
546: private void dumpHNA() {
547: experiment.dumpHNA();
548: }
549:
550: private void importHNAMap() {
551: experiment.importHNA(this );
552: hcb.update();
553: }
554:
555: /**
556: * Save the experiment.
557: * Save if the user said to do so anyhow,
558: * or if it was modified.
559: */
560: private void saveHelper(boolean force) {
561: if (force || experiment.isModified()) {
562: final Component c = this ;
563: GUIUtils.timeConsumingTaskStart(csmart);
564: GUIUtils.timeConsumingTaskStart(c);
565: try {
566: new Thread("Save") {
567: public void run() {
568: experiment.save(saveToDbConflictHandler);
569: GUIUtils.timeConsumingTaskEnd(csmart);
570: GUIUtils.timeConsumingTaskEnd(c);
571: }
572: }.start();
573: } catch (RuntimeException re) {
574: if (log.isErrorEnabled()) {
575: log.error("Error saving experiment: ", re);
576: }
577: GUIUtils.timeConsumingTaskEnd(csmart);
578: GUIUtils.timeConsumingTaskEnd(c);
579: }
580: }
581: }
582:
583: /**
584: * Enable/disable entries in the File menu dependent on what
585: * is selected in the organizer.
586: */
587:
588: private MenuListener myMenuListener = new MenuListener() {
589: public void menuCanceled(MenuEvent e) {
590: }
591:
592: public void menuDeselected(MenuEvent e) {
593: }
594:
595: public void menuSelected(MenuEvent e) {
596: Component selectedComponent = tabbedPane
597: .getSelectedComponent();
598: boolean communityEnabled = selectedComponent
599: .equals(communityPanel);
600: newCommunityMenuItem.setEnabled(communityEnabled);
601: viewCommunityMenuItem.setEnabled(communityEnabled);
602: boolean hcbEnabled = selectedComponent.equals(hcb);
603: globalCommandLineMenuItem.setEnabled(hcbEnabled);
604: newHostMenuItem.setEnabled(hcbEnabled);
605: newNodeMenu.setEnabled(hcbEnabled);
606: commandLineMenuItem.setEnabled(hcbEnabled);
607: describeHostMenuItem.setEnabled(hcbEnabled);
608: describeNodeMenuItem.setEnabled(hcbEnabled);
609: hostTypeMenuItem.setEnabled(hcbEnabled);
610: hostLocationMenuItem.setEnabled(hcbEnabled);
611: deleteHostMenuItem.setEnabled(hcbEnabled);
612: deleteNodeMenuItem.setEnabled(hcbEnabled);
613: if (!hcbEnabled)
614: return;
615: // configure menu items for host configuration builder
616: // enable "global command line" command
617: // if either root, or any set of hosts or nodes is selected
618: DefaultMutableTreeNode[] hostsInHostTree = hcb
619: .getSelectedHostsInHostTree();
620: DefaultMutableTreeNode[] nodesInHostTree = hcb
621: .getSelectedNodesInHostTree();
622: DefaultMutableTreeNode[] nodesInNodeTree = hcb
623: .getSelectedNodesInNodeTree();
624: boolean isNodeRootSelected = hcb.isNodeTreeRootSelected();
625: // enable "new node" command if unassigned nodes root is selected
626: // or one host is selected in the host tree
627: newUnassignedNodeMenuItem.setEnabled(isNodeRootSelected);
628: if (hostsInHostTree != null && hostsInHostTree.length == 1) {
629: newAssignedNodeMenuItem.setText("On "
630: + hostsInHostTree[0].toString());
631: newAssignedNodeMenuItem.setEnabled(true);
632: } else
633: newAssignedNodeMenuItem.setEnabled(false);
634: newNodeMenu.setEnabled(newAssignedNodeMenuItem.isEnabled()
635: || newUnassignedNodeMenuItem.isEnabled());
636: // if a single node is selected
637: // enable "command line arguments"
638: int nodeCount = 0;
639: if (nodesInHostTree != null)
640: nodeCount = nodesInHostTree.length;
641: if (nodesInNodeTree != null)
642: nodeCount += nodesInNodeTree.length;
643: commandLineMenuItem.setEnabled(nodeCount == 1);
644: describeHostMenuItem.setEnabled(hostsInHostTree != null);
645: describeNodeMenuItem.setEnabled(nodesInHostTree != null
646: || nodesInNodeTree != null);
647: hostTypeMenuItem.setEnabled(hostsInHostTree != null);
648: hostLocationMenuItem.setEnabled(hostsInHostTree != null);
649: deleteHostMenuItem.setEnabled(hostsInHostTree != null);
650: deleteNodeMenuItem.setEnabled(nodesInHostTree != null
651: || nodesInNodeTree != null);
652: }
653: };
654:
655: private void readObject(ObjectInputStream ois) throws IOException,
656: ClassNotFoundException {
657: ois.defaultReadObject();
658: createLogger();
659: }
660:
661: }
|