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.call.modules;
22
23 import autohit.common.AutohitErrorCodes;
24 import autohit.common.AutohitLogInjectorWrapper;
25 import autohit.universe.Universe;
26 import autohit.vm.VMCore;
27 import autohit.call.CallException;
28 import autohit.server.SystemContext;
29
30 /**
31 * The abstract base class for modules. Every module must implement this.
32 * <p>
33 * An implemented module needs to complete the following abstract methods:
34 * execute_chain - run a named method.<br>
35 * instantiation_chain() - called at module instantiation<br>
36 * free_chain() - called at module destruction<br>
37 * <p>
38 * All protected methods are helpers for the execute.
39 * <p>
40 * Modules are not allowed to have methods called "name"
41 *
42 * @author Erich P. Gatejen
43 * @version 1.0
44 * <i>Version History</i>
45 * <code>EPG - Initial - 14Jun03<br>
46 * EPG - make SC visible - 3 Sep03</code>
47 *
48 */
49 public abstract class Module {
50
51 // Services visible to the implementor
52 protected VMCore visCore;
53 protected Universe visUniverse;
54 protected AutohitLogInjectorWrapper visLogger;
55 protected String myName = "GenericModule";
56 protected SystemContext visSC;
57
58 /**
59 * Instantiate
60 * @param core is a reference to the environment core
61 * @param uni is the default universe
62 * @param logger is the default logger
63 * @see autohit.vm.VMCore
64 * @see autohit.universe.Universe
65 * @see autohit.common.AutohitLogInjectorWrapper
66 * @throws CallException
67 */
68 public void instance(VMCore core, Universe uni, AutohitLogInjectorWrapper logger, SystemContext sctx)
69 throws CallException {
70 visCore = core;
71 visUniverse = uni;
72 visLogger = logger;
73 visSC = sctx;
74
75 logger.debug(
76 "MODULE: invoke instance.",
77 CallException.CODE_DEBUGGING_CALLS);
78
79 try {
80 myName = this.instantiation_chain();
81 } catch (CallException e) {
82 throw e;
83 } catch (Exception ex) {
84 // Catch any wildassed exceptions
85 throw new CallException(
86 "MODULE: instantiate module has a runaway exception. The module is invalid. exception="
87 + ex.getMessage(),
88 CallException.CODE_CALL_INTENTIONAL_FAULT);
89 }
90 }
91
92 /**
93 * Remove an instance
94 * @throws CallException
95 */
96 public void free() throws CallException {
97
98 // nothing else to do right now
99 try {
100 this.free_chain();
101 } catch (CallException e) {
102 throw e;
103 } catch (Exception ex) {
104 // Catch any wildassed exceptions
105 throw new CallException(
106 "module:" + myName + ":free module has a runaway exception. The module is invalid. exception="
107 + ex.getMessage(),
108 CallException.CODE_CALL_INTENTIONAL_FAULT);
109 }
110 }
111
112 /**
113 * Execute a method
114 * @param methodName the name of the method
115 * @return any resultant object String
116 * @throws CallException
117 */
118 public String execute(String methodName) throws CallException {
119
120 Object thang = null;
121
122 // Abstracting for future use.
123 try {
124 thang = this.execute_chain(methodName);
125 } catch (CallException e) {
126 throw e;
127 } catch (Exception ex) {
128 // Catch any wildassed exceptions
129 throw new CallException(
130 "module:" + myName + ":method " + methodName + " had a FAULT. message="
131 + ex.getMessage(),
132 CallException.CODE_CALL_INTENTIONAL_FAULT);
133 }
134
135 if (!(thang instanceof String)) {
136 throw new CallException(
137 "module:" + myName + ":method " + methodName + " returned something other than String.",
138 CallException.CODE_CALL_INTENTIONAL_FAULT);
139 }
140 return (String) thang;
141 }
142
143 // HELPERS TO THE SUBCLASS
144
145 /**
146 * report if we are debugging (as an accellerator)
147 * @return parameter value or null if not found
148 */
149 protected boolean isDebugging() {
150 return visLogger.debugState();
151 }
152
153 /**
154 * Get a parameter
155 * @param name of the parameter
156 * @return parameter value or null if not found
157 */
158 protected Object getParam(String name) {
159 Object thang = null;
160
161 try {
162
163 if (visCore.exists(name))
164 thang = visCore.fetch(name);
165
166 } catch (Exception e) {
167 // it's already null
168 }
169 return thang;
170 }
171
172 /**
173 * Get a persisted object
174 * @param name of the object in the persist
175 * @return parameter value or null if not found
176 */
177 protected Object getPersist(String name) {
178 Object thang = null;
179
180 try {
181
182 if (visCore.has(name))
183 thang = visCore.get(name);
184
185 } catch (Exception e) {
186 // it's already null
187 }
188 return thang;
189 }
190
191 /**
192 * Local method for logging an event
193 * @param msg event message
194 */
195 protected void log(String msg) {
196 visLogger.info(
197 "module:" + myName + ":" + msg,
198 AutohitErrorCodes.CODE_MODULE_REPORTED_INFO_OK);
199 }
200
201 /**
202 * Local method for logging an error
203 * @param msg event message
204 */
205 protected void error(String msg) {
206 visLogger.error(
207 "module:" + myName + ":ERROR " + msg,
208 AutohitErrorCodes.CODE_MODULE_REPORTED_ERROR);
209 }
210
211 /**
212 * Local method for logging an error for a missing param.
213 * @param missing name of paramater missing
214 * @param method name of method called
215 */
216 protected void errorparam(String missing, String method) {
217 visLogger.error(
218 "module:" + myName + ":ERROR. Missing '" + missing +
219 "' parameter for '" + method + " method. Aborting.",
220 AutohitErrorCodes.CODE_MODULE_REPORTED_ERROR);
221 }
222
223
224 /**
225 * Local method for logging an warning
226 * @param msg event message
227 */
228 protected void warning(String msg) {
229 visLogger.error(
230 "module:" + myName + ":WARNING " + msg,
231 AutohitErrorCodes.CODE_MODULE_REPORTED_WARNING);
232 }
233
234 /**
235 * Local method for logging debug information
236 * @param msg event message
237 */
238 protected void debug(String msg) {
239 visLogger.debug(
240 "module:" + myName + ":DEBUG " + msg,
241 AutohitErrorCodes.CODE_DEBUGGING_MODULES);
242 }
243
244 /**
245 * Build a call exception with our formatting
246 * @param message text of the message
247 * @param code the autohit error code (also available in CallException)
248 * @return a CallException
249 * @see autohit.call.CallException
250 * @see autohit.common.AutohitErrorCodes
251 */
252 protected CallException buildException(String message, int code) {
253 return new CallException("module:" + myName + ":" + message, code);
254 }
255
256 /**
257 * Cause a fault
258 * @param message text of the message
259 * @throws a CallException
260 * @see autohit.call.CallException
261 */
262 protected void fault(String message) throws CallException {
263 throw this.buildException(message, CallException.CODE_MODULE_FAULT);
264 }
265
266 /**
267 * Cause a fault with CHAIN
268 * @param message text of the message
269 * @throws a CallException
270 * @see autohit.call.CallException
271 */
272 protected void fault(String message, Throwable t) throws CallException {
273 throw this.buildException(message, CallException.CODE_MODULE_FAULT, t);
274 }
275
276 /**
277 * Build a call exception with our formatting - chained
278 * @param message text of the message
279 * @param code the autohit error code (also available in CallException)
280 * @param iec initiating exception
281 * @return a CallException
282 * @see autohit.call.CallException
283 * @see autohit.common.AutohitErrorCodes
284 */
285 protected CallException buildException(
286 String message,
287 int code,
288 Throwable iec) {
289 return new CallException("module:" + myName + ":" + message, code, iec);
290 }
291
292 /**
293 * Required parameter. This one requires the parameter to be a string.
294 * If it is not present or is not a String, it is a serious fault
295 * @param param parameter name
296 * @param method method being called. Used for error reporting.
297 * @return String with the parameter value
298 * @throws CallException
299 */
300 protected String required(String param, String method) throws CallException {
301 Object thang = this.getParam(param);
302 if ((thang == null)||(!(thang instanceof String))) {
303 throw new CallException(
304 "module:"
305 + myName
306 + ":FAULT. Required parameter'"
307 + param
308 + "' missing (or not a String) from call to method '" + method + "'.",
309 CallException.CODE_CALL_FAULT);
310 }
311 return (String)thang;
312 }
313
314 /**
315 * Required parameter. This one requires the parameter to be of the type specified.
316 * If it is not present or is not the type, it is a serious fault
317 * @param param parameter name
318 * @param type the class of the type required
319 * @param method method being called. Used for error reporting.
320 * @return String with the parameter value
321 * @throws CallException
322 */
323 protected Object requiredType(String param, Class type, String method) throws CallException {
324 Object thang = this.getParam(param);
325 if ((thang == null)||( !(type.isInstance(thang)) )) {
326 throw new CallException(
327 "module:"
328 + myName
329 + ":FAULT. Required parameter'"
330 + param
331 + "' missing (or wrong type) from call to method '" + method + "'.", CallException.CODE_CALL_FAULT);
332 }
333 return thang;
334 }
335
336 /**
337 * Desired parameter. If it is not present, it is an error message
338 * @param param parameter name
339 * @param method method being called. Used for error reporting.
340 * @return String with the parameter value or null if it is not present
341 */
342 protected String desired(String param, String method) {
343 Object thang = this.getParam(param);
344 if (thang == null) {
345 error("Missing '" + param +
346 "' parameter for '" + method + "' method.");
347 } else if (!(thang instanceof String)) {
348 error("Wrong type for '" + param +
349 "' parameter for '" + method + "' method.");
350 thang = null;
351 }
352 return (String)thang;
353 }
354
355 /**
356 * Desired parameter. If it is not present, it is an error message.
357 * @param param parameter name
358 * @param type the class of the type desired
359 * @param method method being called. Used for error reporting.
360 * @return Object with the parameter value or null if it is not present or the wrong type.
361 */
362 protected Object desiredType(String param, Class type, String method) {
363 Object thang = this.getParam(param);
364 if (thang == null) {
365 error("Missing '" + param +
366 "' parameter for '" + method + "' method.");
367 } else if ( !(type.isInstance(thang)) ) {
368 error("Wrong type for '" + param +
369 "' parameter for '" + method + "' method.");
370 thang = null;
371 }
372 return thang;
373 }
374
375 /**
376 * Optional parameter. If it is not present, nothing happens. It expects
377 * a String. If result is something other than a String, it will return a null.
378 * @param param parameter name
379 * @return String with the parameter value or null if it is not present
380 */
381 protected String optional(String param) {
382 Object thang = this.getParam(param);
383 if ( (thang != null) && (!(thang instanceof String)) )thang = null;
384 return (String)thang;
385 }
386
387 /**
388 * Optional parameter. If it is not present, nothing happens. It expects
389 * the type specified. If result is something other than that type, it will return a null.
390 * @param param parameter name
391 * @param type the class of the type optional
392 * @return Object with the parameter value or null if it is not present
393 */
394 protected Object optionalType(String param, Class type) {
395 Object thang = this.getParam(param);
396 if ( (thang != null) && (!(type.isInstance(thang))) )thang = null;
397 return thang;
398 }
399
400 // IMPLEMENTORS
401
402 /**
403 * Execute a named method. You must implement this method.
404 * You can call any of the helpers for data and services.
405 * The returned object better be a string (for now). YOU MUST
406 * RETURN SOMETHING--and not null! If you don't, there will be an exception
407 * up the chain.
408 * @param name name of the method
409 * @see autohit.common.NOPair
410 * @throws CallException
411 */
412 public abstract Object execute_chain(String name) throws CallException;
413
414 /**
415 * Allow the subclass a chance to initialize. At a minium, an
416 * implementor should create an empty method.
417 * @return the name of the module
418 * @throws CallException
419 */
420 protected abstract String instantiation_chain() throws CallException;
421
422 /**
423 * Allow the subclass a chance to cleanup on free. At a minium, an
424 * implementor should create an empty method.
425 * @throws CallException
426 */
427 protected abstract void free_chain() throws CallException;
428
429 }
|