Source Code Cross Referenced for ExperimentBase.java in  » Science » Cougaar12_4 » org » cougaar » tools » csmart » experiment » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Science » Cougaar12_4 » org.cougaar.tools.csmart.experiment 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* 
0002:         * <copyright>
0003:         *  
0004:         *  Copyright 2003-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:        package org.cougaar.tools.csmart.experiment;
0027:
0028:        import org.cougaar.core.agent.SimpleAgent;
0029:        import org.cougaar.core.node.Node;
0030:        import org.cougaar.tools.csmart.core.cdata.AgentComponentData;
0031:        import org.cougaar.tools.csmart.core.cdata.ComponentData;
0032:        import org.cougaar.tools.csmart.core.cdata.GenericComponentData;
0033:        import org.cougaar.tools.csmart.core.property.BaseComponent;
0034:        import org.cougaar.tools.csmart.core.property.ConfigurableComponent;
0035:        import org.cougaar.tools.csmart.core.property.ConfigurableComponentListener;
0036:        import org.cougaar.tools.csmart.core.property.ModifiableComponent;
0037:        import org.cougaar.tools.csmart.core.property.ModifiableConfigurableComponent;
0038:        import org.cougaar.tools.csmart.core.property.ModificationEvent;
0039:        import org.cougaar.tools.csmart.core.property.ModificationListener;
0040:        import org.cougaar.tools.csmart.core.property.Property;
0041:        import org.cougaar.tools.csmart.core.db.DBUtils;
0042:        import org.cougaar.tools.csmart.core.db.DBConflictHandler;
0043:        import org.cougaar.tools.csmart.recipe.RecipeBase;
0044:        import org.cougaar.tools.csmart.recipe.RecipeComponent;
0045:        import org.cougaar.tools.csmart.society.AgentBase;
0046:        import org.cougaar.tools.csmart.society.AgentComponent;
0047:        import org.cougaar.tools.csmart.society.SocietyBase;
0048:        import org.cougaar.tools.csmart.society.SocietyComponent;
0049:        import org.cougaar.tools.csmart.ui.viewer.CSMART;
0050:        import org.cougaar.tools.csmart.util.ReadOnlyProperties;
0051:        import org.cougaar.util.log.Logger;
0052:
0053:        import javax.swing.*;
0054:        import java.io.File;
0055:        import java.io.IOException;
0056:        import java.io.ObjectInputStream;
0057:        import java.io.OutputStream;
0058:        import java.net.URL;
0059:        import java.util.*;
0060:        import java.util.List;
0061:        import java.awt.*;
0062:
0063:        /**
0064:         * org.cougaar.tools.csmart.experiment
0065:         *
0066:         */
0067:        public abstract class ExperimentBase extends
0068:                ModifiableConfigurableComponent implements  Experiment {
0069:            private static final String DESCRIPTION_RESOURCE_NAME = "description.html";
0070:            // Member Variables
0071:            private SocietyComponent societyComponent = null;
0072:            private final List hosts = new ArrayList();
0073:            private final List nodes = new ArrayList();
0074:            final List recipes = new ArrayList();
0075:            ReadOnlyProperties defaultNodeArguments;
0076:            private File resultDirectory; // where to store results
0077:            private transient boolean editInProgress = false;
0078:            private transient boolean runInProgress = false;
0079:            ComponentData completeSociety = null;
0080:            private String expID = null; // An Experiment has a single ExpID
0081:            private String trialID = null;
0082:
0083:            // modification event
0084:            private static final int EXPERIMENT_SAVED = 1;
0085:            transient LeafOnlyConfigWriter configWriter = null;
0086:            transient Logger log;
0087:            // Mark whether the experiment has been modified
0088:            // and should be saved
0089:            boolean modified = true;
0090:            // add an observer to my arguments
0091:            // if these arguments are modified, then
0092:            // notify listeners on the experiment that it's modified
0093:            private transient Observer myObserver = null;
0094:            /**
0095:             * Create a modification listener, which is registered on
0096:             * all the experiment components. If any components
0097:             * are modified, then mark this experiment as modified,
0098:             * and fire a modification event to the experiment's
0099:             * modification listeners.
0100:             * Checks for modification event being EXPERIMENT_SAVED
0101:             * in which case, it does not mark the experiment modified.
0102:             */
0103:            private final ModificationListener myModificationListener = new MyModificationListener();
0104:
0105:            // The assembly holding community info for this Experiment.
0106:            private String commAsb = null;
0107:
0108:            public ExperimentBase(String name) {
0109:                super (name);
0110:            }
0111:
0112:            public ExperimentBase(String name, String expID, String trialID) {
0113:                super (name);
0114:                this .expID = expID;
0115:                this .trialID = trialID;
0116:            }
0117:
0118:            final void createLogger() {
0119:                log = CSMART.createLogger(this .getClass().getName());
0120:            }
0121:
0122:            final void createObserver() {
0123:                if (myObserver == null) {
0124:                    myObserver = new Observer() {
0125:                        public void update(final Observable o, final Object arg) {
0126:                            fireModification();
0127:                        }
0128:                    };
0129:                    defaultNodeArguments.addObserver(myObserver);
0130:                }
0131:            }
0132:
0133:            /**
0134:             * Adds a <code>societyComponent</code> to this Experiment.
0135:             *
0136:             * @param sc
0137:             * @exception java.lang.IllegalArgumentException if an error occurs
0138:             */
0139:            public final void addSocietyComponent(SocietyComponent sc)
0140:                    throws IllegalArgumentException {
0141:                if (this .societyComponent == null) {
0142:                    setSocietyComponent(sc);
0143:                } else {
0144:                    throw new IllegalArgumentException(
0145:                            "Already have a societyComponent in experiment "
0146:                                    + this );
0147:                }
0148:            }
0149:
0150:            /**
0151:             * Removes the <code>SocietyComponent</code> from this experiment
0152:             *
0153:             */
0154:            public final void removeSocietyComponent() {
0155:                if (this .societyComponent == null)
0156:                    return;
0157:                removeListeners((ModifiableConfigurableComponent) societyComponent);
0158:                this .societyComponent = null;
0159:                fireModification();
0160:            }
0161:
0162:            /**
0163:             * Returns the total number of Societies in this experiment.
0164:             * Since experiments can only have 1 society, this returns
0165:             * a 0 or 1 value.
0166:             *
0167:             * @return an <code>int</code> value
0168:             */
0169:            public final int getSocietyComponentCount() {
0170:                return (this .societyComponent == null ? 0 : 1);
0171:            }
0172:
0173:            /**
0174:             * Return the <code>SocietyComponent</code>
0175:             *
0176:             * @return a <code>SocietyComponent</code> value
0177:             */
0178:            public final SocietyComponent getSocietyComponent() {
0179:                return this .societyComponent;
0180:            }
0181:
0182:            final void setSocietyComponent(SocietyComponent society) {
0183:                if (this .societyComponent != null)
0184:                    removeSocietyComponent();
0185:                this .societyComponent = society;
0186:                installListeners((ModifiableConfigurableComponent) society);
0187:                fireModification();
0188:            }
0189:
0190:            private void installListeners(
0191:                    ModifiableConfigurableComponent component) {
0192:                component.addModificationListener(myModificationListener);
0193:            }
0194:
0195:            private void removeListeners(
0196:                    ModifiableConfigurableComponent component) {
0197:                component.removeModificationListener(myModificationListener);
0198:            }
0199:
0200:            /**
0201:             * Adds an array of <code>RecipeComponent</code>s to this
0202:             * experiment.
0203:             *
0204:             * @param newRecipes RecipeComponents
0205:             */
0206:            public final void setRecipeComponents(RecipeComponent[] newRecipes) {
0207:                for (int i = 0; i < recipes.size(); i++)
0208:                    removeListeners((ModifiableConfigurableComponent) recipes
0209:                            .get(i));
0210:                recipes.clear();
0211:                // FIXME: Remove duplicates?
0212:                for (int i = 0; i < newRecipes.length; i++)
0213:                    installListeners((ModifiableConfigurableComponent) newRecipes[i]);
0214:                recipes.addAll(Arrays.asList(newRecipes));
0215:                fireModification();
0216:            }
0217:
0218:            /**
0219:             * Adds a <code>RecipeComponent</code> to this Experiment
0220:             *
0221:             * @param recipe - <code>RecipeComponent</code> to add to Experiment
0222:             */
0223:            public final void addRecipeComponent(RecipeComponent recipe)
0224:                    throws IllegalArgumentException {
0225:                if (!recipes.contains(recipe)) {
0226:                    recipes.add(recipe);
0227:                    installListeners((ModifiableConfigurableComponent) recipe);
0228:                    fireModification();
0229:                } else {
0230:                    throw new IllegalArgumentException(
0231:                            "Recipe already exists in experiment");
0232:                }
0233:            }
0234:
0235:            /**
0236:             * Removes the specified <code>RecipeComponent</code>.
0237:             *
0238:             * @param recipe
0239:             */
0240:            public final void removeRecipeComponent(RecipeComponent recipe) {
0241:                if (!this .recipes.contains(recipe))
0242:                    return;
0243:                this .recipes.remove(recipe);
0244:                removeListeners((ModifiableConfigurableComponent) recipe);
0245:                fireModification();
0246:            }
0247:
0248:            /**
0249:             * Returns the total number of recipes in this experiment.
0250:             *
0251:             * @return an <code>int</code> value
0252:             */
0253:            public final int getRecipeComponentCount() {
0254:                return this .recipes.size();
0255:            }
0256:
0257:            /**
0258:             * Gets a specific recipe based on Index.
0259:             *
0260:             * @param i
0261:             * @return a <code>RecipeComponent</code> value
0262:             * @exception java.lang.IndexOutOfBoundsException if an error occurs
0263:             */
0264:            public final RecipeComponent getRecipeComponent(int i)
0265:                    throws IndexOutOfBoundsException {
0266:                return (RecipeComponent) recipes.get(i);
0267:            }
0268:
0269:            /**
0270:             * Gets all <code>RecipeComponents</code> for this experiment.
0271:             *
0272:             * @return a <code>RecipeComponent[]</code> value
0273:             */
0274:            public final RecipeComponent[] getRecipeComponents() {
0275:                return (RecipeComponent[]) recipes
0276:                        .toArray(new RecipeComponent[recipes.size()]);
0277:            }
0278:
0279:            /**
0280:             * Adds a new component to this experiment.
0281:             * Currently only two Component Types are accepted:
0282:             * <br><code>SocietyComponent</code>
0283:             * <br><code>RecipeComponent</code>
0284:             *
0285:             * @param comp
0286:             * @exception java.lang.IllegalArgumentException if an error occurs
0287:             */
0288:            public final void addComponent(final ModifiableComponent comp)
0289:                    throws IllegalArgumentException {
0290:                if (comp instanceof  SocietyComponent) {
0291:                    try {
0292:                        addSocietyComponent((SocietyComponent) comp);
0293:                    } catch (IllegalArgumentException e) {
0294:                        if (log.isErrorEnabled()) {
0295:                            log.error("SocietyComponent already set");
0296:                        }
0297:                    }
0298:                } else if (comp instanceof  RecipeComponent) {
0299:                    addRecipeComponent((RecipeComponent) comp);
0300:                } else {
0301:                    throw new IllegalArgumentException(
0302:                            "Unsupported Component Type" + this );
0303:                }
0304:            }
0305:
0306:            /**
0307:             * Removes the given component from the Experiment.
0308:             * If the component is not supported, an exception
0309:             * is throw.
0310:             *
0311:             * @param comp
0312:             * @exception java.lang.IllegalArgumentException if an error occurs
0313:             */
0314:            public final void removeComponent(ModifiableComponent comp)
0315:                    throws IllegalArgumentException {
0316:                if (comp instanceof  SocietyComponent) {
0317:                    removeSocietyComponent();
0318:                } else if (comp instanceof  RecipeComponent) {
0319:                    removeRecipeComponent((RecipeComponent) comp);
0320:                } else {
0321:                    throw new IllegalArgumentException(
0322:                            "Unsupported Component Type");
0323:                }
0324:            }
0325:
0326:            /**
0327:             * Returns the total number of Components
0328:             * (Recipe and Society) in this experiment.
0329:             *
0330:             * @return an <code>int</code> value
0331:             */
0332:            public final int getComponentCount() {
0333:                return getSocietyComponentCount() + recipes.size();
0334:            }
0335:
0336:            /**
0337:             * @return a <code>ModifiableConfigurableComponent[]</code> array of
0338:             * all the components in the experiment
0339:             */
0340:            public final ModifiableComponent[] getComponentsAsArray() {
0341:                List comps = getComponents();
0342:                ModifiableComponent[] compArray = (ModifiableComponent[]) comps
0343:                        .toArray(new ModifiableComponent[comps.size()]);
0344:                return compArray;
0345:            }
0346:
0347:            /**
0348:             * Get all the recipes and the society.
0349:             * @return List list of all the components in the experiment
0350:             */
0351:            public final List getComponents() {
0352:                List comps = new ArrayList();
0353:                for (int i = 0; i < getRecipeComponentCount(); i++) {
0354:                    comps.add(getRecipeComponent(i));
0355:                }
0356:                if (getSocietyComponent() != null)
0357:                    comps.add(getSocietyComponent());
0358:                return comps;
0359:            }
0360:
0361:            /**
0362:             * Set run in progress.  Used by UI tools to indicate that an
0363:             * experiment is being run.  Note that this is distinct from
0364:             * setting the runnability flag, which indicates whether the experiment
0365:             * can ever be run.
0366:             * @param newRunInProgress
0367:             */
0368:            public final void setRunInProgress(boolean newRunInProgress) {
0369:                runInProgress = newRunInProgress;
0370:            }
0371:
0372:            /**
0373:             * Return whether or not experiment is being run.
0374:             * @return boolean whether or not experiment is being run
0375:             */
0376:            public final boolean isRunInProgress() {
0377:                return runInProgress;
0378:            }
0379:
0380:            /**
0381:             * Return whether or not experiment is runnable.  An experiment is runnable:
0382:             * if it has a host-node-agent mapping, and
0383:             * it has no unbound properties, and
0384:             * it's not being edited or run, and
0385:             * it's been saved in the database (i.e. the modified flag is false)
0386:             * @return whether or not an experiment is runnable
0387:             */
0388:            public final boolean isRunnable() {
0389:                if (!hasConfiguration() || modified)
0390:                    return false;
0391:                return !runInProgress; // allow user to run experiment they're editing
0392:            }
0393:
0394:            /**
0395:             * Set edit in progress.  Used by UI tools to indicate that an
0396:             * experiment is being edited.  Note that this is distinct from
0397:             * setting the editability flag, which indicates whether the experiment
0398:             * can ever be edited.
0399:             * @param newEditInProgress
0400:             */
0401:            public final void setEditInProgress(boolean newEditInProgress) {
0402:                editInProgress = newEditInProgress;
0403:            }
0404:
0405:            /**
0406:             * Return whether or not experiment is being edited.
0407:             * Note that the experiment may be viewed (but not edited) in an editor,
0408:             * even if this flag is not set.
0409:             * @return boolean whether or not experiment is being edited
0410:             */
0411:            public final boolean isEditInProgress() {
0412:                return editInProgress;
0413:            }
0414:
0415:            /**
0416:             * Stop after the current trial.
0417:             * This invokes experimentStopped.
0418:             */
0419:            public final void stop() {
0420:                // TODO: stop the experiment after the current trial
0421:                experimentStopped();
0422:            }
0423:
0424:            /**
0425:             * Notify listeners that experiment was terminated.
0426:             */
0427:            public final void experimentStopped() {
0428:                // Tell the Societies in the experiment they are no longer running?
0429:                if (societyComponent != null)
0430:                    societyComponent.setRunning(false);
0431:            }
0432:
0433:            /**
0434:             * Returns the Default Node Arguments
0435:             *
0436:             * @return a <code>Properties</code> object containing all default Node Args.
0437:             */
0438:            public final Properties getDefaultNodeArguments() {
0439:                return defaultNodeArguments;
0440:            }
0441:
0442:            public final File getResultDirectory() {
0443:                return resultDirectory;
0444:            }
0445:
0446:            public final void setResultDirectory(File resultDirectory) {
0447:                this .resultDirectory = resultDirectory;
0448:            }
0449:
0450:            /**
0451:             * Returns the Name of this Experiment
0452:             *
0453:             * @return a <code>String</code> value
0454:             */
0455:            public final String getExperimentName() {
0456:                return getShortName();
0457:            }
0458:
0459:            /**
0460:             * Returns the name of this component
0461:             *
0462:             * @return a <code>String</code> value
0463:             */
0464:            public final String toString() {
0465:                return this .getShortName();
0466:            }
0467:
0468:            /**
0469:             * Get the URL of the file that describes this experiment.
0470:             */
0471:            public final URL getDescription() {
0472:                return getClass().getResource(
0473:                        ExperimentBase.DESCRIPTION_RESOURCE_NAME);
0474:            }
0475:
0476:            public final void initProperties() {
0477:                // put all the properties in here
0478:                // the list of components are children
0479:                // the editability & runability are properties
0480:                // the hosts, trial, etc should all be properties
0481:                // then we wouldn't need the special copy mechanism
0482:                // (if all the sub-pieces were also components)
0483:            }
0484:
0485:            /**
0486:             * If the experiment was saved, let the listeners know,
0487:             * but don't mark our modified flag.
0488:             * If the society or any recipe was changed, tell the listeners that the
0489:             * experiment changed.
0490:             * If the society or recipe was saved, ignore this,
0491:             * as the experiment must still be saved.
0492:             */
0493:            private void notifyExperimentListeners(ModificationEvent e) {
0494:                if (e.getWhatChanged() == ExperimentBase.EXPERIMENT_SAVED) {
0495:                    super .fireModification();
0496:                    return;
0497:                }
0498:                if (e.getWhatChanged() == SocietyBase.SOCIETY_SAVED
0499:                        || e.getWhatChanged() == RecipeBase.RECIPE_SAVED)
0500:                    return;
0501:                // an experiment, society, or recipe was changed,
0502:                // mark this experiment as modified, and notify the listeners
0503:                fireModification();
0504:            }
0505:
0506:            public final void fireModification() {
0507:                modified = true;
0508:                super .fireModification();
0509:            }
0510:
0511:            private void addDefaultNodeArguments(ComponentData theSoc) {
0512:                Properties props = getDefaultNodeArguments();
0513:                for (Iterator i = props.entrySet().iterator(); i.hasNext();) {
0514:                    Map.Entry entry = (Map.Entry) i.next();
0515:                    String entVal = entry.getKey().toString();
0516:                    if (entVal.startsWith("-X")) {
0517:                        if (entry.getValue().equals("")
0518:                                || entry.getValue() == null) {
0519:                            theSoc.addParameter(entry.getKey());
0520:                        } else {
0521:                            theSoc.addParameter(entry.getKey() + "="
0522:                                    + entry.getValue());
0523:                        }
0524:                    } else if (entVal.startsWith("X:")) {
0525:                        theSoc.addParameter("-X" + entry.getKey() + "="
0526:                                + entry.getValue());
0527:                    } else {
0528:                        theSoc.addParameter("-D" + entry.getKey() + "="
0529:                                + entry.getValue());
0530:                    }
0531:                }
0532:            }
0533:
0534:            private void readObject(ObjectInputStream ois) throws IOException,
0535:                    ClassNotFoundException {
0536:                ois.defaultReadObject();
0537:                boolean temp = modified;
0538:                createLogger();
0539:                createObserver();
0540:                modified = temp;
0541:                editInProgress = false;
0542:                runInProgress = false;
0543:            }
0544:
0545:            // Put a bunch of Prop$ as parameters to the given component.
0546:            // even if the component itself doesnt think it wants it.
0547:            // This may cause problems for Agents, I think....
0548:            private void addPropertiesAsParameters(ComponentData cd,
0549:                    BaseComponent cp) {
0550:                for (Iterator it = cp.getProperties(); it.hasNext();) {
0551:                    Property prop = (Property) it.next();
0552:                    if (prop != null) {
0553:                        Object pvalue = prop.getValue();
0554:                        if (pvalue instanceof  String)
0555:                            // FIXME: by doing getName.last(), it flattens out any
0556:                            // internal hierarchy. Surely that makes
0557:                            // it impossible for these to be much use?
0558:                            // FIXME??
0559:                            cd.addParameter(PROP_PREFIX + prop.getName().last()
0560:                                    + "=" + pvalue);
0561:                    }
0562:                }
0563:            }
0564:
0565:            /**
0566:             * Adds the Given Host to the Experiment
0567:             * If the given host already exists, an exception is thrown.
0568:             *
0569:             * @param name - Name of the new Host
0570:             * @return a <code>HostComponent</code> for this host.
0571:             * @exception java.lang.IllegalArgumentException if an error occurs
0572:             */
0573:            public final HostComponent addHost(String name)
0574:                    throws IllegalArgumentException {
0575:                // FIXME: Maybe forbid localhost?
0576:                if (hostExists(name)) {
0577:                    throw new IllegalArgumentException(
0578:                            "Host Already Exists in Society");
0579:                } else {
0580:                    ExperimentHost eh = new ExperimentHost(name);
0581:                    eh.initProperties();
0582:                    return addHostComponent(eh);
0583:                }
0584:            }
0585:
0586:            /**
0587:             * Get the Hosts in this experiment.
0588:             * As a side effect, reconcile the Node/Agent mapping, if the experiment
0589:             * is marked as modified.
0590:             **/
0591:            public final HostComponent[] getHostComponents() {
0592:                if (modified) {
0593:                    reconcileNodeAgentMapping();
0594:                }
0595:                return (HostComponent[]) hosts.toArray(new HostComponent[hosts
0596:                        .size()]);
0597:            }
0598:
0599:            public final HostComponent[] getHostComponentsNoReconcile() {
0600:                return (HostComponent[]) hosts.toArray(new HostComponent[hosts
0601:                        .size()]);
0602:            }
0603:
0604:            /**
0605:             * Removes the given host from the experiment.
0606:             *
0607:             * @param hostComponent - <code>HostComponent</code> to remove.
0608:             */
0609:            public final void removeHost(HostComponent hostComponent) {
0610:                if (!hosts.contains(hostComponent))
0611:                    return;
0612:                hosts.remove(hostComponent);
0613:                // Let the host disassociate itself from nodes
0614:                ((ExperimentHost) hostComponent).dispose();
0615:                removeListeners((ExperimentHost) hostComponent);
0616:                fireModification();
0617:            }
0618:
0619:            /**
0620:             * Renames a host in the Experiment.
0621:             * If a host with the given name already exists, an exception
0622:             * is thrown.
0623:             *
0624:             * @param hostComponent - <code>HostComponent</code> of the host to be renamed.
0625:             * @param name - New Host Name
0626:             * @exception java.lang.IllegalArgumentException if an error occurs
0627:             */
0628:            public final void renameHost(HostComponent hostComponent,
0629:                    String name) throws IllegalArgumentException {
0630:                // Fixme: Maybe forbid localhost?
0631:                ExperimentHost testHost = new ExperimentHost(name);
0632:                if (hosts.contains(testHost)) {
0633:                    throw new IllegalArgumentException(
0634:                            "Host Already Exists in Society");
0635:                } else {
0636:                    if (hostComponent.getFullName().equals(name))
0637:                        return;
0638:                    hosts.remove(hostComponent);
0639:                    hostComponent.setName(name);
0640:                    hosts.add(hostComponent);
0641:                    fireModification();
0642:                }
0643:            }
0644:
0645:            /**
0646:             * Insure that we have a valid nameserver specification. There are
0647:             * several possibilities: If the default node nameserver argument
0648:             * has been set, try to make that be the name server. Parse out the
0649:             * host name part. Then scan all the hosts that have nodes
0650:             * and check to see if any host matches that specified by the
0651:             * default node nameserver argument. If it does, keep that
0652:             * nameserver. If it doesn't (or if there was no default node
0653:             * nameserver argument) then use the first host as the nameserver.
0654:             **/
0655:            public final void updateNameServerHostName() {
0656:                Properties defaultNodeArgs = getDefaultNodeArguments();
0657:                String oldNameServer = defaultNodeArgs
0658:                        .getProperty(Experiment.NAME_SERVER);
0659:                String newNameServer = null;
0660:                String dfltNameServer = null;
0661:                String nameServerHost = null;
0662:                if (oldNameServer != null) {
0663:                    dfltNameServer = oldNameServer;
0664:                    int colon = oldNameServer.indexOf(':');
0665:                    if (colon >= 0) {
0666:                        nameServerHost = oldNameServer.substring(0, colon);
0667:                    } else {
0668:                        nameServerHost = oldNameServer;
0669:                    }
0670:                }
0671:
0672:                // This does the NodeAgent reconcilation, if the experiment is modified
0673:                HostComponent[] hosts = getHostComponents();
0674:
0675:                hostLoop: for (int i = 0; i < hosts.length; i++) {
0676:                    NodeComponent[] nodes = hosts[i].getNodes();
0677:                    if (nodes.length == 0)
0678:                        continue;
0679:                    String this Host = hosts[i].getShortName();
0680:                    if (this Host.equals(nameServerHost)) {
0681:                        newNameServer = oldNameServer;
0682:                        break hostLoop; // Use existing nameserver definition
0683:                    }
0684:                    if (dfltNameServer == null) { // First host is default
0685:                        dfltNameServer = this Host + ":"
0686:                                + Experiment.NAME_SERVER_PORTS;
0687:                        if (oldNameServer == null) {
0688:                            break hostLoop; // Use dfltNameServer
0689:                        }
0690:                    }
0691:                }
0692:                if (newNameServer == null)
0693:                    newNameServer = dfltNameServer;
0694:
0695:                // set new server in all nodes
0696:                // Do not, again, reconcile NodeAgent mapping
0697:                // This method doesnt care, and if the experiment is modified, getHostComponents
0698:                // above already does it
0699:                NodeComponent[] nodes = getNodesInner(false);
0700:                for (int i = 0; i < nodes.length; i++) {
0701:                    NodeComponent node = nodes[i];
0702:                    Properties arguments = node.getArguments();
0703:                    // Insure no per-node override exists
0704:                    arguments.remove(Experiment.NAME_SERVER);
0705:                }
0706:                // Now install experiment-wide setting.
0707:                if (newNameServer != null) {
0708:                    defaultNodeArgs.setProperty(Experiment.NAME_SERVER,
0709:                            newNameServer);
0710:                }
0711:            }
0712:
0713:            private boolean hostExists(String name) {
0714:                return (hosts.contains(new ExperimentHost(name))) ? true
0715:                        : false;
0716:            }
0717:
0718:            private ExperimentHost addHostComponent(ExperimentHost host) {
0719:                if (hosts.contains(host))
0720:                    return host;
0721:                hosts.add(host);
0722:                installListeners(host);
0723:                fireModification();
0724:                return host;
0725:            }
0726:
0727:            /**
0728:             * Adds a new node to this experiment.  If the node
0729:             * currently exists, an exception is thrown.
0730:             *
0731:             * @param name - Name of new Node
0732:             * @return a <code>NodeComponent</code> value
0733:             * @exception java.lang.IllegalArgumentException if an error occurs
0734:             */
0735:            public final NodeComponent addNode(String name)
0736:                    throws IllegalArgumentException {
0737:                // if have an agent of this name, complain
0738:                if (!agentNameUnique(name)) {
0739:                    throw new IllegalArgumentException(
0740:                            "Name already in use (by a Node or Agent)");
0741:                } else if (!nodeExists(name)) {
0742:                    ExperimentNode result = new ExperimentNode(name, this );
0743:                    result.initProperties();
0744:                    addNodeComponent(result);
0745:                    return result;
0746:                } else {
0747:                    throw new IllegalArgumentException("Node already exists");
0748:                }
0749:            }
0750:
0751:            /**
0752:             * Removes the specified node from the Experiment
0753:             *
0754:             * @param nc <code>NodeComponent</code> of the Node to remove
0755:             */
0756:            public final void removeNode(NodeComponent nc) {
0757:                if (!nodes.contains(nc))
0758:                    return;
0759:                ExperimentNode expNode = (ExperimentNode) nc;
0760:                nodes.remove(nc);
0761:                expNode.dispose(); // Let the node disassociate itself from agents
0762:                removeListeners(expNode);
0763:                fireModification();
0764:            }
0765:
0766:            /**
0767:             * Renames a currently existing Node in this Experiment.
0768:             * If a node with the new name already exists, an exception is thrown
0769:             *
0770:             * @param nc - Node Component of the Node to change name
0771:             * @param name - New Name
0772:             * @exception java.lang.IllegalArgumentException if an error occurs
0773:             */
0774:            public final void renameNode(NodeComponent nc, String name)
0775:                    throws IllegalArgumentException {
0776:                if (nodeExists(name)) {
0777:                    throw new IllegalArgumentException(
0778:                            "Node name already exists!");
0779:                } else if (!agentNameUnique(name)) {
0780:                    throw new IllegalArgumentException("Name already in use");
0781:                } else {
0782:                    if (nc.getFullName().equals(name))
0783:                        return;
0784:                    nodes.remove(nc);
0785:                    nc.setName(name);
0786:                    nodes.add(nc);
0787:                    fireModification();
0788:                }
0789:            }
0790:
0791:            /**
0792:             * Get the Nodes in this Experiment.
0793:             * As a side-effect, ensure that the NameServer Host property
0794:             * is set correctly, and ensure that the Node/Agent mapping
0795:             * is up-to-date.
0796:             */
0797:            public final NodeComponent[] getNodeComponents() {
0798:                // Note that as a side-effect, this will also
0799:                // reconcile the node/agent mapping, if the experiment is modified
0800:                updateNameServerHostName(); // Be sure this is update-to-date
0801:
0802:                // Since we just did the reconciliation if the experiment is modified,
0803:                // only do it here if the experiment is _not_ modified
0804:                // -- I know, shouldnt need to, but this preserves current functionality closer
0805:                return getNodesInner(!isModified());
0806:            }
0807:
0808:            private boolean nodeExists(String name) {
0809:                return (nodes.contains(new ExperimentNode(name, this ))) ? true
0810:                        : false;
0811:            }
0812:
0813:            public final boolean agentNameUnique(String name) {
0814:                if (name == null || name.equals(""))
0815:                    return false;
0816:
0817:                // is this agent / node name combination unique
0818:                for (Iterator i = nodes.iterator(); i.hasNext();) {
0819:                    NodeComponent nc = (NodeComponent) i.next();
0820:                    if (nc.getShortName().equals(name))
0821:                        return false;
0822:                }
0823:                for (Iterator i = getAgentsList().iterator(); i.hasNext();) {
0824:                    AgentComponent nc = (AgentComponent) i.next();
0825:                    if (nc.getShortName().equals(name))
0826:                        return false;
0827:                }
0828:                return true;
0829:            }
0830:
0831:            final void addNodeComponent(ExperimentNode node) {
0832:                if (nodes.contains(node))
0833:                    return;
0834:                nodes.add(node);
0835:                installListeners(node);
0836:                fireModification();
0837:            }
0838:
0839:            private NodeComponent[] getNodesInner(boolean check) {
0840:                //     if (log.isDebugEnabled())
0841:                //       log.debug("getNodesInner(" + check + ")");
0842:
0843:                if (check)
0844:                    reconcileNodeAgentMapping();
0845:
0846:                return (NodeComponent[]) nodes.toArray(new NodeComponent[nodes
0847:                        .size()]);
0848:            }
0849:
0850:            // Ensure only Agents in the Experiment are assigned
0851:            // to Nodes, and that all Agents assigned to Nodes are the objects
0852:            // given by the society & recipes
0853:            // Note that this takes a little time
0854:            private void reconcileNodeAgentMapping() {
0855:                //     if (log.isDebugEnabled())
0856:                //       log.debug("reconcileNodeAgentMapping", new Throwable());
0857:                if (log.isDebugEnabled())
0858:                    log.debug("reconcileNodeAgentMapping");
0859:
0860:                List agents = getAgentsList();
0861:                if (nodes == null)
0862:                    return;
0863:                for (Iterator i = nodes.iterator(); i.hasNext();) {
0864:                    NodeComponent nc = (NodeComponent) i.next();
0865:                    AgentComponent[] nodeAgent = nc.getAgents();
0866:                    for (int j = 0; j < nodeAgent.length; j++) {
0867:                        int index = agents.indexOf(nodeAgent[j]);
0868:                        if (index < 0) {
0869:                            //	if (!agents.contains(nodeAgent[j]))
0870:                            nc.removeAgent(nodeAgent[j]);
0871:                        } else {
0872:                            // Find the agent in the agents list which is .equals
0873:
0874:                            // We're never going to find a second Agent with this
0875:                            // name on a Node. So no need to keep it in the list
0876:                            // of Agents in the Experiment we compare against
0877:
0878:                            AgentComponent ag = (AgentComponent) agents
0879:                                    .remove(index);
0880:                            // if its not ==, remove it from the Node, and re-add it
0881:                            // to ensure only the correct object in use
0882:                            if (ag != null && ag != nodeAgent[j]) {
0883:                                nc.removeAgent(nodeAgent[j]);
0884:                                nc.addAgent(ag);
0885:                            }
0886:                        }
0887:                    }
0888:                }
0889:            }
0890:
0891:            // returns a collection of all agents written.
0892:            private Collection generateNodeComponent(NodeComponent node,
0893:                    ComponentData parent) {
0894:                Set writtenAgents = new HashSet();
0895:
0896:                ComponentData nc = new GenericComponentData();
0897:                nc.setType(ComponentData.NODE);
0898:                nc.setName(node.getShortName());
0899:                nc.setClassName(Node.class.getName()); // leave this out?? FIXME
0900:                nc.setOwner(this ); // the experiment? FIXME
0901:                nc.setParent(parent);
0902:                //     ComponentName name =
0903:                //       new ComponentName((ConfigurableComponent) node, "ConfigurationFileName");
0904:                nc.addParameter(node.getShortName());
0905:                Properties props = node.getArguments();
0906:                for (Iterator i = props.entrySet().iterator(); i.hasNext();) {
0907:                    Map.Entry entry = (Map.Entry) i.next();
0908:                    String entVal = entry.getKey().toString();
0909:                    if (entVal.startsWith("-X")) {
0910:                        if (entry.getValue().equals("")
0911:                                || entry.getValue() == null) {
0912:                            nc.addParameter(entry.getKey());
0913:                        } else {
0914:                            nc.addParameter(entry.getKey() + "="
0915:                                    + entry.getValue());
0916:                        }
0917:                    } else if (entVal.startsWith("X:")) {
0918:                        nc.addParameter("-X" + entry.getKey() + "="
0919:                                + entry.getValue());
0920:                    } else {
0921:                        nc.addParameter("-D" + entry.getKey() + "="
0922:                                + entry.getValue());
0923:                    }
0924:
0925:                    // nc.addParameter("-D" + entry.getKey() + "=" + entry.getValue());
0926:                }
0927:                addPropertiesAsParameters(nc, node);
0928:                if (log.isDebugEnabled()) {
0929:                    log.debug("Adding: " + nc.getName() + " to "
0930:                            + parent.getName());
0931:                }
0932:                parent.addChild(nc);
0933:
0934:                // Now get the Agents on this Node
0935:                AgentComponent[] agents = node.getAgents();
0936:                if (agents != null && agents.length > 0) {
0937:                    for (int j = 0; j < agents.length; j++) {
0938:                        generateAgentComponent(agents[j], nc, parent.getOwner());
0939:                        //          if(log.isDebugEnabled()) {
0940:                        //            log.debug("Remember Agent: " + agents[j].getFullName().toString());
0941:                        //          }
0942:                        writtenAgents.add(agents[j]);
0943:                    }
0944:                }
0945:                return writtenAgents;
0946:            }
0947:
0948:            public final List getAgentsList() {
0949:                List agents = getAgentsInSociety();
0950:                if (agents == null)
0951:                    agents = new ArrayList();
0952:                List other = getAgentsInRecipes();
0953:                if (other != null && (!other.isEmpty()))
0954:                    agents.addAll(other);
0955:                return agents;
0956:            }
0957:
0958:            public final AgentComponent[] getAgents() {
0959:                List agents = getAgentsList();
0960:                return (AgentComponent[]) agents
0961:                        .toArray(new AgentComponent[agents.size()]);
0962:            }
0963:
0964:            /**
0965:             * Get the agents from the society in the experiment.
0966:             */
0967:            private List getAgentsInSociety() {
0968:                List agents = new ArrayList();
0969:                if (societyComponent != null) {
0970:                    AgentComponent[] sags = societyComponent.getAgents();
0971:                    if (sags != null && sags.length > 0)
0972:                        agents.addAll(Arrays.asList(sags));
0973:                }
0974:                return agents;
0975:            }
0976:
0977:            private List getAgentsInRecipes() {
0978:                List agents = new ArrayList();
0979:                for (int i = 0; i < recipes.size(); i++) {
0980:                    RecipeComponent recipe = (RecipeComponent) recipes.get(i);
0981:                    AgentComponent[] impagents = recipe.getAgents();
0982:                    if (impagents != null && impagents.length > 0)
0983:                        agents.addAll(Arrays.asList(impagents));
0984:                }
0985:                return agents;
0986:            }
0987:
0988:            private void generateAgentComponent(AgentComponent agent,
0989:                    ComponentData parent, ConfigurableComponent owner) {
0990:                if (log.isDebugEnabled()) {
0991:                    log.debug("Adding Agent: " + agent.getFullName().toString()
0992:                            + " To " + parent.getName());
0993:                }
0994:
0995:                AgentComponentData ac = new AgentComponentData();
0996:                ac.setName(agent.getShortName());
0997:
0998:                // Change AgentComponent to have a getClass?
0999:                if (agent instanceof  AgentBase)
1000:                    ac.setClassName(((AgentBase) agent).getAgentClassName());
1001:                else
1002:                    ac.setClassName(SimpleAgent.class.getName());
1003:
1004:                ac.addParameter(agent.getShortName()); // Agents have one parameter, the agent name
1005:                ac.setOwner(owner);
1006:                ac.setParent(parent);
1007:
1008:                // FIXME: This is the lines that forces all the $Prop things
1009:                // on the agents to be stored!!!
1010:                //addPropertiesAsParameters(ac, agent);
1011:                parent.addChild(ac);
1012:            }
1013:
1014:            // Generate a host-node-agent ComponentData tree in the global
1015:            // completeSociety variable
1016:            // This saves all assignments of agents to Nodes, including
1017:            // those nodes not assigned to Hosts.
1018:            // It also gathers the command-line arguments
1019:            final void generateHNACDATA() {
1020:                Set savedNodes = new HashSet();
1021:                Set savedAgents = new HashSet();
1022:
1023:                // getNodeComponents calls getNodesInner which should
1024:                // reconcile old Agents & new Agents
1025:                updateNameServerHostName();
1026:                // Force a reconciliation, once, even if the Experiment says it is not
1027:                // modified -- just to be safe
1028:                NodeComponent[] nodesToWrite = getNodesInner(!isModified());
1029:                AgentComponent[] agentsToWrite = getAgents();
1030:
1031:                if (log.isDebugEnabled())
1032:                    log.debug("genHNA has " + agentsToWrite.length
1033:                            + " Agents to write");
1034:
1035:                completeSociety = new GenericComponentData();
1036:
1037:                completeSociety.setType(ComponentData.SOCIETY);
1038:                completeSociety.setName(getExperimentName()); // this should be experiment: trial FIXME
1039:                completeSociety.setClassName("java.lang.Object"); // Must not be null
1040:                completeSociety.setOwner(this ); // the experiment
1041:                completeSociety.setParent(null);
1042:                addDefaultNodeArguments(completeSociety);
1043:
1044:                // For each host, add it to the society, and recurse for each of its nodes
1045:                for (Iterator iter = hosts.iterator(); iter.hasNext();) {
1046:                    ExperimentHost host = (ExperimentHost) iter.next();
1047:                    ComponentData hc = new GenericComponentData();
1048:                    if (log.isDebugEnabled()) {
1049:                        log.debug("Processing Host: " + host.getShortName());
1050:                    }
1051:                    hc.setType(ComponentData.HOST);
1052:                    hc.setName(host.getShortName());
1053:                    hc.setClassName("");
1054:                    hc.setOwner(this );
1055:                    hc.setParent(completeSociety);
1056:                    addPropertiesAsParameters(hc, host);
1057:                    completeSociety.addChild(hc);
1058:                    NodeComponent[] nodes = host.getNodes();
1059:                    for (int j = 0; j < nodes.length; j++) {
1060:                        savedAgents.addAll(generateNodeComponent(nodes[j], hc));
1061:                        savedNodes.add(nodes[j]);
1062:                    }
1063:                }
1064:
1065:                //     if (log.isDebugEnabled())
1066:                //       log.debug("genHNA: After adding assigned nodes, # saved Agents: " + savedAgents.size());
1067:
1068:                // For each un-assigned Node, add it, and recurse for the Agents
1069:                for (int i = 0; i < nodesToWrite.length; i++) {
1070:                    if (savedNodes.contains(nodesToWrite[i]))
1071:                        continue;
1072:                    savedAgents.addAll(generateNodeComponent(nodesToWrite[i],
1073:                            completeSociety));
1074:                    savedNodes.add(nodesToWrite[i]);
1075:                }
1076:
1077:                //     if (log.isDebugEnabled())
1078:                //       log.debug("genHNA: After adding UN-assigned nodes, # saved Agents: " + savedAgents.size() + ", agentsToWrite is now: " + agentsToWrite.length);
1079:
1080:                // For each unassigned Agent, add it
1081:                for (int i = 0; i < agentsToWrite.length; i++) {
1082:                    if (savedAgents.contains(agentsToWrite[i])) {
1083:                        if (log.isDebugEnabled()) {
1084:                            log.debug("genHNA Already wrote Agent: "
1085:                                    + agentsToWrite[i].getShortName());
1086:                        }
1087:                        continue;
1088:                    } else {
1089:
1090:                        // print out the FullName().toString() of all the savedAgents.
1091:
1092:                        if (log.isDebugEnabled()) {
1093:                            // 	  log.debug("genHNA: Apparently haven't yet saved " + agentsToWrite[i]);
1094:                            // 	  int j = 0;
1095:                            // 	  for (Iterator ags = savedAgents.iterator(); ags.hasNext(); j++) {
1096:                            // 	    AgentComponent ag = (AgentComponent)ags.next();
1097:                            // 	    log.debug("savedAgent[" + j + "]: " + ag.getFullName().toString());
1098:                            // 	  }
1099:
1100:                            log
1101:                                    .debug("genHNA Writing Agent["
1102:                                            + i
1103:                                            + "]: "
1104:                                            + agentsToWrite[i].getFullName()
1105:                                                    .toString());
1106:                        }
1107:                        generateAgentComponent(agentsToWrite[i],
1108:                                completeSociety, this );
1109:                        savedAgents.add(agentsToWrite[i]);
1110:                    }
1111:                } // end of loop over AgentsToWrite, to catch unassigned Agents
1112:
1113:                // Uncomment for very verbose output setting up HNA mapping
1114:                //     if (log.isDebugEnabled())
1115:                //       checkHNA(completeSociety, getAgents());
1116:            }
1117:
1118:            private void checkHNA(ComponentData data, AgentComponent[] agents) {
1119:                // Look for each of the Agents in the Experiment && make
1120:                // sure I can find them, and print out their parent.
1121:                if (data == null) {
1122:                    log.debug("checkHNA got null root");
1123:                    return;
1124:                }
1125:                ComponentData[] kids = data.getChildren();
1126:                for (int i = 0; i < kids.length; i++) {
1127:                    if (kids[i].getType().equals(ComponentData.AGENT)) {
1128:                        boolean foundkid = false;
1129:                        log.debug("checkHNA found Agent child " + kids[i]
1130:                                + " with parent " + data.getName());
1131:                        for (int j = 0; j < agents.length; j++) {
1132:                            if (agents[j] == null) {
1133:                                log
1134:                                        .debug("checkHNA: someone already matched the "
1135:                                                + j + " agent");
1136:                                continue;
1137:                            }
1138:                            log
1139:                                    .debug("checkHNA looking to see if we found agent "
1140:                                            + agents[j].getShortName());
1141:                            if (agents[j].getShortName().equals(
1142:                                    kids[i].getName())) {
1143:                                log
1144:                                        .debug("checkHNA!!! found a match for AgentComp "
1145:                                                + agents[j].getShortName()
1146:                                                + " with full name "
1147:                                                + agents[j].getFullName());
1148:                                agents[j] = null;
1149:                                foundkid = true;
1150:                                break;
1151:                            }
1152:                        } // loop over agents
1153:
1154:                        // Make sure I found a real Agent for this ComponentData
1155:                        if (!foundkid) {
1156:                            log
1157:                                    .debug("checkHNA!!!! didnt find a real AgentComp to match AgentData "
1158:                                            + kids[i]
1159:                                            + " in parent "
1160:                                            + data.getName());
1161:                        }
1162:                    } else
1163:                        checkHNA(kids[i], agents);
1164:                }
1165:
1166:                // See if I found all of the Agents in the Experiment
1167:                if (data == completeSociety)
1168:                    for (int i = 0; i < agents.length; i++) {
1169:                        if (agents[i] != null) {
1170:                            log
1171:                                    .debug("checkHNA!!!! Never found componentData for Agent: "
1172:                                            + agents[i].getShortName()
1173:                                            + " with full name "
1174:                                            + agents[i].getFullName());
1175:                        }
1176:                    }
1177:            }
1178:
1179:            // Use the previously inited host-node-agent ComponentData tree
1180:            // in the variable 'completeSociety'
1181:            // And loop through all components in the Experiment,
1182:            // asking them to add their ComponentData
1183:            // return the or'ed value of componentWasRemoved()
1184:            final boolean askComponentsToAddCDATA() {
1185:                // Now ask each component in turn to add its stuff
1186:                boolean componentWasRemoved = false;
1187:
1188:                BaseComponent theSoc = getSocietyComponent();
1189:                if (log.isDebugEnabled()) {
1190:                    log.debug(theSoc.getFullName().toString()
1191:                            + ".addComponentData");
1192:                }
1193:                theSoc.addComponentData(completeSociety);
1194:                componentWasRemoved |= theSoc.componentWasRemoved();
1195:
1196:                for (int i = 0, n = recipes.size(); i < n; i++) {
1197:                    BaseComponent soc = (BaseComponent) recipes.get(i);
1198:
1199:                    if (log.isDebugEnabled()) {
1200:                        log.debug(soc.getFullName().toString()
1201:                                + ".addComponentData");
1202:                    }
1203:                    // Warning: This is a no-op in general
1204:                    // for recipes that use RecipeBase. AgentInsertion and ABCImpact
1205:                    // use it though. Basically, you can only use
1206:                    // it if you don't need a DB query to know what to do.
1207:                    soc.addComponentData(completeSociety);
1208:
1209:                    //       if (log.isDebugEnabled())
1210:                    // 	log.debug("askToAdd: now complete is: " + completeSociety);
1211:
1212:                    // Components can notice here if they had to remove
1213:                    // a component (or, I suppose, modify)
1214:                    componentWasRemoved |= soc.componentWasRemoved();
1215:                    // Note that no current component returns true here
1216:                }
1217:                return componentWasRemoved;
1218:            }
1219:
1220:            public final void writeContents(String filename, OutputStream out) {
1221:                createConfigWriter();
1222:                try {
1223:                    configWriter.writeFile(filename, out);
1224:                } catch (Exception e) {
1225:                    if (log.isErrorEnabled()) {
1226:                        log.error("Exception: ", e);
1227:                    }
1228:                }
1229:            }
1230:
1231:            /**
1232:             * An Experiment now has a configuration writer that
1233:             * lets all the components write themselves out
1234:             */
1235:            final void createConfigWriter() {
1236:                if (configWriter == null) {
1237:                    configWriter = new LeafOnlyConfigWriter(
1238:                            getSocietyComponentData());
1239:                }
1240:            }
1241:
1242:            /**
1243:             * If the experiment has at least one host with at least one node
1244:             * with at least one agent, that is a configuration.
1245:             *
1246:             * @return a <code>boolean</code> true if it has a configured agent
1247:             */
1248:            public final boolean hasConfiguration() {
1249:                if (hosts.isEmpty() || nodes.isEmpty() || getAgents() == null
1250:                        || getAgents().length == 0) {
1251:                    return false;
1252:                }
1253:                HostComponent[] hosts = getHostComponents();
1254:                for (int i = 0; i < hosts.length; i++) {
1255:                    if (hosts[i] == null)
1256:                        continue;
1257:                    NodeComponent[] nodes = hosts[i].getNodes();
1258:                    for (int j = 0; j < nodes.length; j++) {
1259:                        if (nodes[j] == null)
1260:                            continue;
1261:                        AgentComponent[] agents = nodes[j].getAgents();
1262:                        if (agents.length > 0)
1263:                            return true;
1264:                    } // loop over nodes in host
1265:                } // loop over hosts in experiment
1266:                return false;
1267:            }
1268:
1269:            /**
1270:             * Blindly assume the experiment has no hosts or nodes yet.
1271:             * Create a host for the local host, a Node named Node0, and put
1272:             * all the agents on that node on that host.
1273:             */
1274:            public final void createDefaultConfiguration() {
1275:                // Check if it already has a node?
1276:                // create one Node
1277:                NodeComponent node = null;
1278:
1279:                // BIG HACK IN HERE!!!!!!
1280:                node = addNode("Node0");
1281:                // Put all the agents in this Node
1282:                // Skip agents already assigned to Nodes?
1283:                AgentComponent[] agents = getAgents();
1284:                for (int i = 0; i < agents.length; i++) {
1285:                    node.addAgent(agents[i]);
1286:                }
1287:
1288:                // Create one host
1289:                // get this machine's name and use it
1290:                String localhost = "localhost";
1291:                try {
1292:                    localhost = java.net.InetAddress.getLocalHost()
1293:                            .getHostName();
1294:                } catch (java.net.UnknownHostException e) {
1295:                }
1296:                HostComponent host = addHost(localhost);
1297:
1298:                // put the one node on that host
1299:                host.addNode(node);
1300:                fireModification();
1301:            }
1302:
1303:            /**
1304:             * Returns whether or not this experiment has been modified
1305:             * since it was saved to the database.
1306:             * @return true if experiment has been modified
1307:             */
1308:            public final boolean isModified() {
1309:                return modified;
1310:            }
1311:
1312:            /**
1313:             * Indicate that the experiment is up-to-date with respect to the database.
1314:             * Use with caution!  The only reason to reset this flag
1315:             * is that when an experiment is created from the database, its components
1316:             * are built-up from the database information, and thus the experiment
1317:             * appears to be modified.
1318:             */
1319:            public final void resetModified() {
1320:                modified = false;
1321:                // tell listeners experiment is now saved
1322:                fireModification(new ModificationEvent(this ,
1323:                        ExperimentBase.EXPERIMENT_SAVED));
1324:            }
1325:
1326:            /**
1327:             * Sets the current Trial ID.
1328:             *
1329:             * @param trialID - New Trial ID
1330:             */
1331:            final void setTrialID(String trialID) {
1332:                if (this .trialID == trialID)
1333:                    return;
1334:                this .trialID = trialID;
1335:                defaultNodeArguments
1336:                        .setReadOnlyProperty(EXPERIMENT_ID, trialID);
1337:                fireModification();
1338:            }
1339:
1340:            public final String getTrialID() {
1341:                if (DBUtils.dbMode) {
1342:                    return trialID;
1343:                } else {
1344:                    return null;
1345:                }
1346:            }
1347:
1348:            /**
1349:             * Sets the Experiment ID for this Experiment.
1350:             *
1351:             * @param expID
1352:             */
1353:            public final void setExperimentID(String expID) {
1354:                if (this .expID == expID)
1355:                    return;
1356:                this .expID = expID;
1357:                fireModification();
1358:            }
1359:
1360:            public final String getExperimentID() {
1361:                if (DBUtils.dbMode) {
1362:                    return expID;
1363:                } else {
1364:                    return null;
1365:                }
1366:            }
1367:
1368:            /**
1369:             * get the local variable idea of the community assembly for this
1370:             * experiment, possibly null
1371:             */
1372:            public final String getCommAsbID() {
1373:                return commAsb;
1374:            }
1375:
1376:            /**
1377:             * (Re) set the local variables idea of the community assembly for
1378:             * this experiment, possibly to null
1379:             */
1380:            public final void setCommAsbID(String id) {
1381:                this .commAsb = id;
1382:            }
1383:
1384:            /**
1385:             * Imports a HNA XML file.  The file is imported into
1386:             * a <code>ComponentData</code> structure which is then
1387:             * traversed and applied to the current experiment.
1388:             *
1389:             * @param parent - Parent GUI Component
1390:             */
1391:            public final void importHNA(Component parent) {
1392:                File resultDir = getResultDirectory();
1393:                String path = ".";
1394:                if (resultDir != null)
1395:                    path = resultDir.getAbsolutePath();
1396:                JFileChooser chooser = new JFileChooser(path);
1397:                chooser.setDialogTitle("Select HNA Export file to apply");
1398:                chooser
1399:                        .setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
1400:                chooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
1401:                    public boolean accept(final File f) {
1402:                        return (f.isDirectory() || (f.isFile())
1403:                                && f.canRead()
1404:                                && (f.getName().endsWith("xml") || f.getName()
1405:                                        .endsWith("XML")));
1406:                    }
1407:
1408:                    public String getDescription() {
1409:                        return "HNA XML Files";
1410:                    }
1411:                });
1412:                File file = null;
1413:                while (file == null) {
1414:                    int result = chooser.showDialog(parent, "OK");
1415:                    if (result != JFileChooser.APPROVE_OPTION)
1416:                        return;
1417:                    file = chooser.getSelectedFile();
1418:                    if (file != null && (!file.canRead() || file.isDirectory()))
1419:                        file = null;
1420:                }
1421:
1422:                if (log.isInfoEnabled()) {
1423:                    log.info("importing HNA file " + file.getAbsolutePath());
1424:                }
1425:
1426:                // FIXME: Put up a dialog indicating the file being imported?
1427:                // Bug 1765
1428:
1429:                ComponentData mapping = null;
1430:                ExperimentXML parser = new ExperimentXML();
1431:                mapping = parser.parseExperimentFile(file);
1432:                if (mapping == null) {
1433:                    if (log.isErrorEnabled()) {
1434:                        log.error("Error parsing file: " + file.getName());
1435:                    }
1436:                    // Display an error dialog here!
1437:                    return;
1438:                }
1439:
1440:                if (mapping.getType().equals(ComponentData.SOCIETY)) {
1441:                    addChildren(mapping.getChildren());
1442:                } else {
1443:                    if (log.isErrorEnabled()) {
1444:                        log.error("Didn't start with a society!");
1445:                    }
1446:                }
1447:            }
1448:
1449:            /**
1450:             * Adds new children to the experiment components
1451:             * based on the NHA mappings loaded in from a file.
1452:             *
1453:             * @param children - Child Component to re-map.
1454:             */
1455:            private void addChildren(final ComponentData[] children) {
1456:                if (children == null)
1457:                    return;
1458:                for (int i = 0; i < children.length; i++) {
1459:                    final ComponentData child = children[i];
1460:                    if (child == null)
1461:                        continue;
1462:                    if (child.getType().equals(ComponentData.HOST)) {
1463:                        // Add host.
1464:                        HostComponent host = null;
1465:                        try {
1466:                            host = addHost(child.getName());
1467:                        } catch (IllegalArgumentException e) {
1468:                            // Host already exists.
1469:                            final HostComponent[] allHosts = getHostComponents();
1470:                            if (allHosts == null)
1471:                                continue;
1472:                            for (int x = 0; x < allHosts.length; x++) {
1473:                                if (allHosts[x].getShortName().equals(
1474:                                        child.getName())) {
1475:                                    host = allHosts[x];
1476:                                    break;
1477:                                }
1478:                            }
1479:                            if (log.isDebugEnabled()) {
1480:                                log.debug("Host already exists: "
1481:                                        + child.getName());
1482:                            }
1483:                        }
1484:                        if (host != null)
1485:                            addHostChildren(child.getChildren(), host);
1486:                    } else if (child.getType().equals(ComponentData.NODE)) {
1487:                        // Add node.
1488:                        NodeComponent node = null;
1489:                        try {
1490:                            node = addNode(child.getName());
1491:                        } catch (IllegalArgumentException e) {
1492:                            // Node already exists.
1493:                            final NodeComponent[] allNodes = getNodeComponents();
1494:                            if (allNodes == null)
1495:                                continue;
1496:                            for (int x = 0; x < allNodes.length; x++) {
1497:                                if (allNodes[x].getShortName().equals(
1498:                                        child.getName())) {
1499:                                    node = allNodes[x];
1500:                                    break;
1501:                                }
1502:                            }
1503:                            if (log.isDebugEnabled()) {
1504:                                log.debug("Node already exists: "
1505:                                        + child.getName());
1506:                            }
1507:                        }
1508:                        if (node != null)
1509:                            addNodeChildren(child.getChildren(), node);
1510:                    } else if (child.getType().equals(ComponentData.AGENT)) {
1511:                        // Ignore.
1512:                    } else {
1513:                        if (log.isWarnEnabled()) {
1514:                            log.warn("Unknown Type: " + child.getType());
1515:                        }
1516:                    }
1517:                }
1518:            }
1519:
1520:            /**
1521:             * Adds all new children to the HostComponent
1522:             *
1523:             * @param children All children of the new HostComponent.
1524:             * @param host - HostComponent to add children to.
1525:             */
1526:            private void addHostChildren(ComponentData[] children,
1527:                    HostComponent host) {
1528:                if (children == null)
1529:                    return;
1530:                if (host == null)
1531:                    return;
1532:                for (int i = 0; i < children.length; i++) {
1533:                    boolean foundInHost = false;
1534:                    boolean foundInSociety = false;
1535:                    ComponentData child = children[i];
1536:                    if (child == null)
1537:                        return;
1538:                    NodeComponent expNode = null;
1539:                    NodeComponent[] allNodes = getNodeComponents();
1540:                    if (child.getType().equals(ComponentData.NODE)) {
1541:                        if (allNodes != null) {
1542:                            for (int k = 0; k < allNodes.length; k++) {
1543:                                if (allNodes[k] == null)
1544:                                    continue;
1545:                                if (child.getName().equals(
1546:                                        allNodes[k].getShortName())) {
1547:                                    foundInSociety = true;
1548:                                    expNode = allNodes[k];
1549:                                    break;
1550:                                }
1551:                            }
1552:                        }
1553:                        NodeComponent[] crntNodes = host.getNodes();
1554:                        if (crntNodes != null) {
1555:                            for (int j = 0; j < crntNodes.length; j++) {
1556:                                if (crntNodes[j] == null)
1557:                                    continue;
1558:                                if (child.getName().equals(
1559:                                        crntNodes[j].getShortName())) {
1560:                                    foundInHost = true;
1561:                                    break;
1562:                                }
1563:                            }
1564:                        }
1565:                        if (!foundInHost) {
1566:                            // See if in Exp.
1567:                            if (foundInSociety) {
1568:                                expNode = host.addNode(expNode);
1569:                            } else {
1570:                                expNode = host
1571:                                        .addNode(addNode(child.getName()));
1572:                            }
1573:                        }
1574:                        if (expNode != null)
1575:                            addNodeChildren(child.getChildren(), expNode);
1576:                    } else {
1577:                        if (log.isWarnEnabled()) {
1578:                            log.warn("Unknown child of host: "
1579:                                    + child.getName());
1580:                        }
1581:                    }
1582:                }
1583:            }
1584:
1585:            /**
1586:             * Adds all children to the Node.
1587:             *
1588:             * @param children All new children for the node.
1589:             * @param node Node to add children to.
1590:             */
1591:            private void addNodeChildren(ComponentData[] children,
1592:                    NodeComponent node) {
1593:                if (node == null)
1594:                    return;
1595:                if (children == null)
1596:                    return;
1597:
1598:                for (int i = 0; i < children.length; i++) {
1599:                    boolean foundInSociety = false;
1600:                    boolean foundInNode = false;
1601:                    ComponentData child = children[i];
1602:                    if (child == null)
1603:                        continue;
1604:                    AgentComponent[] allAgents = getAgents();
1605:                    AgentComponent addAgent = null;
1606:                    if (child.getType().equals(ComponentData.AGENT)) {
1607:                        if (allAgents != null) {
1608:                            for (int k = 0; k < allAgents.length; k++) {
1609:                                if (allAgents[k] == null)
1610:                                    continue;
1611:                                if (child.getName().equals(
1612:                                        allAgents[k].getShortName())) {
1613:                                    foundInSociety = true;
1614:                                    addAgent = allAgents[k];
1615:                                    break;
1616:                                }
1617:                            }
1618:                        }
1619:
1620:                        if (foundInSociety) {
1621:                            AgentComponent[] crntAgents = node.getAgents();
1622:                            if (crntAgents != null) {
1623:                                for (int j = 0; j < crntAgents.length; j++) {
1624:                                    if (crntAgents[j] == null)
1625:                                        continue;
1626:                                    if (child.getName().equals(
1627:                                            crntAgents[j].getShortName())) {
1628:                                        foundInNode = true;
1629:                                        break;
1630:                                    }
1631:                                }
1632:                            }
1633:                            if (!foundInNode) {
1634:                                if (addAgent == null) {
1635:                                    // this shouldnt happen
1636:                                } else {
1637:                                    // FIXME: This test not quite adequate - must
1638:                                    // check that agent name not same as any
1639:                                    // other Node or Agent name
1640:                                    if (node.getShortName().equalsIgnoreCase(
1641:                                            addAgent.getShortName())) {
1642:                                        if (log.isWarnEnabled()) {
1643:                                            log
1644:                                                    .warn("Agent name same as node, cannot perform addition");
1645:                                        }
1646:                                        JOptionPane
1647:                                                .showMessageDialog(
1648:                                                        null,
1649:                                                        "Cannot Map Agent to Node of Same name, ignoring agent: "
1650:                                                                + addAgent
1651:                                                                        .getShortName());
1652:                                    } else {
1653:                                        node.addAgent(addAgent);
1654:                                    }
1655:                                }
1656:                            }
1657:                        } else {
1658:                            JOptionPane.showMessageDialog(null,
1659:                                    "Cannot Map Unknown Agent: "
1660:                                            + child.getName());
1661:                            if (log.isWarnEnabled()) {
1662:                                log.warn("Agent: " + child.getName()
1663:                                        + " not known.  Add aborted");
1664:                            }
1665:                        }
1666:                    } else {
1667:                        if (log.isWarnEnabled()) {
1668:                            log.warn("Unknown child of node: "
1669:                                    + child.getName());
1670:                        }
1671:                    }
1672:                }
1673:            }
1674:
1675:            public abstract void save(DBConflictHandler ch);
1676:
1677:            protected abstract void setDefaultNodeArguments();
1678:
1679:            final class MyModificationListener implements  ModificationListener,
1680:                    ConfigurableComponentListener {
1681:                // tell listeners on experiment that experiment was modified
1682:                public void modified(ModificationEvent e) {
1683:                    notifyExperimentListeners(e);
1684:                }
1685:            }
1686:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.