/* * Title: TestArguments * Version: 0.1 * Copyright: Copyright (c) 2001 * Author: Sven Thommesen * Description: Sample app to show parsing of command line arguments. * Example 4 of 5. */ /* * This example demonstrates a way to extract command line data directly * from the command line, using some of the data to set local variables in * the BatchSwarm, and putting data into an application parameter database * which can be passed around for objects in the simulation to access. * * It differs from Example 2 in that: * a) the '-Dkey=value' arguments are specified on the command line * AFTER the name of the program and FOLLOWING ' -- '. * b) the main program shows a slightly different way of getting the * program started in a separate thread. * * NOTE that the benefit of this approach is that it can also be used * in objective-C based Swarm programs, since it does not depend on the * Java runtime system to parse the command line and add items to the * System Properties database. * * Only data values passed to the program on the command line are entered * into the parameter database. * * The example consists of 3 parts (objects), named TestArgsMain.java, * TestArgsBatchSwarm.java, and TestArgsModelSwarm.java. Cut the relevant * sections from the file below and create the 3 named files, then compile * the application: * * $ javacswarm TestArgsMain.java * * You then invoke the application in the usual way, except you place * command line arguments of the form '-Dkey=value' between the word * 'javaswarm' (or 'java') and the name of the application, for example: * * $ javaswarm TestArgsMain -b -- -DrandomSeed=456 -Dii=77 * * You can capture program output by redirecting it to a disk file for * later inspection: * * $ javaswarm TestArgsMain -b -- -DrandomSeed=456 -Dii=77 > runlog.txt * * As you will see from the program listing, you can also set the values of * parameters 'experimentDuration', 'dd', 'ss', and 'evaporationRate' on * the command line and the program will pick the new values up. * * The activities of the ModelSwarm depend on the values of the parameters * 'experimentDuration' and 'randomSeed'. * */ // ----- cut here --- // TestArgsMain.java /* * Title: TestArguments * Version: 0.1 * Copyright: Copyright (c) 2001 * Author: Sven Thommesen * Description: Sample app to show parsing of command line arguments */ import swarm.Globals; import swarm.defobj.Archiver; import swarm.defobj.LispArchiverImpl; /* * This version of the main program demonstrates the use of Java's * 'Runnable' interface, starting the program in a separate thread. * */ public class TestArgsMain implements Runnable { String[] commandLineArgs = null; public TestArgsMain(String[] args) { commandLineArgs = args; System.out.println("Main: Incoming command line args are:"); for (int i=0; i * Description: Sample app to show parsing of command line arguments. * Example 4 of 5. */ import swarm.Globals; import swarm.Selector; import swarm.SignatureNotFoundException; import swarm.NonUniqueMethodSignatureException; import swarm.defobj.Zone; import swarm.objectbase.Swarm; import swarm.objectbase.SwarmImpl; import swarm.objectbase.Probe; import swarm.objectbase.VarProbe; import swarm.objectbase.VarProbeImpl; import swarm.objectbase.ProbeMap; import swarm.activity.Activity; import swarm.activity.ActionGroup; import swarm.activity.ActionGroupImpl; import swarm.activity.Schedule; import swarm.activity.ScheduleImpl; import java.lang.String; import java.util.HashMap; import java.util.Properties; import java.util.Enumeration; import java.util.Iterator; public class TestArgsBatchSwarm extends SwarmImpl { // Program parameters: // (note that these must be 'public' to be settable by probes) public int experimentDuration = 0; public int randomSeed = 0; public int ii = 0; public double dd = 0.0; public String ss = null; // Objects: public TestArgsModelSwarm modelSwarm = null; Schedule stopSchedule = null; Schedule modelSchedule = null; ActionGroup modelActions = null; HashMap arguments = null; ProbeMap aProbeMap = null; String[] commandLineArgs = null; public TestArgsBatchSwarm(Zone aZone) { super(aZone); aProbeMap = Globals.env.probeLibrary.getCompleteVarMapFor (this.getClass()); arguments = new HashMap(); // Set default values for instance variables: experimentDuration = 10; randomSeed = 123456789; ii = -1; dd = 987.6; ss = "DefaultValue"; } public void setArgs (String[] args) { commandLineArgs = args; System.out.println("BatchSwarm: relevant command line args are"); for (int i = Globals.env.arguments.getLastArgIndex()-1; i < args.length; i++) System.out.println( i + ": " + args[i] ); } /* * This version looks for "-Dkey=value" * anywhere on the command line past the '--' token. * */ public void parseCommandLine() { // Inspect the args[] array of command line atoms, // starting after the '--' token. // If we find one that starts with "-D": // inspect the rest of the string for key=value, or // skip this atom if '=' is not found within it. // Parse and split into key-string and value-string. // Add the key-value pair to the 'arguments' database. System.out.println("Parsing the command line:"); String key = new String ("-D"); int delim = (int) '='; for (int i = Globals.env.arguments.getLastArgIndex()-1; i < commandLineArgs.length; i++) { String arg = commandLineArgs[i]; System.out.println(i + " arg = " + arg); int key_index = arg.indexOf(key); if (key_index < 0) { // -D not found // do nothing } else { // found it! int delim_index = arg.indexOf(delim, key_index+2); if (delim_index < 0) { // '=' not found // do nothing } else { // found '=' here String argName = arg.substring(key_index+2, delim_index); String argValue = arg.substring(delim_index+1); System.out.println (" Found tokens: " + argName + " " + argValue); // Now do something with what we found: // add the key-value pair to the 'arguments' HashMap this.addArgument (argName, argValue); } } } } /* * This method filters out the properties our simulation is interested in * and adds them to our private properties database (a HashMap). * A HashMap allows both 'key' and 'value' to be arbitrary object types, * so we convert the value string (str2) to the relevant object type. * */ public void addArgument (String str1, String str2) { if ( str1.equals("experimentDuration") || str1.equals("randomSeed") || str1.equals("ii") ) { arguments.put (str1, new Integer(str2)); // System.out.println(" key = " + str1 + ", value = " + str2); } else if ( str1.equals("dd") || str1.equals("evaporationRate") ) { arguments.put (str1, new Double(str2)); // System.out.println(" key = " + str1 + ", value = " + str2); } else if ( str1.equals("ss") ) { arguments.put (str1, new String(str2)); // System.out.println(" key = " + str1 + ", value = " + str2); } else { // key values not listed above are ignored } } /* * Now we cycle through our arguments database and extract * values relevant to the present object (the BatchSwarm). * Values needed by other objects ('evaporationRate') are ignored. * Values set here override default values set in the constructor. * */ public void parseArguments() { System.out.println("BatchSwarm: setting local variables"); Iterator index = arguments.keySet().iterator(); while ( index.hasNext() ) { String key = (String) index.next(); if (key.equals("experimentDuration")) { experimentDuration = ((Integer)arguments.get(key)).intValue(); System.out.println(" Setting variable \"" + key + "\" to value \'" + experimentDuration + "\'"); } else if (key.equals("randomSeed")) { randomSeed = ((Integer)arguments.get(key)).intValue(); System.out.println(" Setting variable \"" + key + "\" to value \'" + randomSeed + "\'"); } else if (key.equals("ii")) { ii = ((Integer)arguments.get(key)).intValue(); System.out.println(" Setting variable \"" + key + "\" to value \'" + ii + "\'"); } else if (key.equals("dd")) { dd = ((Double)arguments.get(key)).doubleValue(); System.out.println(" Setting variable \"" + key + "\" to value \'" + dd + "\'"); } else if (key.equals("ss")) { ss = (String) arguments.get(key); System.out.println(" Setting variable \"" + key + "\" to value \'" + ss + "\'"); } } } public Object buildObjects() { super.buildObjects(); // extract command line arguments from the command line // and put them into a HashMap object: this.parseCommandLine(); // set values of instance variables for this object (batchSwarm): this.parseArguments(); // initialize the random generator with the provided seed: if (randomSeed != 0) { System.out.println("Setting random generator with seed " + randomSeed); Globals.env.randomGenerator.setStateFromSeed (randomSeed); } // Build the ModelSwarm and pass it a pointer to the 'arguments' object: System.out.println("Building ModelSwarm."); modelSwarm = new TestArgsModelSwarm(this.getZone(), arguments); // tell modelSwarm to build its own objects: modelSwarm.buildObjects(); return this; } /* * Here we show the use of a schedule to halt the simulation at a * predetermined simulation time, regulated by the 'experimentDuration' * parameter, which the user may set from the command line. * The modelSwarm builds its own actions (to run its 'step' method.) * */ public Object buildActions() { super.buildActions(); modelSwarm.buildActions(); // Create schedules for runtime actions: stopSchedule = new ScheduleImpl(this.getZone(), true); // autodrop try { stopSchedule.at$createActionTo$message (experimentDuration-1, this, new Selector (this.getClass(), "stopRunning", false) ); } catch (SignatureNotFoundException e) { System.err.println("BatchSwarm::build--Couldn't find method."); e.printStackTrace(); System.exit(-1); } catch (NonUniqueMethodSignatureException e) { System.err.println("BatchSwarm::build--NonUnique method."); e.printStackTrace(); System.exit(-1); } return this; } public Activity activateIn (Swarm swarmContext) { super.activateIn(swarmContext); modelSwarm.activateIn(this); stopSchedule.activateIn(this); return getActivity(); } public Object go() { System.out.println("You typed -b or --batch."); System.out.println("TestArgs is running in non-gui batch mode."); System.out.println ("Model will run for at most " + experimentDuration + " periods."); (getActivity().getSwarmActivity()).run(); System.out.println("BatchSwarm: stopped."); return getActivity().getStatus(); } public void stopRunning () { System.out.println ("BatchSwarm: Quitting at " + Globals.env.getCurrentTime() ); Globals.env.getCurrentSwarmActivity().terminate(); } public void drop() { System.out.println("BatchSwarm: drop."); super.drop(); System.out.println("BatchSwarm: halt."); System.exit(0); } } // ----- cut here --- // TestArgsModelSwarm.java /* * Title: TestArguments * Version: 0.1 * Copyright: Copyright (c) 2001 * Author: Sven Thommesen * Description: Sample app to show parsing of command line arguments. */ /* * This version of the ModelSwarm expects a HashMap object * passed to it in the constructor. */ import swarm.Globals; import swarm.Selector; import swarm.defobj.Zone; import swarm.activity.Activity; import swarm.activity.ActionGroup; import swarm.activity.ActionGroupImpl; import swarm.activity.Schedule; import swarm.activity.ScheduleImpl; import swarm.objectbase.Swarm; import swarm.objectbase.SwarmImpl; import java.util.HashMap; import java.util.Iterator; public class TestArgsModelSwarm extends SwarmImpl { // data public double evaporationRate; // objects ActionGroup modelActions; Schedule modelSchedule; HashMap arguments; public TestArgsModelSwarm (Zone aZone, HashMap args) { super (aZone); // This is a pointer to the arguments data base (HashMap): arguments = args; // Set default data values: evaporationRate = 0.225; } public Object buildObjects () { super.buildObjects(); // Extract data values from the data base: this.parseArguments(); return this; } public Object buildActions () { super.buildActions(); modelActions = new ActionGroupImpl (getZone ()); try { modelActions.createActionTo$message (this, new Selector (this.getClass(), "step", true)); } catch (Exception e) { System.err.println ("Exception step: " + e.getMessage ()); } modelSchedule = new ScheduleImpl (getZone (), 1); modelSchedule.at$createAction (0, modelActions); return this; } public Activity activateIn (Swarm swarmContext) { super.activateIn (swarmContext); modelSchedule.activateIn (this); return getActivity (); } /* * This method shows how to extract data from the HashMap which was * passed in from the BatchSwarm. We cannot assume that any particular * key-value pair exists in the HashMap. * */ public void parseArguments() { System.out.println("ModelSwarm: setting local variables"); Iterator index = arguments.keySet().iterator(); while ( index.hasNext() ) { String key = (String) index.next(); if (key.equals("evaporationRate")) { evaporationRate = ((Double) arguments.get(key)).doubleValue(); System.out.println(" Setting variable \"" + key + "\" to value \'" + evaporationRate + "\'"); } } } /* * The 'step' method will be executed 'experimentDuration' number * of times. The random samples drawn will depend on the 'randomSeed' * with which the generator was initialized. The value of 'evaporationRate' * is printed to show either the default value (set in the constructor * for the modelSwarm) or the value set on the command line. * */ public void step() { // Note: the number of steps taken should depend on 'experimentDuration' // Note: the random variates printed should depend on 'randomSeed' System.out.println(" -> Step: t = " + Globals.env.getCurrentTime() + " random int = " + Globals.env.randomGenerator.getUnsignedSample() + " evapRate = " + evaporationRate); // Caution: since Java does not support unsigned integers, the random // generator method getUnsignedSample() returns a signed integer // in java programs. } }