1 /**
2 * AUTOHIT 2003
3 * Copyright Erich P Gatejen (c) 1989,1997,2003,2004
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Additional license information can be found in the documentation.
19 * @author Erich P Gatejen
20 */
21 package autohit.server.service;
22
23 import java.io.BufferedReader;
24 import java.io.InputStreamReader;
25
26 import autohit.common.AutohitProperties;
27 import autohit.common.channels.Channel;
28 import autohit.common.channels.ChannelException;
29 import autohit.common.channels.Controller;
30 import autohit.common.channels.Injector;
31 import autohit.common.channels.SimpleInjector;
32 import autohit.server.invoker.SimTextCommand;
33 import autohit.server.ServerException;
34 import autohit.server.command.CommandAtom;
35
36 /**
37 * This as an interactive, STDIO based CLI. We'll use the AutohitLogManager for
38 * targets and responses. There can be only one instance of this service, since
39 * it hsa a unique injector.
40 * <p>
41 * The command channel (autohit.command) must be built before creating one of
42 * these!!!! CommandService will do that for you.
43 * <p>
44 *
45 * @author Erich P. Gatejen
46 * @version 1.0 <i>Version History</i><code>EPG - Initial - 19SEP03</code>
47 */
48 public class CLIService extends Service {
49
50 public final static String INJECTOR_NAME = AutohitProperties.COMMAND_SERVER_INJECTOR + ".CLIService";
51
52 /**
53 * Channel stuff */
54 private Channel commandChannel;
55 private Injector commandInjector;
56
57 /**
58 * Command stuff */
59 SimTextCommand cmd;
60 BufferedReader stdin = null;
61
62 /**
63 * Default constructor */
64 public CLIService() {
65 super();
66 }
67
68 /**
69 * Complete construction. This will be called when the VM is initialized.
70 */
71 public void construct() throws ServiceException {
72 try {
73
74 // Build command injector
75 commandInjector = new SimpleInjector();
76 commandChannel = Controller.tune(AutohitProperties.COMMAND_SERVER_STATION);
77 commandChannel.register(INJECTOR_NAME, commandInjector);
78
79 // Build a text command invoker
80 // local initialization
81 cmd = new SimTextCommand();
82 cmd.init(sc);
83
84 // Attach streams
85 stdin = new BufferedReader(new InputStreamReader(System.in));
86
87 } catch (ChannelException cce) {
88 throw new ServiceException(
89 "Failed to start CLIService due to Channel Exception. message=" + cce.getMessage(),
90 ServiceException.CODE_SERVICE_STARTUP_FAULT);
91 } catch (Exception ee) {
92 throw new ServiceException(
93 "Failed to start CLIService due to General Exception. message=" + ee.getMessage(),
94 ServiceException.CODE_SERVICE_STARTUP_FAULT);
95 }
96 }
97
98 /**
99 * Fast loop. We spend most of our time waiting for connections. Cycle back
100 * to VM only after an accept or a timeout.
101 * @see autohit.vm.VMException
102 */
103 public void execute() throws ServiceException {
104
105 boolean cont = true;
106 String currentLine;
107 CommandAtom a;
108
109 // open drain
110 while (cont == true) {
111
112 try {
113
114 // Get line and see if we get a command
115 currentLine = stdin.readLine();
116 if (currentLine == null)
117 break;
118 a = cmd.create(currentLine);
119
120 // loop if no command
121 if (a == null)
122 continue;
123
124 // dispatch it
125 commandInjector.post(a);
126
127 // ok
128 cont = false;
129
130 } catch (ServerException se) {
131 if (se.numeric == ServerException.CODE_SERVER_DONE) {
132 // Done. Bust loop.
133 throw new ServiceException(
134 "CLIService ordered to stop.",
135 ServiceException.CODE_SERVICE_INTENTIONAL_HALT,
136 se);
137 } else {
138 throw new ServiceException(
139 "CLIService Server error due to exception. code=" + se.numeric + " message=" + se.getMessage(),
140 ServiceException.CODE_SERVICE_GENERIC_ERROR);
141 }
142 } catch (ChannelException e) {
143 throw new ServiceException(
144 "CLIService Server HALTED because there is no command service running or command channel available. This may be intentional during a shutdown.",
145 ServiceException.CODE_SERVICE_PANIC);
146
147 } catch (Exception e) {
148 throw new ServiceException(
149 "CLIService Server PANIC due to unexpected exception. message=" + e.getMessage(),
150 ServiceException.CODE_SERVICE_PANIC);
151 }
152 }
153 }
154
155 /**
156 * Complete destroy. This will be called when the VM is finalizing. */
157 public void destruct() throws ServiceException {
158
159 }
160 }
|