obol/testScript.java
package obol;
import java.io.*;
import java.util.*;
import obol.tools.Base64;
import obol.tools.Debug;
import obol.lang.API;
import obol.lang.Runtime;
import obol.lang.ScriptHandle;
import obol.lang.ReturnValue;
import obol.lang.ObolException;
import obol.lang.LoadedScriptInfo;
/** General script testing tool.
* Loads and executes some script, allowing script inputs to be given on the
* command line.
* @version $Id: testScript.java,v 1.1 2007/03/16 16:22:07 perm Exp $
*/
public class testScript {
private static final String __me = "obol.testScript";
private static final String __version = "$Id: testScript.java,v 1.1 2007/03/16 16:22:07 perm Exp $";
private static Debug __D = new Debug();
public static String helpText =
"Usage: java " + __me + " <args> <scriptfile> <script-params>\n" +
" <args> are:\n" +
" -h\tthis help text\n" +
" -v\tbe verbose\n" +
" -V\tprint version and exit\n" +
" -n <name>\tname of script to execute, instead of first found\n" +
" -r <ver>\tversion of script to execute, instead of first found\n" +
" -D <name>=<level> set debug level for a named debug facility\n" +
" (can appear multiple times) See tools.Debug class docs.\n" +
" <scriptfile> - an obol script filename\n" +
" <script-params> - script input arguments, of the form \"key=value\".";
// return true if the string contains any whitespace character
private static boolean hasWhiteSpace(String data) {
for (int _i = 0; _i < data.length(); _i++) {
if (Character.isWhitespace(data.charAt(_i))) {
return true;
}
}
return false;
}
// strip enclosing double and single qoutes from the given string
private static String strip(String data) {
if (0 != data.length()) {
int _end = data.length() - 1;
char _dq = '"', _sq = '\'';
if ((_dq == data.charAt(0) && _dq == data.charAt(_end)) ||
(_sq == data.charAt(0) && _sq == data.charAt(_end))) {
data = data.substring(1,_end);
}
}
return data;
}
// base64-decode the string, if it is surrounded by a pair of bars
private static Object decode(String data) {
int _end = data.length() - 1;
if ('|' == data.charAt(0) && '|' == data.charAt(_end)) { // Base64
return Base64.decode(data.substring(1, _end));
}
return data;
}
// convert an array of strings of the form "key=value" into a hashmap,
// starting at the given index.
private static Map mapifyArgs(String [] args, int startIndex) {
HashMap _map = new HashMap(args.length - startIndex);
for (int _i = startIndex; _i < args.length; _i++) {
String [] _sa = args[_i].split("=");
if (null == _sa || 2 != _sa.length) {
throw new RuntimeException(__me + ".mapifyArgs(): " +
"Bogus argument \"" + args[_i] + "\"!");
}
String _key = _sa[0];
if (hasWhiteSpace(_key)) {
throw new RuntimeException(__me + ".mapifyArgs(): " +
"Whitespace in key part of arg \"" + args[_i] +
"\"!");
}
String _value = strip(_sa[1]);
_map.put(_key, decode(strip(_value)));
}
return _map;
}
// create a string consisting of comma-separated iterator elements
private static String dumpIterator(Iterator it) { return dumpIterator(it, false); }
private static String dumpIterator(Iterator it, boolean quote) {
StringBuffer _sb = new StringBuffer();
while(it.hasNext()) {
if (quote) _sb.append('"');
_sb.append(it.next().toString());
if (quote) _sb.append('"');
if (it.hasNext()) { _sb.append(", "); }
}
return _sb.toString();
}
// Main program (doh!)
public static void main(String [] args) throws Exception {
try {
mainLoop(args);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
public static void mainLoop(String [] args) throws Exception {
// Process args
int _i = 0;
if (0 == args.length) {
System.out.println(helpText);
System.exit(0);
}
String _scriptName = null;
String _scriptVersion = null;
String _debugName = null;
String _debugLevel = null;
boolean _argsOK = true;
int _usedArgs = 0;
for(; _i < args.length; _i++) {
String _arg = args[_i];
if (false == _arg.startsWith("-")) {
break;
}
// System.err.println("processing arg " + _arg);
if ("-h".equals(_arg)) {
System.out.println(helpText);
System.exit(0);
} else if ("-v".equals(_arg)) {
} else if ("-V".equals(_arg)) {
System.out.println(__me + " version: " + __version);
System.exit(0);
} else if ("-n".equals(_arg)) {
if (false == ((_i + 1) < args.length)) {
System.err.println("ERROR: Missing script name argument.");
_argsOK = false;
}
_scriptName = strip(args[++_i]);
_usedArgs++;
} else if ("-r".equals(_arg)) {
if (false == ((_i + 1) < args.length)) {
System.err.println("ERROR: Missing script version argument.");
_argsOK = false;
}
_scriptVersion = strip(args[++_i]);
_usedArgs++;
} else if ("-D".equals(_arg)) {
if (false == ((_i + 1) < args.length)) {
System.err.println("ERROR: Missing debug name facility and level argument!");
System.err.println(" Available facilities: " + Debug.getNames());
_argsOK = false;
} else {
String [] _sa = args[++_i].split("=");
if (2 != _sa.length) {
System.err.println("ERROR: -D option must have \"debug-name=level\" syntax!");
_argsOK = false;
} else {
_debugName = _sa[0];
_debugLevel = _sa[1];
// Call this here since -D can occure multiple times.
Debug.setLevel(_debugName, _debugLevel);
}
}
_usedArgs++;
} else {
_argsOK = false;
System.err.println(__me + ": Unrecognized argument \"" + _arg +
"\"!");
}
}
if ((0 != _usedArgs && _usedArgs == (args.length - 1))
|| (_i >= args.length)) {
System.err.println(__me + ": ERROR: Missing filename argument.");
_argsOK = false;
}
if (false == _argsOK) {
System.out.println(helpText);
System.exit(1);
}
String _scriptFileName = args[_i++];
Map _args = mapifyArgs(args, _i);
// contact Obol runtime, and load all scripts from the given file
API _lobo = Runtime.getInstance();
System.err.println(__me + ": Loading script(s) from file \"" +
_scriptFileName + "\"");
LoadedScriptInfo [] _loaded = _lobo.loadScripts(_scriptFileName);
if (null == _loaded) {
System.err.println(__me + ": *** no scripts found in input file!");
System.exit(1);
}
LoadedScriptInfo _defaultInfo = _loaded[0];
if (null == _scriptName) {
_scriptName = _defaultInfo.getName();
}
for(Iterator _it = _lobo.getInfoIterator(); _it.hasNext(); ) {
// tell user what scripts were loaded from the file
LoadedScriptInfo _scriptInfo = (LoadedScriptInfo)_it.next();
System.err.println(__me + ": Runtime loaded script:\n" +
_scriptInfo.dumpAll());
}
// get instance of the script we want (either user-supplied or first
// encountered), and tell user about it.
ScriptHandle _script = _lobo.getScriptInstance(_scriptName, _scriptVersion);
if (null == _script) {
if (null != _scriptName) {
System.err.println(__me + ": *** no script named \"" +
_scriptName+ "\" found in input file!");
}
if (null != _scriptVersion) {
System.err.println(__me + ": *** no script of version " +
_scriptVersion + " found in input file!");
}
}
System.err.println(__me + ": Selected this script: " +
_script.getScriptInfo().dumpAll() + "\n...");
// see if we can give the script all its input-requirements.
if (false == _script.setMissingInputRequirements(_args)) {
Set _missing = _script.getMissingInputRequirements();
System.err.println(__me + ": *** There are " + _missing.size() +
" missing " + "input symbols: " +
dumpIterator(_missing.iterator()));
System.err.println(__me + ": *** Please rectify and retry.");
System.exit(1);
}
// start script
System.err.println(__me + ": Starting script \"" + _scriptName +
"\" with " + _args.size() + " input arguments " +
dumpIterator(_args.keySet().iterator(), true) + " ...");
_script.startExecution();
try {
// main script handling event-loop
while (true) {
// wait for a particular status change (available results,
// or more input needed, as well as some defaults states,
// such as completion or error states).
int _status = _script.waitForStatus(
ScriptHandle.STATUS_ARGUMENTS_REQUIRED
| ScriptHandle.STATUS_RESULT_AVAILABLE);
// status has changed, now see what it is
if (0 != (_status & ScriptHandle.STATUS_ERROR_AVAILABLE)) {
// handle error flag
throw new RuntimeException(__me + ": Error status set");
}
if (0 != (_status & ScriptHandle.STATUS_RESULT_AVAILABLE)) {
// handle results availability
System.err.println(__me + ": Results available");
}
if (0 != (_status & ScriptHandle.STATUS_ARGUMENTS_REQUIRED)) {
// handle more missing input requirements: either supply
// more of user-supplied arguments, or complain and die.
Set _missing = _script.getMissingInputRequirements();
System.err.println(__me + ": Script require more input: " +
dumpIterator(_missing.iterator()));
if (false == _script.setMissingInputRequirements(_args)) {
_missing = _script.getMissingInputRequirements();
System.err.println(__me + ": ERROR: There are " +
"still " + _missing.size() + " missing " +
"input symbols: " +
dumpIterator(_missing.iterator()));
System.err.println("\nPlease rectify and retry.");
System.exit(1);
}
System.err.println(__me + ": Required input provided, continuing.");
_script.continueExecution();
}
if (0 != (_status & ScriptHandle.STATUS_DONE)) {
// handle completion.
System.err.println("\n" + __me + ": Script is done.");
break;
}
}
// obtain any results from the script, and tell user about these
Map _resultSpec = _script.getResultSpecification();
System.out.println(__me + ": Script \"" + _scriptName +
"\" returned " + _resultSpec.size() + " values: ");
int _count = 1;
for (Iterator _it = _resultSpec.keySet().iterator(); _it.hasNext();) {
String _symName = (String)_it.next();
ReturnValue _sym = _script.getSymbol(_symName);
System.out.print(" " + (_count++) + " ReturnValue \"" +
_symName + "\"");
if (null == _sym || null == _sym.getValue()) {
System.out.println(" has NO value set!");
} else {
System.out.println(" = " + _sym.dumpValue());
}
}
} catch (ObolException e) {
int [] _pos = _script.getCurrentPosition();
System.err.println(__me + "Caught " + e + " at " + _pos[0] + ":" + _pos[1]);
e.printStackTrace();
}
// we're done.
System.err.println("\n" + __me + ": Done.");
}
}
Generated by GNU enscript 1.6.4.