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 }
|