Source code for /engineering/autohit-2003/src/autohit/server/invoker/SimTextCommand.javaOriginal file SimTextCommand.java
   1 /**
   2  * AUTOHIT 2003
   3  * Copyright Erich P Gatejen (c) 1989,1997,2003
   4  * ALL RIGHTS RESERVED.  See license for details.
   5  * @author Erich P Gatejen
   6  */
   7 package autohit.server.invoker;
   8 
   9 import java.io.InputStream;
  10 
  11 import autohit.common.AutohitProperties;
  12 import autohit.common.AutohitErrorCodes;
  13 import autohit.common.AutohitLogInjectorWrapper;
  14 import autohit.common.CommandLine;
  15 import autohit.common.channels.Injector;
  16 import autohit.common.channels.SimpleInjector;
  17 import autohit.server.ServerException;
  18 import autohit.server.SystemContext;
  19 import autohit.server.command.Command;
  20 import autohit.server.command.CommandAtom;
  21 import autohit.server.command.CommandServer;
  22 import autohit.vm.VMExecutableWrapper;
  23 
  24 /**
  25  * Text command processor for SimVM. It'll create the command atoms and return
  26  * them.
  27  * <p>
  28  * 
  29  * <pre>
  30  *  compile(name) - force compile a script dump(name) - dump an compiled object run(name) {
  31  *  	vm }
  32  *  -spawn a script into an automat ps
  33  *  	- process list by PID kill(PID)
  34  *  	- kill processes exit
  35  *  	- exit props
  36  *  	- list properties set
  37  *  	- set a property name =
  38  *  	{ value }
  39  * </pre>
  40  * 
  41  * <p>
  42  * Only handles VMExecutable compiles now. Compiles to cache space.
  43  * 
  44  * @author Erich P. Gatejen
  45  * @version 1.0 <i>Version History</i><code>EPG - Initial - 25Apr03
  46  */
  47 public class SimTextCommand {
  48 
  49 	/**
  50 	 * Command dictionary. IMPORTANT! The command tokens must match the numbers
  51 	 * in the CommandRegistry!
  52 	 */
  53 
  54 	public final static int TOKEN_COMMAND_BAD = 0;
  55 	public final static String COMMAND_COMPILE = "com";
  56 	public final static int COMMAND_COMPILE_TOKEN = 1;
  57 
  58 	public final static String COMMAND_DUMP = "dum";
  59 	public final static int COMMAND_DUMP_TOKEN = 2;
  60 
  61 	public final static String COMMAND_RUN = "run";
  62 	public final static int COMMAND_RUN_TOKEN = 3;
  63 
  64 	public final static String COMMAND_PS = "ps";
  65 	public final static int COMMAND_PS_TOKEN = 4;
  66 
  67 	public final static String COMMAND_KILL = "kill";
  68 	public final static int COMMAND_KILL_TOKEN = 5;
  69 
  70 	public final static String COMMAND_PROPS = "props";
  71 	public final static int COMMAND_PROPS_TOKEN = 6;
  72 
  73 	public final static String COMMAND_SET = "set";
  74 	public final static int COMMAND_SET_TOKEN = 7;
  75 
  76 	public final static String COMMAND_LOADPROPS = "loadprops";
  77 	public final static int COMMAND_LOADPROPS_TOKEN = 8;
  78 	
  79 	public final static String COMMAND_SAVEPROPS = "saveprops";
  80 	public final static int COMMAND_SAVEPROPS_TOKEN = 9;
  81 	
  82 	// Special case. Says we are done.
  83 	public final static String COMMAND_EXIT = "exit";
  84 
  85 	public final static int TOKEN_COMMAND_CORRUPT = 99999;
  86 
  87 	protected SystemContext sc;
  88 	protected CommandServer cServer;
  89 
  90 	private AutohitLogInjectorWrapper log;
  91 	private Injector controlInjector;
  92 	private Injector clientInjector;
  93 	private String stc_id = null; // object unique ID
  94 
  95 	/**
  96 	 *  Default constructor */
  97 	public SimTextCommand() {
  98 		sc = null;
  99 		log = null;
 100 	}
 101 
 102 	/**
 103 	 * Initialize with defaults. It'll use the default SystemContext injectors
 104 	 * which are tied to the AutohitLogManager. You can call this as often as
 105 	 * you want, but must be called at least once.
 106 	 * 
 107 	 * @param c
 108 	 *           the SystemContext
 109 	 */
 110 	public void init(SystemContext c) throws Exception {
 111 
 112 		sc = c;
 113 		log = c.getRootLogger();
 114 
 115 		// Default control injector is the root
 116 		try {
 117 			SimpleInjector __controlInjector;
 118 			__controlInjector = (SimpleInjector)log.sinjector;
 119 			__controlInjector.setDefaultSenderID(AutohitProperties.SYSTEM_COMMANDCONTROL_ID);
 120 			controlInjector = __controlInjector;
 121 		} catch (Exception eeee) {
 122 			// Means someone is using something other than a simple logger
 123 			// for the root.  This is ok, but it is up to them to handle
 124 			// setting the default ID!
 125 			controlInjector = log.sinjector;
 126 		}	
 127 
 128 		// Create a default client injector
 129 		stc_id = Integer.toString(c.uniqueInteger());
 130 		SimpleInjector __clientInjector = new SimpleInjector();
 131 		__clientInjector.setDefaultSenderID(AutohitProperties.SYSTEM_COMMANDRESPONSE_ID);
 132 		clientInjector = __clientInjector;
 133 		c.getLogManager().addClient(clientInjector, stc_id);
 134 	}
 135 
 136 	/**
 137 	 * Initialize. Specify the contol and client channels. You can call this as
 138 	 * often as you want, but must be called at least once.
 139 	 * 
 140 	 * @param control
 141 	 *           Control injector
 142 	 * @param client
 143 	 *           Client injector
 144 	 * @param c
 145 	 *           the SystemContext
 146 	 */
 147 	public void init(SystemContext c, Injector control, Injector client) throws Exception {
 148 		sc = c;
 149 		log = c.getRootLogger();
 150 
 151 		// Default control injector is the root
 152 		controlInjector = control;
 153 
 154 		// Create a default client injector
 155 		clientInjector = client;
 156 
 157 		// was there a prior default client
 158 		if (stc_id != null) {
 159 			// discard the client
 160 			sc.getLogManager().discardClient(stc_id);
 161 			stc_id = null;
 162 		}
 163 	}
 164 
 165 	/**
 166 	 * This will create a command atom based on the command passed
 167 	 * 
 168 	 * @param command
 169 	 *           textual command
 170 	 * @throws ServerException.
 171 	 *            It will throw a AutohitErrorCodes.CODE_SERVER_DONE if given
 172 	 *            the exit command.
 173 	 * @return CommandAtom
 174 	 */
 175 	public CommandAtom create(String command) throws ServerException {
 176 
 177 		CommandAtom a = null;
 178 		CommandLine cl = new CommandLine();
 179 		cl.start(command);
 180 
 181 		// Check the context
 182 		if (log == null) {
 183 			throw new ServerException(
 184 				"Command ERROR: Bad context or context not set.",
 185 				ServerException.CODE_SERVER_BAD_CONTEXT_FAULT);
 186 		}
 187 
 188 		// Parse command and run
 189 		try {
 190 			String cmd = cl.get();
 191 
 192 			if (cmd.startsWith(COMMAND_COMPILE)) {
 193 				a = compile(cl);
 194 			} else if (cmd.startsWith(COMMAND_DUMP)) {
 195 				a = dump(cl);
 196 			} else if (cmd.startsWith(COMMAND_RUN)) {
 197 				a = run(cl);
 198 			} else if (cmd.startsWith(COMMAND_PS)) {
 199 				a = ps(cl);
 200 			} else if (cmd.startsWith(COMMAND_KILL)) {
 201 				a = kill(cl);
 202 			} else if (cmd.startsWith(COMMAND_PROPS)) {
 203 				a = props(cl);
 204 			} else if (cmd.startsWith(COMMAND_SAVEPROPS)) {
 205 				a = saveprops(cl);			
 206 			} else if (cmd.startsWith(COMMAND_LOADPROPS)) {
 207 				a = loadprops(cl);				
 208 			} else if (cmd.startsWith(COMMAND_SET)) {
 209 				a = set(cl);
 210 			} else if (cmd.startsWith(COMMAND_EXIT)) {
 211 				throw new ServerException("Command EXIT!", AutohitErrorCodes.CODE_SERVER_DONE);
 212 			} else {
 213 				log.error("Command ERROR:Unknown command.", AutohitErrorCodes.CODE_COMMAND_UNKNOWN);
 214 			}
 215 
 216 		} catch (ServerException se) {
 217 			throw se;
 218 
 219 		} catch (Exception e) {
 220 			//log.error("Command ERROR:Command corrupt.", AutohitErrorCodes.CODE_COMMAND_UNKNOWN);
 221 			// empty line.  ignore it
 222 		}
 223 		return a;
 224 	}
 225 
 226 	// Format helpers
 227 	private void error(String name, String message) {
 228 		log.error("Command:" + name + ":ERROR!  " + message, AutohitErrorCodes.CODE_COMMAND_ERROR);
 229 	}
 230 
 231 	// Format helpers
 232 	private void info(String name, String message) {
 233 		log.info("Command:" + name + ": " + message, AutohitErrorCodes.CODE_INFORMATIONAL_OK);
 234 	}
 235 
 236 	// Format helpers
 237 	private void finished(String name, String r) {
 238 		log.debug("Command:" + name + ":Finshed.  Receipt value=" + r, AutohitErrorCodes.CODE_DEBUGGING);
 239 	}
 240 
 241 	/**
 242 	 * Compile helper */
 243 	private CommandAtom compile(CommandLine cli) throws ServerException {
 244 
 245 		CommandAtom response = null;
 246 		try {
 247 			// Check params
 248 			String source = cli.get();
 249 			if (source == null) {
 250 				error("compile", "Required parameter 'name' missing.");
 251 				return null;
 252 			}
 253 
 254 			// Build it.
 255 			response =
 256 				new CommandAtom(
 257 					COMMAND_COMPILE_TOKEN,
 258 					Command.createCommand(sc.getUniverse(), controlInjector, clientInjector, null, source, null));
 259 
 260 		} catch (Exception e) {
 261 			error("compile", "Compile command creation failed.  " + e.getMessage());
 262 		}
 263 		return response;
 264 	}
 265 
 266 	/**
 267 	 * Dump helper */
 268 	private CommandAtom dump(CommandLine cli) throws ServerException {
 269 
 270 		InputStream is;
 271 		String data = null;
 272 		VMExecutableWrapper ob;
 273 
 274 		CommandAtom response = null;
 275 		try {
 276 
 277 			// Check params
 278 			String source = cli.get();
 279 			if (source == null) {
 280 				error("dump", "Required parameter 'name' missing.");
 281 				return null;
 282 			}
 283 			response =
 284 				new CommandAtom(
 285 					COMMAND_DUMP_TOKEN,
 286 					Command.createCommand(sc.getUniverse(), controlInjector, clientInjector, null, source, null));
 287 
 288 		} catch (Exception e) {
 289 			error("dump", "Dump command creation failed.  " + e.getMessage());
 290 		}
 291 		return response;
 292 	}
 293 
 294 	/**
 295 	 * Save props helper */
 296 	private CommandAtom saveprops(CommandLine cli) throws ServerException {
 297 
 298 		InputStream is;
 299 		String data = null;
 300 
 301 		CommandAtom response = null;
 302 		try {
 303 
 304 			// Check params
 305 			String source = cli.get();
 306 			if (source == null) {
 307 				error("saveprops", "Required parameter 'universe destination' missing.");
 308 				return null;
 309 			}
 310 			response =
 311 			new CommandAtom(
 312 					COMMAND_SAVEPROPS_TOKEN,
 313 					Command.createCommand(sc.getUniverse(), controlInjector, clientInjector, null, source, null));
 314 
 315 		} catch (Exception e) {
 316 			error("saveprops", "Saveprops command creation failed.  " + e.getMessage());
 317 		}
 318 		return response;
 319 	}
 320 	
 321 	
 322 
 323 	/**
 324 	 * Load props helper */
 325 	private CommandAtom loadprops(CommandLine cli) throws ServerException {
 326 
 327 		InputStream is;
 328 		String data = null;
 329 
 330 		CommandAtom response = null;
 331 		try {
 332 
 333 			// Check params
 334 			String source = cli.get();
 335 			if (source == null) {
 336 				error("loadprops", "Required parameter 'universe source' missing.");
 337 				return null;
 338 			}
 339 			response =
 340 			new CommandAtom(
 341 					COMMAND_LOADPROPS_TOKEN,
 342 					Command.createCommand(sc.getUniverse(), controlInjector, clientInjector, null, source, null));
 343 
 344 		} catch (Exception e) {
 345 			error("loadprops", "Loadprops command creation failed.  " + e.getMessage());
 346 		}
 347 		return response;
 348 	}
 349 	
 350 	
 351 	/**
 352 	 * Run helper */
 353 	private CommandAtom run(CommandLine cli) throws ServerException {
 354 		CommandAtom response = null;
 355 
 356 		try {
 357 			// Check required param
 358 			String source = cli.get();
 359 			if (source == null) {
 360 				error("run", "Required parameter 'name' missing.");
 361 				return null;
 362 			}
 363 
 364 			// See if they specified the VM class
 365 			String vm = cli.get();
 366 			if (vm == null)
 367 				vm = "autohit.vm.SimVM";
 368 
 369 			// build command
 370 			response =
 371 				new CommandAtom(
 372 					COMMAND_RUN_TOKEN,
 373 					Command.createCommand(sc.getUniverse(), controlInjector, clientInjector, vm, source, null));
 374 
 375 		} catch (Exception e) {
 376 			error("run", "RUN command creation failed.  message=" + e.getMessage());
 377 		}
 378 		return response;
 379 	}
 380 
 381 	/**
 382 	 * PS helper */
 383 	private CommandAtom ps(CommandLine cli) throws ServerException {
 384 
 385 		CommandAtom response = null;
 386 		try {
 387 			response = new CommandAtom(COMMAND_PS_TOKEN, Command.createCommand(null, controlInjector, clientInjector, null, null, null));
 388 
 389 		} catch (Exception e) {
 390 			error("ps", "PS command creation failed.  " + e.getMessage());
 391 		}
 392 		return response;
 393 	}
 394 
 395 	/**
 396 	 * Kill helper */
 397 	private CommandAtom kill(CommandLine cli) throws ServerException {
 398 
 399 		CommandAtom response = null;
 400 		try {
 401 
 402 			// Check params
 403 			String source = cli.get();
 404 			if (source == null) {
 405 				error("kill", "Required parameter 'PID' missing.");
 406 				return null;
 407 			}
 408 
 409 			// Build it.
 410 			response =
 411 				new CommandAtom(
 412 					COMMAND_KILL_TOKEN,
 413 					Command.createCommand(null, controlInjector, null, null, source, null));
 414 
 415 		} catch (Exception e) {
 416 			error("kill", "Kill command creation failed.  " + e.getMessage());
 417 		}
 418 		return response;
 419 	}
 420 
 421 	/**
 422 	 * PS helper */
 423 	private CommandAtom props(CommandLine cli) throws ServerException {
 424 
 425 		CommandAtom response = null;
 426 		try {
 427 			response = new CommandAtom(COMMAND_PROPS_TOKEN, Command.createCommand(null, controlInjector, clientInjector, null, null, null));
 428 
 429 		} catch (Exception e) {
 430 			error("props", "Invoker command properties list creation failed.  " + e.getMessage());
 431 		}
 432 		return response;
 433 	}
 434 
 435 	/**
 436 	 * Set helper */
 437 	private CommandAtom set(CommandLine cli) throws ServerException {
 438 
 439 		CommandAtom response = null;
 440 		try {
 441 
 442 			// Check params
 443 			String source = cli.get();
 444 			if (source == null) {
 445 				error("set", "Required parameter 'name=value pair' missing.");
 446 				return null;
 447 			}
 448 			if (source.indexOf('=') < 1)
 449 				throw new NumberFormatException();
 450 
 451 			// Build it
 452 			response =
 453 				new CommandAtom(
 454 					COMMAND_SET_TOKEN,
 455 					Command.createCommand(sc.getUniverse(), controlInjector, clientInjector, null, source, null));
 456 		} catch (IndexOutOfBoundsException ie) {
 457 			error(
 458 				"set",
 459 				"Set command creation failed.  No name/value string given.  It should be in the form 'name=..text..'");
 460 		} catch (Exception e) {
 461 			error("set", "Set command creation failed.  " + e.getMessage());
 462 		}
 463 		return response;
 464 	}
 465 
 466 	/**
 467 	 * finalizer Clear anything we don't need */
 468 	protected void finalize() throws Throwable {
 469 		super.finalize();
 470 		log.debug("SimTextCommand: Exiting.  closing any connections and channels.", AutohitErrorCodes.CODE_DEBUGGING);
 471 
 472 		// was there a prior default client
 473 		if (stc_id != null) {
 474 			// discard the client
 475 			sc.getLogManager().discardClient(stc_id);
 476 		}
 477 	}
 478 
 479 }