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.viewer;
0028:
0029: // tools created by this user interface
0030: import org.cougaar.bootstrap.Bootstrapper;
0031: import org.cougaar.tools.csmart.core.cdata.ComponentData;
0032: import org.cougaar.tools.csmart.core.property.ModifiableComponent;
0033: import org.cougaar.tools.csmart.experiment.DBExperiment;
0034: import org.cougaar.tools.csmart.experiment.Experiment;
0035: import org.cougaar.tools.csmart.recipe.RecipeComponent;
0036: import org.cougaar.tools.csmart.society.SocietyComponent;
0037: import org.cougaar.tools.csmart.society.cdata.SocietyCDataComponent;
0038: import org.cougaar.tools.csmart.ui.Browser;
0039: import org.cougaar.tools.csmart.ui.analyzer.Analyzer;
0040: import org.cougaar.tools.csmart.ui.configbuilder.PropertyBuilder;
0041: import org.cougaar.tools.csmart.ui.console.CSMARTConsoleView;
0042: import org.cougaar.tools.csmart.ui.experiment.ExperimentBuilder;
0043: import org.cougaar.tools.csmart.ui.monitor.generic.ExtensionFileFilter;
0044: import org.cougaar.tools.csmart.ui.monitor.viewer.CSMARTUL;
0045: import org.cougaar.tools.csmart.ui.util.NamedFrame;
0046: import org.cougaar.util.ConfigFinder;
0047: import org.cougaar.util.log.Logger;
0048: import org.cougaar.util.log.LoggerFactory;
0049:
0050: import javax.swing.*;
0051: import javax.swing.event.MenuEvent;
0052: import javax.swing.event.MenuListener;
0053: import javax.swing.event.TreeSelectionEvent;
0054: import javax.swing.event.TreeSelectionListener;
0055: import javax.swing.tree.DefaultMutableTreeNode;
0056: import java.awt.*;
0057: import java.awt.event.ActionEvent;
0058: import java.awt.event.ActionListener;
0059: import java.awt.event.WindowAdapter;
0060: import java.awt.event.WindowEvent;
0061: import java.io.File;
0062: import java.io.FileInputStream;
0063: import java.io.IOException;
0064: import java.io.ObjectInputStream;
0065: import java.lang.reflect.Field;
0066: import java.net.InetAddress;
0067: import java.net.URL;
0068: import java.text.SimpleDateFormat;
0069: import java.util.ArrayList;
0070: import java.util.Date;
0071: import java.util.HashMap;
0072: import java.util.Hashtable;
0073: import java.util.Observable;
0074: import java.util.Observer;
0075: import java.util.Properties;
0076:
0077: /**
0078: * Top level CSMART user interface.
0079: * Allows user to: build, test, control, monitor and analyze a society. For installation and
0080: * basic usage, see csmart/doc/InstallAndTest.html.<br>
0081: * @property org.cougaar.tools.csmart.doWorkspace if false do NOT read/write from Default Worksapce file.
0082: * @property org.cougaar.configuration.database should be specified in
0083: * cougaar.rc as the URL to find the CSMART database. See CSMART InstallAndTest.html
0084: * @property csmart.PopulateDb.log.enable if true enables the logging
0085: * of some executed database queries to a file named PopulateDb<datetime>.log.
0086: * @property org.cougaar.install.path Used to default results directory,
0087: * find workspace file, saved graphs, etc
0088: * @property org.cougaar.config.path has standard meaning, and is used to
0089: * find some CSMART UI properties among other things.
0090: * @property org.cougaar.useBootstrapper has meaning specified by Bootstrapper
0091: *
0092: */
0093: public class CSMART extends JFrame {
0094: private static Organizer organizer;
0095: private static JFileChooser workspaceFileChooser;
0096: private static ArrayList runningExperiments = new ArrayList();
0097: private static JToolBar toolBar = null;
0098: private static JMenu windowMenu;
0099: // private static CSMARTConsole console;
0100: private static File resultDir;
0101: private static JMenu fileMenu;
0102: private static JMenu editMenu;
0103: private static JButton configureButton;
0104: private static JButton buildButton;
0105: private static JButton runButton;
0106: private static Hashtable titleToMenuItem = new Hashtable();
0107:
0108: // define strings here so we can easily change them
0109: private static final String FILE_MENU = "File";
0110: private static final String NEW_MENU_ITEM = "Open Workspace...";
0111: private static final String NEW_RESULTS_MENU_ITEM = "Save New Results In...";
0112: private static final String EXIT_MENU_ITEM = "Exit";
0113:
0114: private static final String EDIT_MENU = "Edit";
0115:
0116: private static final String WINDOW_MENU = "Window";
0117:
0118: private static final String HELP_MENU = "Help";
0119: protected static final String HELP_DOC = "help.html";
0120: protected static final String ABOUT_DOC = "/org/cougaar/tools/csmart/ui/help/about-csmart.html";
0121: private static final String VERSION_ACTION = "Show CSMART Version";
0122: private static final String ABOUT_CSMART_ACTION = "About CSMART";
0123: private static final String HELP_ACTION = "About Launcher";
0124: private static final String CSMART_LISTENER = "CSMART-";
0125: private static String listenerId;
0126: private transient Logger log;
0127:
0128: private Action[] helpActions = { new AbstractAction(HELP_ACTION) {
0129: public void actionPerformed(ActionEvent e) {
0130: CSMART.displayURL(HELP_DOC);
0131: }
0132: }, new AbstractAction(VERSION_ACTION) {
0133: public void actionPerformed(ActionEvent e) {
0134: Browser.setPage(writeDebug());
0135: //CSMART.displayURL(ABOUT_DOC);
0136: }
0137: }, new AbstractAction(ABOUT_CSMART_ACTION) {
0138: public void actionPerformed(ActionEvent e) {
0139: CSMART.displayURL(ABOUT_DOC);
0140: }
0141: } };
0142:
0143: private static final String PRE = "<html><center><b><font face=\"sans-serif\">";
0144: private static final String POST = "</font></b></center></html>";
0145: // tool names
0146: public static final String CONFIGURATION_BUILDER = "Configuration Builder";
0147: public static final String EXPERIMENT_BUILDER = "Experiment Builder";
0148: private static final String EXPERIMENT_CONTROLLER = "Experiment Controller";
0149: private static final String SOCIETY_MONITOR = "Society Monitor";
0150: private static final String PERFORMANCE_ANALYZER = "Performance Analyzer";
0151: private static final String[] views = { CONFIGURATION_BUILDER,
0152: EXPERIMENT_BUILDER, EXPERIMENT_CONTROLLER, SOCIETY_MONITOR,
0153: PERFORMANCE_ANALYZER };
0154:
0155: private static final String[] tooltips = {
0156: "Specify properties of a society or other configurable component.",
0157: "Configure an experiment.",
0158: "Start, stop and abort experiments.",
0159: "Monitor a running society.",
0160: "Analyze results of running an experiment." };
0161:
0162: private static final String[] iconFilenames = { "SB.gif",
0163: "Experiment48t.gif", "EC.gif", "SM.gif", "PA.gif" };
0164:
0165: private CSMART csmart;
0166:
0167: private DBExperiment experimentToEdit;
0168:
0169: /**
0170: * Constructor for top level class in CSMART.
0171: */
0172: public CSMART() {
0173: setTitle("CSMART");
0174: csmart = this ;
0175:
0176: createLog();
0177:
0178: // Write initial CSMART info to the log file
0179: if (log.isShoutEnabled()) {
0180: log.shout(writeDebug());
0181: }
0182:
0183: resultDir = initResultDir();
0184:
0185: organizer = new Organizer(this );
0186: initDisplay();
0187: setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
0188:
0189: // if user closes this window, quit
0190: addWindowListener(new WindowAdapter() {
0191: public void windowClosing(WindowEvent e) {
0192: if (!CSMART.this .getGlassPane().isVisible()) {
0193: exit();
0194: }
0195: }
0196: });
0197:
0198: NamedFrame.getNamedFrame().addObserver(myFrameObserver);
0199:
0200: pack();
0201: Dimension screenSize = Toolkit.getDefaultToolkit()
0202: .getScreenSize();
0203: int w = getWidth();
0204: int h = getHeight();
0205: setSize(w, h);
0206: setLocation((screenSize.width - w) / 2,
0207: (screenSize.height - h) / 2);
0208: setVisible(true);
0209: }
0210:
0211: public static String getNodeListenerId() {
0212: if (listenerId == null) {
0213: String hostName = "";
0214: try {
0215: InetAddress myAddr = InetAddress.getLocalHost();
0216: hostName = myAddr.getHostName();
0217: } catch (Exception e) {
0218: // Safe to ignore. Will just have an empty hostname.
0219: }
0220:
0221: listenerId = CSMART_LISTENER
0222: + hostName
0223: + "-"
0224: + new SimpleDateFormat("yyyyMMddHHmmss")
0225: .format(new Date());
0226: }
0227: return listenerId;
0228: }
0229:
0230: // must be called whenever there's a new organizer (i.e. new workspace)
0231: private void initDisplay() {
0232: JMenuBar menuBar = new JMenuBar();
0233: getRootPane().setJMenuBar(menuBar);
0234: // set-up file menu which includes entries based on workspace selection
0235: fileMenu = new JMenu(FILE_MENU);
0236: fileMenu.setToolTipText("Create new workspace or quit.");
0237: fileMenu.addMenuListener(myMenuListener);
0238: JMenuItem newMenuItem = new JMenuItem(NEW_MENU_ITEM);
0239: newMenuItem.addActionListener(new ActionListener() {
0240: public void actionPerformed(ActionEvent e) {
0241: newWorkspace();
0242: }
0243: });
0244: newMenuItem.setToolTipText("Create a new workspace.");
0245: fileMenu.add(newMenuItem);
0246: JMenuItem newResultsMenuItem = new JMenuItem(
0247: NEW_RESULTS_MENU_ITEM);
0248: newResultsMenuItem.addActionListener(new ActionListener() {
0249: public void actionPerformed(ActionEvent e) {
0250: setResultDir();
0251: }
0252: });
0253: newResultsMenuItem
0254: .setToolTipText("Select a directory for saving results");
0255: fileMenu.add(newResultsMenuItem);
0256:
0257: JMenuItem exitMenuItem = new JMenuItem(EXIT_MENU_ITEM);
0258: exitMenuItem.addActionListener(new ActionListener() {
0259: public void actionPerformed(ActionEvent e) {
0260: exit();
0261: }
0262: });
0263: exitMenuItem.setToolTipText("Exit");
0264: fileMenu.add(exitMenuItem);
0265:
0266: // End of file menu
0267: editMenu = new JMenu(EDIT_MENU);
0268: editMenu
0269: .setToolTipText("Load, edit, run, or delete experiments");
0270: editMenu.addMenuListener(myMenuListener);
0271:
0272: JMenu newExperimentMenu = new JMenu(
0273: ActionUtil.NEW_EXPERIMENT_ACTION);
0274: for (int i = 0; i < organizer.newExperimentActions.length; i++)
0275: newExperimentMenu.add(organizer.newExperimentActions[i]);
0276: editMenu.add(newExperimentMenu);
0277: newExperimentMenu
0278: .setToolTipText("Load or Create an Experiment");
0279:
0280: JMenu newRecipeMenu = new JMenu(ActionUtil.NEW_RECIPE_ACTION);
0281: for (int i = 0; i < organizer.newRecipeActions.length; i++)
0282: newRecipeMenu.add(organizer.newRecipeActions[i]);
0283: editMenu.add(newRecipeMenu);
0284: newRecipeMenu.setToolTipText("Load or Create a Recipe");
0285:
0286: JMenuItem newMenu = null;
0287: newMenu = new JMenuItem(
0288: organizer.deleteExperimentFromDatabaseAction);
0289: newMenu
0290: .setToolTipText("Delete an Experiment from the Database");
0291: editMenu.add(newMenu);
0292:
0293: newMenu = new JMenuItem(
0294: organizer.deleteRecipeFromDatabaseAction);
0295: newMenu.setToolTipText("Delete a recipe from the Database");
0296: editMenu.add(newMenu);
0297:
0298: newMenu = new JMenuItem(organizer.newFolderAction);
0299: newMenu.setToolTipText("Create new folder in Organizer");
0300: editMenu.add(newMenu);
0301:
0302: editMenu.addSeparator();
0303:
0304: newMenu = new JMenuItem(organizer.configureAction);
0305: newMenu.setToolTipText("Edit a Society or Recipe");
0306: editMenu.add(newMenu);
0307:
0308: newMenu = new JMenuItem(organizer.buildExperimentAction);
0309: newMenu.setToolTipText("Set up Experiment Configuration");
0310: editMenu.add(newMenu);
0311:
0312: newMenu = new JMenuItem(organizer.runExperimentAction);
0313: newMenu
0314: .setToolTipText("Run a configured Experiment, or attach to a running Experiment");
0315: editMenu.add(newMenu);
0316:
0317: newMenu = new JMenuItem(organizer.duplicateAction);
0318: newMenu.setToolTipText("Copy this item");
0319: editMenu.add(newMenu);
0320:
0321: newMenu = new JMenuItem(organizer.renameAction);
0322: newMenu.setToolTipText("Rename this item (possibly workspace)");
0323: editMenu.add(newMenu);
0324:
0325: newMenu = new JMenuItem(organizer.saveAction);
0326: newMenu.setToolTipText("Save a modified item");
0327: editMenu.add(newMenu);
0328:
0329: newMenu = new JMenuItem(organizer.deleteAction);
0330: newMenu.setToolTipText("Delete this item");
0331: editMenu.add(newMenu);
0332:
0333: // Done with Edit menu
0334:
0335: windowMenu = new JMenu(WINDOW_MENU);
0336: windowMenu.setToolTipText("Display selected window.");
0337:
0338: JMenu helpMenu = new JMenu(HELP_MENU);
0339: for (int i = 0; i < helpActions.length; i++)
0340: helpMenu.add(new JMenuItem(helpActions[i]));
0341:
0342: menuBar.add(fileMenu);
0343: menuBar.add(editMenu);
0344: menuBar.add(windowMenu);
0345: menuBar.add(helpMenu);
0346:
0347: if (toolBar != null)
0348: getContentPane().remove(toolBar); // get rid of old tool bar if any
0349: toolBar = new JToolBar();
0350: toolBar.setLayout(new GridLayout(1, 5, 2, 2));
0351: getContentPane().add("North", toolBar);
0352: // Warning: This listener will fire as the organizer restores
0353: // the XML workspace
0354: organizer.addTreeSelectionListener(new TreeSelectionListener() {
0355: public void valueChanged(TreeSelectionEvent e) {
0356: enableCSMARTTools();
0357: }
0358: });
0359:
0360: Action societyAction = new AbstractAction() {
0361: public void actionPerformed(ActionEvent e) {
0362: JFrame societyMonitorFrame = NamedFrame.getNamedFrame()
0363: .getToolFrame(SOCIETY_MONITOR);
0364: if (societyMonitorFrame == null)
0365: runMonitor();
0366: else
0367: societyMonitorFrame.toFront();
0368: }
0369: };
0370:
0371: Action analyzerAction = new AbstractAction() {
0372: public void actionPerformed(ActionEvent e) {
0373: DefaultMutableTreeNode node = organizer
0374: .getSelectedNode();
0375: Object userObject = node.getUserObject();
0376: if (userObject instanceof Experiment)
0377: runAnalyzer((Experiment) userObject);
0378: else
0379: runAnalyzer();
0380: }
0381: };
0382:
0383: Action[] actions = { organizer.configureAction,
0384: organizer.buildExperimentAction,
0385: organizer.runExperimentAction, societyAction,
0386: analyzerAction };
0387:
0388: for (int i = 0; i < views.length; i++) {
0389: JButton button = makeButton(views[i], iconFilenames[i],
0390: actions[i]);
0391: button.setHorizontalTextPosition(JButton.CENTER);
0392: button.setVerticalTextPosition(JButton.BOTTOM);
0393: button.setActionCommand(views[i]);
0394: button.setToolTipText(tooltips[i]);
0395: toolBar.add(button);
0396: }
0397: configureButton = (JButton) toolBar.getComponentAtIndex(0);
0398: buildButton = (JButton) toolBar.getComponentAtIndex(1);
0399: runButton = (JButton) toolBar.getComponentAtIndex(2);
0400:
0401: // Add the Organizer much later, so the listeners dont fire
0402: // before the buttons have been defined.
0403: getContentPane().add("Center", organizer);
0404:
0405: enableCSMARTTools();
0406: }
0407:
0408: /**
0409: * Get the <code>Organizer</code> object which manages the tree
0410: * of experiments, societies, recipes, etc.
0411: * @return the organizer
0412: */
0413: public static Organizer getOrganizer() {
0414: return organizer;
0415: }
0416:
0417: /**
0418: * Enable/disable entries in the File menu dependent on what
0419: * is selected in the organizer.
0420: */
0421:
0422: private MenuListener myMenuListener = new MenuListener() {
0423: public void menuCanceled(MenuEvent e) {
0424: }
0425:
0426: public void menuDeselected(MenuEvent e) {
0427: }
0428:
0429: public void menuSelected(MenuEvent e) {
0430: enableActions((JMenu) e.getSource());
0431: }
0432:
0433: // set whether actions in menu are enabled
0434: // and return true if any are enabled
0435: private boolean enableActions(JMenu menu) {
0436: boolean haveEnabledActions = false;
0437: int n = menu.getItemCount();
0438: for (int i = 0; i < n; i++) {
0439: JMenuItem menuItem = menu.getItem(i);
0440: if (menuItem == null)
0441: continue;
0442: String s = menuItem.getText();
0443: if (s.equals(NEW_MENU_ITEM)
0444: || s.equals(NEW_RESULTS_MENU_ITEM)
0445: || s.equals(EXIT_MENU_ITEM)) {
0446: haveEnabledActions = true;
0447: continue;
0448: }
0449: if (menuItem instanceof JMenu) {
0450: if (enableActions((JMenu) menuItem)) {
0451: menuItem.setEnabled(true);
0452: haveEnabledActions = true;
0453: } else
0454: menuItem.setEnabled(false);
0455: } else {
0456: Action action = menuItem.getAction();
0457: if (action != null) {
0458: ActionUtil.setActionAllowed(action, organizer);
0459: if (action.isEnabled())
0460: haveEnabledActions = true;
0461: }
0462: }
0463: }
0464: return haveEnabledActions;
0465: }
0466: }; // end of listener
0467:
0468: // TODO: runningExperiments is maintained solely so
0469: // that the SocietyMonitor can be started with a reference
0470: // to the running experiment if there is one
0471: // is there a better way to do this, i.e. have the console(s)
0472: // implement a method to get the running experiment if any?
0473: /**
0474: * Add an experiment to the list of running experiments.
0475: * @param experiment the experiment to add
0476: */
0477: public void addRunningExperiment(Experiment experiment) {
0478: if (!runningExperiments.contains(experiment))
0479: runningExperiments.add(experiment);
0480: }
0481:
0482: /**
0483: * Remove an experiment from the list of running experiments.
0484: * @param experiment the experiment to remove
0485: */
0486: public void removeRunningExperiment(Experiment experiment) {
0487: runningExperiments.remove(experiment);
0488: }
0489:
0490: /**
0491: * Get the list of running experiments.
0492: * @return an array of <code>Experiment</code>
0493: */
0494: public static Experiment[] getRunningExperiments() {
0495: return (Experiment[]) runningExperiments
0496: .toArray(new Experiment[runningExperiments.size()]);
0497: }
0498:
0499: /**
0500: * Called on initialization, when a selection changes in the Organizer, or
0501: * when the configuration builder, experiment builder, or console
0502: * start or stop.
0503: * Uses the action utilities to figure out what's allowed,
0504: * so that it matches the File menu and pop-up menus.
0505: */
0506:
0507: protected void enableCSMARTTools() {
0508: // When restoring Organizer XML, the listener can get fired
0509: // before the buttons have been defined, causing an NPE.
0510: if (configureButton == null)
0511: return;
0512: ActionUtil.setActionAllowed(configureButton.getAction(),
0513: organizer);
0514: ActionUtil.setActionAllowed(buildButton.getAction(), organizer);
0515: ActionUtil.setActionAllowed(runButton.getAction(), organizer);
0516: }
0517:
0518: private void exit() {
0519: if (organizer.exitAllowed()) {
0520: // don't stop experiments when exiting CSMART
0521: // if (console != null)
0522: // console.stopExperiments();
0523: System.exit(0);
0524: }
0525: }
0526:
0527: private JButton makeButton(String label, String iconFilename,
0528: Action action) {
0529: // replace spaces in label with <br> so that labels fit on buttons
0530: int index = label.indexOf(' ');
0531: while (index != -1) {
0532: label = label.substring(0, index) + "<br>"
0533: + label.substring(index + 1);
0534: index = label.indexOf(' ');
0535: }
0536: label = PRE + label + POST; // formatting
0537: URL iconURL = getClass().getResource(iconFilename);
0538: if (iconURL == null)
0539: return new JButton(label);
0540: ImageIcon icon = new ImageIcon(iconURL);
0541: JButton button = new JButton(action);
0542: button.setText(label);
0543: button.setIcon(icon);
0544: return button;
0545: // return new JButton(label, icon);
0546: }
0547:
0548: Observer myFrameObserver = new Observer() {
0549: ActionListener myActionListener = new ActionListener() {
0550: public void actionPerformed(ActionEvent e) {
0551: String s = ((AbstractButton) e.getSource())
0552: .getActionCommand();
0553: JFrame f = NamedFrame.getNamedFrame().getFrame(s);
0554: if (f != null) {
0555: f.toFront();
0556: f.setState(Frame.NORMAL);
0557: }
0558: }
0559: };
0560:
0561: /**
0562: * Window management for windows launched by CSMART.
0563: * Updates which tools are enabled and updates the Window menu.
0564: * @param o the <code>NamedFrame</code> that was added, removed or changed
0565: * @param arg an event describing the change
0566: */
0567: public void update(Observable o, Object arg) {
0568: if (o instanceof NamedFrame) {
0569: // NamedFrame namedFrame = (NamedFrame) o;
0570: NamedFrame.Event event = (NamedFrame.Event) arg;
0571: if (event.eventType == NamedFrame.Event.ADDED) {
0572: JMenuItem menuItem = new JMenuItem(event.title);
0573: titleToMenuItem.put(event.title, menuItem);
0574: menuItem.addActionListener(myActionListener);
0575: windowMenu.add(menuItem);
0576: // update experiment Controls, as the experiment's runnability
0577: // may have changed
0578: if ((event.title.indexOf(CONFIGURATION_BUILDER) != -1)
0579: || (event.title.indexOf(EXPERIMENT_BUILDER) != -1)
0580: || (event.title
0581: .indexOf(EXPERIMENT_CONTROLLER) != -1))
0582: enableCSMARTTools();
0583: } else if (event.eventType == NamedFrame.Event.REMOVED) {
0584: JMenuItem menuItem = (JMenuItem) titleToMenuItem
0585: .get(event.title);
0586: if (menuItem == null) {
0587: if (log.isWarnEnabled()) {
0588: log.warn("CSMART: No window menu item for "
0589: + event.title);
0590: }
0591: } else {
0592: windowMenu.remove(menuItem);
0593: titleToMenuItem.remove(event.title);
0594: }
0595: // update experiment Controls, as the experiment's runnability
0596: // may have changed
0597: if ((event.title.indexOf(CONFIGURATION_BUILDER) != -1)
0598: || (event.title.indexOf(EXPERIMENT_BUILDER) != -1)
0599: || (event.title
0600: .indexOf(EXPERIMENT_CONTROLLER) != -1))
0601: enableCSMARTTools();
0602: } else if (event.eventType == NamedFrame.Event.CHANGED) {
0603: JMenuItem menuItem = (JMenuItem) titleToMenuItem
0604: .get(event.prevTitle);
0605: if (menuItem == null) {
0606: if (log.isWarnEnabled()) {
0607: log.warn("CSMART: No window menu item for "
0608: + event.title);
0609: }
0610: } else {
0611: windowMenu.remove(menuItem);
0612: titleToMenuItem.remove(event.prevTitle);
0613: JMenuItem newMenuItem = new JMenuItem(
0614: event.title);
0615: titleToMenuItem.put(event.title, newMenuItem);
0616: newMenuItem.addActionListener(myActionListener);
0617: windowMenu.add(newMenuItem);
0618: }
0619: }
0620: }
0621: }
0622: };
0623:
0624: /**
0625: * Run configuration builder.
0626: * If this is called on an experiment, copy the experiment,
0627: * create a new society (SocietyCDataComponent),
0628: * remove the society and any recipes from the experiment copy,
0629: * and put the new society in the experiment.
0630: * @param cc the component to configure
0631: * @param alwaysNew if true create a new configuration builder, otherwise re-use existing one
0632: */
0633: protected void runBuilder(ModifiableComponent cc, boolean alwaysNew) {
0634: // note that cc is guaranteed non-null when this is called
0635: if (cc instanceof Experiment) {
0636: runBuilderOnExperiment((Experiment) cc);
0637: return;
0638: }
0639:
0640: ModifiableComponent originalComponent = null;
0641: Experiment experiment = null;
0642: DefaultMutableTreeNode selectedNode = organizer
0643: .getSelectedNode();
0644: DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) selectedNode
0645: .getParent();
0646: if (parentNode.getUserObject() != null
0647: && parentNode.getUserObject() instanceof Experiment) {
0648: experiment = (Experiment) parentNode.getUserObject();
0649: // if configuring a component in an experiment,
0650: // copy the component, so it's modified only in the experiment
0651: if (cc instanceof SocietyComponent) {
0652: SocietyComponent society = (SocietyComponent) cc;
0653: String newName = organizer.generateSocietyName(society
0654: .getSocietyName(), false);
0655: if (newName == null)
0656: return;
0657: SocietyComponent societyCopy = (SocietyComponent) society
0658: .copy(newName);
0659: originalComponent = cc;
0660: cc = societyCopy;
0661: } else if (cc instanceof RecipeComponent) {
0662: RecipeComponent recipe = (RecipeComponent) cc;
0663: String newName = organizer.generateRecipeName(recipe
0664: .getRecipeName(), false);
0665: if (newName == null)
0666: return;
0667: RecipeComponent recipeCopy = (RecipeComponent) recipe
0668: .copy(newName);
0669: originalComponent = cc;
0670: cc = recipeCopy;
0671: } else
0672: return; // unknown component in experiment
0673: }
0674: cc.setEditable(false);
0675: if (originalComponent != null)
0676: originalComponent.setEditable(false);
0677: JFrame tool = new PropertyBuilder(this , cc, originalComponent,
0678: experiment);
0679: addTool(CONFIGURATION_BUILDER, cc.getShortName(), tool);
0680: }
0681:
0682: private void runBuilderOnExperiment(Experiment experiment) {
0683: Thread configureThread = null;
0684: experimentToEdit = null;
0685: configureThread = new ConfigureThread(experiment);
0686: // TODO: this isn't blocking mouse events on the toolbar; it's deferring them
0687: GUIUtils.timeConsumingTaskStart(csmart);
0688: try {
0689: configureThread.start();
0690: } catch (RuntimeException re) {
0691: if (log.isErrorEnabled()) {
0692: log.error("Runtime exception creating experiment", re);
0693: }
0694: }
0695: // wait for the above to finish, and then edit the new society
0696: if (configureThread != null) {
0697: try {
0698: configureThread.join();
0699: } catch (InterruptedException ie) {
0700: if (log.isErrorEnabled()) {
0701: log
0702: .error(
0703: "Interrupted exception creating experiment",
0704: ie);
0705: }
0706: }
0707: if (experimentToEdit == null)
0708: return;
0709: organizer.addExperimentAndComponentsToWorkspace(
0710: experimentToEdit,
0711: (DefaultMutableTreeNode) organizer
0712: .getSelectedNode().getParent());
0713: SocietyComponent originalSociety = experimentToEdit
0714: .getSocietyComponent();
0715: String copyName = organizer.generateSocietyName(
0716: originalSociety.getSocietyName(), false);
0717: if (copyName == null) {
0718: GUIUtils.timeConsumingTaskEnd(csmart);
0719: return;
0720: }
0721: SocietyComponent societyCopy = (SocietyComponent) originalSociety
0722: .copy(copyName);
0723: societyCopy.setEditable(false);
0724: originalSociety.setEditable(false);
0725: JFrame tool = new PropertyBuilder(csmart, societyCopy,
0726: originalSociety, experimentToEdit);
0727: addTool(CONFIGURATION_BUILDER, societyCopy.getShortName(),
0728: tool);
0729: GUIUtils.timeConsumingTaskEnd(csmart);
0730: }
0731: }
0732:
0733: /**
0734: * Run the experiment builder to edit an experiment.
0735: * @param experiment the experiment to edit
0736: * @param alwaysNew true to create a new <code>ExperimentBuilder</code>; false to re-use an existing one
0737: */
0738: protected void runExperimentBuilder(Experiment experiment,
0739: boolean alwaysNew) {
0740: // // if this experiment is being edited, then don't edit again
0741: // if (isExperimentInEditor(experiment))
0742: // return;
0743: // if (!experiment.isEditable()) {
0744: // // otherwise editability can be overwritten
0745: // Object[] options = { "Edit", "View", "Copy", "Cancel" };
0746: // experiment = queryUser(experiment, options);
0747: // if (experiment == null)
0748: // return;
0749: // }
0750: // gray out the children of the experiment in the tree
0751: // to avoid confusion while editing the experiment
0752: organizer.removeChildren(experiment);
0753: JFrame tool = new ExperimentBuilder(this , experiment);
0754: addTool(EXPERIMENT_BUILDER, experiment.getExperimentName(),
0755: tool);
0756: }
0757:
0758: // private Experiment queryUser(Experiment experiment,
0759: // Object[] options) {
0760: // int result =
0761: // JOptionPane.showOptionDialog(this,
0762: // experiment.getShortName() +
0763: // " is not editable",
0764: // "Experiment Not Editable",
0765: // JOptionPane.DEFAULT_OPTION,
0766: // JOptionPane.WARNING_MESSAGE,
0767: // null,
0768: // options,
0769: // options[0]);
0770: // if (options[result].equals("Edit"))
0771: // // edit it anyway
0772: // experiment.setEditable(true);
0773: // else if (options[result].equals("Copy"))
0774: // // copy it
0775: // experiment = organizer.copyExperiment(experiment, true);
0776: // else if (options[result].equals("Cancel"))
0777: // // user cancelled
0778: // return null;
0779: // return experiment;
0780: // }
0781:
0782: /**
0783: * Run the specified experiment. The experiment must be runnable.
0784: * @param experiment the experiment to run
0785: */
0786: protected void runConsole(Experiment experiment) {
0787: JFrame tool = new CSMARTConsoleView(this , experiment);
0788: String s = "";
0789: if (experiment != null)
0790: s = experiment.getExperimentName();
0791: addTool(EXPERIMENT_CONTROLLER, s, tool);
0792: }
0793:
0794: /**
0795: * Run the Society Monitor tool.
0796: */
0797: protected void runMonitor() {
0798: Experiment runningExperiment = null;
0799: String name = "";
0800: if (runningExperiments.size() > 0) {
0801: runningExperiment = (Experiment) runningExperiments.get(0);
0802: name = runningExperiment.getExperimentName();
0803: }
0804: JFrame tool = new CSMARTUL(this , runningExperiment);
0805: addTool(SOCIETY_MONITOR, name, tool);
0806: }
0807:
0808: /**
0809: * Run the Performance Analyzer tool.
0810: * @param experiment the experiment to analyze
0811: */
0812: protected void runAnalyzer(Experiment experiment) {
0813: JFrame tool = new Analyzer(this , experiment);
0814: addTool(PERFORMANCE_ANALYZER, experiment.getExperimentName(),
0815: tool);
0816: }
0817:
0818: protected void runAnalyzer() {
0819: JFrame tool = new Analyzer(this );
0820: addTool(PERFORMANCE_ANALYZER, "", tool);
0821: }
0822:
0823: /**
0824: * Add the tool to the menu of windows CSMART maintains,
0825: * and set up a listener to update the menu when the tool is exited.
0826: */
0827: private void addTool(String toolName, String docName, JFrame tool) {
0828: NamedFrame.getNamedFrame().addFrame(
0829: toolName
0830: + ((docName != null && !docName.trim().equals(
0831: "")) ? (": " + docName) : ""), tool);
0832: final boolean isConsole = (toolName == EXPERIMENT_CONTROLLER);
0833: tool
0834: .setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
0835:
0836: tool.addWindowListener(new WindowAdapter() {
0837: public void windowClosing(WindowEvent e) {
0838: JFrame frameArg = (JFrame) e.getWindow();
0839: if (!frameArg.getGlassPane().isVisible()) {
0840: // If user hit cancel in exit dialog in console,
0841: // then don't close the window
0842: if (isConsole
0843: && ((CSMARTConsoleView) frameArg).dontClose)
0844: return;
0845: NamedFrame.getNamedFrame().removeFrame(frameArg);
0846: // Next line can cause NPE in Container.removeNotify(line 1878)
0847: // Is there some test we can/should do on the JFrame before calling?
0848: try {
0849: frameArg.dispose();
0850: //frameArg = null;
0851: } catch (NullPointerException npe) {
0852: if (log.isWarnEnabled())
0853: log.warn(
0854: "Bug 1439: Was a drop-down list open? Using: "
0855: + writeDebug(), npe);
0856: }
0857: }
0858: }
0859: });
0860: }
0861:
0862: /**
0863: * Determine if an experiment is being edited in the ExperimentBuilder.
0864: * @param experiment the experiment
0865: * @return true if experiment is in the ExperimentBuilder
0866: */
0867: protected static boolean isExperimentInEditor(Experiment experiment) {
0868: String s = EXPERIMENT_BUILDER + ": "
0869: + experiment.getExperimentName();
0870: if (NamedFrame.getNamedFrame().getFrame(s) != null)
0871: return true;
0872: else
0873: return false;
0874: }
0875:
0876: /**
0877: * Determine if an experiment is in the Console.
0878: * @param experiment the experiment name
0879: * @return true if experiment is in the Console
0880: */
0881: protected static boolean isExperimentInConsole(Experiment experiment) {
0882: String s = EXPERIMENT_CONTROLLER + ": "
0883: + experiment.getExperimentName();
0884: if (NamedFrame.getNamedFrame().getFrame(s) != null)
0885: return true;
0886: else
0887: return false;
0888: }
0889:
0890: /**
0891: * Determine if a recipe is being edited in the ConfigurationBuilder.
0892: * @param recipe the recipe
0893: * @return true if recipe is in the ConfigurationBuilder
0894: */
0895: protected static boolean isRecipeInEditor(RecipeComponent recipe) {
0896: String s = CONFIGURATION_BUILDER + ": "
0897: + recipe.getRecipeName();
0898: if (NamedFrame.getNamedFrame().getFrame(s) != null)
0899: return true;
0900: else
0901: return false;
0902: }
0903:
0904: /**
0905: * Determine if a society is being edited in the ConfigurationBuilder.
0906: * @param society the society
0907: * @return true if society is in the ConfigurationBuilder
0908: */
0909: protected static boolean isSocietyInEditor(SocietyComponent society) {
0910: String s = CONFIGURATION_BUILDER + ": "
0911: + society.getShortName();
0912: if (NamedFrame.getNamedFrame().getFrame(s) != null)
0913: return true;
0914: else
0915: return false;
0916: }
0917:
0918: private void newWorkspace() {
0919: if (workspaceFileChooser == null) {
0920: workspaceFileChooser = new JFileChooser(System
0921: .getProperty("org.cougaar.install.path"));
0922: workspaceFileChooser
0923: .setDialogTitle("Select workspace file");
0924: String[] filters = { "bin" };
0925: ExtensionFileFilter filter = new ExtensionFileFilter(
0926: filters, "workspace file");
0927: workspaceFileChooser.addChoosableFileFilter(filter);
0928: }
0929: if (workspaceFileChooser.showOpenDialog(this ) != JFileChooser.APPROVE_OPTION)
0930: return;
0931: File file = workspaceFileChooser.getSelectedFile();
0932: if (file == null)
0933: return;
0934: // FIXME: Test it is writable / readable?
0935: organizer.exitAllowed();
0936: getContentPane().remove(organizer);
0937: organizer = new Organizer(this , file.getPath());
0938: initDisplay();
0939: getContentPane().add("Center", organizer);
0940: validate();
0941: }
0942:
0943: private static String getResultDirName() {
0944: String resultDirName = ".";
0945: try {
0946: resultDirName = System
0947: .getProperty("org.cougaar.install.path");
0948: } catch (RuntimeException e) {
0949: // just use current directory
0950: resultDirName = ".";
0951: }
0952: return resultDirName;
0953: }
0954:
0955: private static File initResultDir() {
0956: return new File(getResultDirName() + File.separatorChar
0957: + "results");
0958: }
0959:
0960: /**
0961: * Set the directory in which to store the metrics file.
0962: * Displays a file chooser, initted
0963: * to the cougaar install path, for the user to choose a directory.
0964: */
0965: private void setResultDir() {
0966: JFileChooser chooser = new JFileChooser(getResultDirName());
0967: chooser.setDialogTitle("Select directory for results");
0968: chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
0969: chooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
0970: public boolean accept(File f) {
0971: return f.isDirectory();
0972: }
0973:
0974: public String getDescription() {
0975: return "All Directories";
0976: }
0977: });
0978: int result = chooser.showDialog(this ,
0979: "Select Results Directory");
0980: if (result != JFileChooser.APPROVE_OPTION)
0981: return;
0982: File res = chooser.getSelectedFile();
0983:
0984: if (res == null || !res.exists())
0985: return;
0986:
0987: resultDir = chooser.getSelectedFile();
0988: }
0989:
0990: /**
0991: * Set the new global result file. Used when reading a workspace file.
0992: **/
0993: public void setResultFile(String fileName) {
0994: if (fileName == null)
0995: return;
0996: resultDir = new File(fileName);
0997: }
0998:
0999: /**
1000: * Return directory in which to store results.
1001: * @return the directory
1002: */
1003: public static File getResultDir() {
1004: if (resultDir == null) {
1005: resultDir = initResultDir();
1006: }
1007: return resultDir;
1008: }
1009:
1010: public static void displayURL(String s) {
1011: URL help = CSMART.class.getResource(s);
1012: if (help != null)
1013: Browser.setPage(help);
1014: }
1015:
1016: /**
1017: * Start up CSMART main UI. <br>
1018: * If <code>org.cougaar.useBootstrapper</code> is set false,
1019: * use CLASSPATH to find classes as normal.<br>
1020: * Otherwise, use the Cougaar Bootstrapper to search the
1021: * Classpath + CIP/lib, /plugins, /sys, etc.
1022: **/
1023: public static void main(String[] args) {
1024: if ("true".equals(System.getProperty(
1025: "org.cougaar.useBootstrapper", "true"))) {
1026: Bootstrapper.launch(CSMART.class.getName(), args);
1027: } else {
1028: launch(args);
1029: }
1030: }
1031:
1032: public static void launch(String[] args) {
1033: new CSMART();
1034: }
1035:
1036: /**
1037: * Write out basic info about this run of CSMART
1038: * to help with debugging.
1039: *
1040: * @return a <code>String</code> debug string for logging
1041: */
1042: public static String writeDebug() {
1043: // Cougaar version, build info
1044: StringBuffer result = new StringBuffer();
1045: String version = null;
1046: long buildtime = 0;
1047: String repositoryTag = null;
1048: boolean repositoryModified = false;
1049: long repositoryTime = -1;
1050: try {
1051: Class vc = Class
1052: .forName("org.cougaar.tools.csmart.Version");
1053: Field vf = vc.getField("version");
1054: Field bf = vc.getField("buildTime");
1055: version = (String) vf.get(null);
1056: buildtime = bf.getLong(null);
1057: Field tf = vc.getField("repositoryTag");
1058: Field rmf = vc.getField("repositoryModified");
1059: Field rtf = vc.getField("repositoryTime");
1060: repositoryTag = (String) tf.get(null);
1061: repositoryModified = rmf.getBoolean(null);
1062: repositoryTime = rtf.getLong(null);
1063: } catch (Exception e) {
1064: }
1065:
1066: result.append("CSMART ");
1067: if (version == null) {
1068: result.append("(unknown version)\n");
1069: } else {
1070: result.append(version
1071: + " built on "
1072: + ((buildtime > 0) ? (new Date(buildtime))
1073: .toString() : "(unknown time)") + "\n");
1074: // add repositoryTag, repositoryModified, repositoryTime?
1075: result
1076: .append("Repository: "
1077: + ((repositoryTag != null) ? (repositoryTag + (repositoryModified ? " (modified)"
1078: : ""))
1079: : "(unknown tag)")
1080: + " on "
1081: + ((repositoryTime > 0) ? ((new Date(
1082: repositoryTime)).toString())
1083: : "(unknown time)") + "\n");
1084: }
1085:
1086: version = null;
1087: try {
1088: Class vc = Class.forName("org.cougaar.Version");
1089: Field vf = vc.getField("version");
1090: Field bf = vc.getField("buildTime");
1091: version = (String) vf.get(null);
1092: buildtime = bf.getLong(null);
1093: Field tf = vc.getField("repositoryTag");
1094: Field rmf = vc.getField("repositoryModified");
1095: Field rtf = vc.getField("repositoryTime");
1096: repositoryTag = (String) tf.get(null);
1097: repositoryModified = rmf.getBoolean(null);
1098: repositoryTime = rtf.getLong(null);
1099: } catch (Exception e) {
1100: }
1101:
1102: result.append("Based on Cougaar core ");
1103: if (version == null) {
1104: result.append("(unknown version)\n");
1105: } else {
1106: result.append(version
1107: + " built on "
1108: + ((buildtime > 0) ? (new Date(buildtime))
1109: .toString() : "(unknown time)") + "\n");
1110: // add repositoryTag, repositoryModified, repositoryTime?
1111: result
1112: .append("Repository: "
1113: + ((repositoryTag != null) ? (repositoryTag + (repositoryModified ? " (modified)"
1114: : ""))
1115: : "(unknown tag)")
1116: + " on "
1117: + ((repositoryTime > 0) ? ((new Date(
1118: repositoryTime)).toString())
1119: : "(unknown time)") + "\n");
1120: }
1121:
1122: String vminfo = System.getProperty("java.vm.info");
1123: String vmv = System.getProperty("java.vm.version");
1124: result.append("VM: JDK " + vmv + " (" + vminfo + ")\n");
1125: String os = System.getProperty("os.name");
1126: String osv = System.getProperty("os.version");
1127: result.append("OS: " + os + " (" + osv + ")\n");
1128:
1129: // Some properties valus: install.path, config.path,
1130: result
1131: .append("org.cougaar.tools.csmart.doWorkspace="
1132: + System
1133: .getProperty("org.cougaar.tools.csmart.doWorkspace")
1134: + "\n");
1135: result.append("org.cougaar.config.path="
1136: + System.getProperty("org.cougaar.config.path") + "\n");
1137: result
1138: .append("org.cougaar.install.path="
1139: + System
1140: .getProperty("org.cougaar.install.path")
1141: + "\n");
1142: // result.append("CSMART configuration DB (org.cougaar.configuration.database)=" + System.getProperty("org.cougaar.configuration.database") + "\n");
1143: // dbMode, isMySQL
1144: // What tools are open
1145: // whats loaded in the workspace
1146: // if (experimentToEdit != null) {
1147: // result.append("Working with experiment " + experimentToEdit.getFullName().toString() + " (ID: " + experimentToEdit.getExperimentID() + ", trial: " + experimentToEdit.getTrialID() + ") which says to isEditable: " + experimentToEdit.isEditable() + " and to isEditInProgress: " + experimentToEdit.isEditInProgress() + " and to isModified: " + experimentToEdit.isModified() + " and to isRunInProgress: " + experimentToEdit.isRunInProgress() + " and to isRunnable: " + experimentToEdit.isRunnable() + "\n");
1148: // SocietyComponent soc = experimentToEdit.getSocietyComponent();
1149: // if (soc != null) {
1150: // result.append(" made of society " + soc.getFullName() + " (ID: " + soc.getAssemblyId() + ") whic says to isModified: " + soc.isModified() + " and to isRunning: " + soc.isRunning() + " and to isEditable: " + soc.isEditable() + "\n");
1151: // }
1152: // result.append(" and which also has " + experimentToEdit.getRecipeComponentCount() + " recipes\n");
1153: // }
1154: // results directory setting
1155: // but probably not the cougaar.rc contents
1156:
1157: return result.toString();
1158: }
1159:
1160: // Logging Methods
1161:
1162: private static LoggerFactory lf;
1163: static {
1164: lf = LoggerFactory.getInstance();
1165:
1166: Properties defaults = new Properties();
1167: defaults.setProperty("log4j.rootCategory", "WARN, A1");
1168: defaults.setProperty("log4j.appender.A1",
1169: "org.apache.log4j.ConsoleAppender");
1170: defaults.setProperty("log4j.appender.A1.Target", "System.out");
1171: defaults.setProperty("log4j.appender.A1.layout",
1172: "org.apache.log4j.PatternLayout");
1173: defaults.setProperty(
1174: "log4j.appender.A1.layout.ConversionPattern",
1175: "%d{ABSOLUTE} %-5p [ %t] - %m%n");
1176:
1177: Properties props = new Properties(defaults);
1178: // Get the debug file.
1179: ConfigFinder cf = ConfigFinder.getInstance("csmart");
1180: try {
1181: props.load(new FileInputStream(cf
1182: .locateFile("debug.properties")));
1183: } catch (Exception e) {
1184: System.err
1185: .println("CSMART.java Could not read debug.properties file, using defaults.");
1186: }
1187:
1188: lf.configure(props);
1189: }
1190:
1191: /** Keep loggers as flyweights **/
1192: private static final HashMap _loggers = new HashMap(97);
1193:
1194: /**
1195: * Used to grab an instance of the Logger
1196: *
1197: * @param name the requestor
1198: * @return a <code>Logger</code> value
1199: */
1200: public static Logger createLogger(String name) {
1201: synchronized (_loggers) {
1202: Logger l = (Logger) _loggers.get(name);
1203: if (l == null) {
1204: l = lf.createLogger(name);
1205: _loggers.put(name, l);
1206: }
1207: return l;
1208: }
1209: }
1210:
1211: private void createLog() {
1212: log = CSMART.createLogger(this .getClass().getName());
1213: }
1214:
1215: private void readObject(ObjectInputStream ois) throws IOException,
1216: ClassNotFoundException {
1217: ois.defaultReadObject();
1218: createLog();
1219: }
1220:
1221: // Configure an experiment by combining its societies and recipes
1222: // into a single society.
1223: class ConfigureThread extends Thread {
1224: Experiment experiment;
1225:
1226: ConfigureThread(Experiment experiment) {
1227: this .experiment = experiment;
1228: }
1229:
1230: public void run() {
1231: // copy the original experiment and put the copy in the workspace
1232: String newName = organizer
1233: .generateExperimentName(experiment
1234: .getExperimentName());
1235: experimentToEdit = (DBExperiment) experiment.copy(newName);
1236: if (experimentToEdit == null) {
1237: return;
1238: }
1239: // remove all the components from the copy
1240: SocietyComponent sc = experimentToEdit
1241: .getSocietyComponent();
1242: if (sc != null)
1243: experimentToEdit.removeComponent(sc);
1244: RecipeComponent[] recipes = experimentToEdit
1245: .getRecipeComponents();
1246: for (int i = 0; i < recipes.length; i++)
1247: experimentToEdit.removeRecipeComponent(recipes[i]);
1248: // create a new society based on the society component data
1249: // in the original experiment
1250: ComponentData cdata = experiment.getSocietyComponentData();
1251: newName = organizer.generateSocietyName(cdata.getName());
1252: cdata.setName(newName);
1253: SocietyComponent newSociety = new SocietyCDataComponent(
1254: cdata, (experiment.getSocietyComponent())
1255: .getAssemblyId());
1256: newSociety.initProperties();
1257: // Save this new society
1258: newSociety.saveToDatabase();
1259: // put the new society in the copy of the experiment
1260: experimentToEdit.addSocietyComponent(newSociety);
1261: }
1262: }
1263:
1264: }
|