Source code for /engineering/autohit-2003/src/autohit/call/modules/Module.javaOriginal file Module.java
   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 }