Source code for /engineering/autohit-2003/src/autohit/call/Call.javaOriginal file Call.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;
  22 
  23 import autohit.server.SystemContext;
  24 import autohit.universe.Universe;
  25 import autohit.vm.VMCore;
  26 import autohit.common.AutohitLogInjectorWrapper;
  27 
  28 /**
  29  * The abstract class to all the callable functions. Every CALL should
  30  * implement this. The call will get passed parameters by name out of core.
  31  * IMPORTANT!!!! Calls should not have any fields! Those that are already
  32  * provided are inherently thread safe. Calls are cached per VM and reused as
  33  * often as possible. There will be no thread-safety issues with the VMCore or
  34  * log, but the SystemContecxt and Universe may be shared.
  35  * 
  36  * @author Erich P. Gatejen
  37  * @version 1.1 <i>Version History</i><code>EPG - Initial - 14May03<br>
  38  * EPG - reorganize to make Call the base class - 10Sep03</code>
  39  */
  40 public abstract class Call {
  41 
  42 	public final static String CALL_TEXT_HEADER = "call:";
  43 
  44 	/**
  45 	 * Core */
  46 	public VMCore vmc;
  47 
  48 	/**
  49 	 * System Context */
  50 	public SystemContext sc;
  51 
  52 	/**
  53 	 * Primary Logger */
  54 	public AutohitLogInjectorWrapper log;
  55 
  56 	/**
  57 	 * Our simple little universe. */
  58 	public Universe u;
  59 
  60 	/**
  61 	 * Implement this to handle load time initialization. The four main fields
  62 	 * will already be set--vmc, sc, log, and u. You must implement this, but
  63 	 * you don't have to do anything. Remember that calls are cached per VM and
  64 	 * reused as often as possible. There will be no thread-safety issues with
  65 	 * the VMCore or log, but the SystemContecxt and Universe may be shared.
  66 	 * @throws CallException
  67 	 */
  68 	public abstract void load_chain() throws CallException;
  69 
  70 	/**
  71 	 * Implement this to return the name of the CALL
  72 	 * @return name of the CALL
  73 	 */
  74 	public abstract String name();
  75 
  76 	/**
  77 	 * Execute it.
  78 	 * 
  79 	 * @return the result or null if there is no result
  80 	 */
  81 	public abstract String call() throws CallException;
  82 
  83 	/**
  84 	 * Execute using the passed universe, rather than the loaded.
  85 	 * @param uni
  86 	 *           a universe
  87 	 * @return the result or null if there is no result
  88 	 * @see autohit.universe.Universe
  89 	 */
  90 	public abstract String call(Universe uni) throws CallException;
  91 
  92 	// METHODS
  93 
  94 	/**
  95 	 * This will be called to set references to the environment and usable Universe.
  96 	 * 
  97 	 * @param core
  98 	 *           is a reference to the environment core
  99 	 * @param sctx
 100 	 *           is a system context
 101 	 * @param logger
 102 	 *           the log target
 103 	 * @see autohit.vm.VMCore
 104 	 * @see autohit.server.SystemContext
 105 	 */
 106 	public void load(VMCore core, SystemContext sctx, AutohitLogInjectorWrapper logger) throws CallException {
 107 		log = logger;
 108 		vmc = core;
 109 		sc = sctx;
 110 		u = sc.getUniverse();
 111 		this.load_chain();
 112 	}
 113 
 114 	// SERVICES
 115 
 116 	/**
 117 	 * Log a debugging statement.
 118 	 * 
 119 	 * @param text
 120 	 *           The text of the statement.
 121 	 */
 122 	public void debug(String text) {
 123 		if (log.debugState())
 124 			log.debug(CALL_TEXT_HEADER + this.name() + ':' + text, CallException.CODE_DEBUGGING_CALLS);
 125 	}
 126 
 127 	/**
 128 	 * Log an error statement.
 129 	 * 
 130 	 * @param text
 131 	 *           The text of the statement.
 132 	 */
 133 	public void error(String text) {
 134 		log.error(CALL_TEXT_HEADER + this.name() + ':' + text, CallException.CODE_CALL_ERROR);
 135 	}
 136 
 137 	/**
 138 	 * Log an info statement.
 139 	 * 
 140 	 * @param text
 141 	 *           The text of the statement.
 142 	 */
 143 	public void info(String text) {
 144 		log.error(CALL_TEXT_HEADER + this.name() + ':' + text, CallException.CODE_INFORMATIONAL_OK_VERBOSE);
 145 	}
 146 
 147 	/**
 148 	 * Return a formatted text. Useful for making Exception messages.
 149 	 * 
 150 	 * @param text
 151 	 *           The text of the statement.
 152 	 * @return the formatted text.
 153 	 */
 154 	public String format(String text) {
 155 		return CALL_TEXT_HEADER + this.name() + ':' + text;
 156 	}
 157 
 158 	/**
 159 	 * Get a desired parameter.  If it is not found, it will post an error and return null.
 160 	 * 
 161 	 * @param item
 162 	 *           Name of the parameter
 163 	 * @return the object or null
 164 	 */
 165 	public Object desired(String item) {
 166 		Object thang = null;
 167 		try {
 168 			thang = (String) vmc.fetch(item);
 169 		} catch (Exception e) {
 170 			// dont care. null will cause error
 171 		}
 172 		if (thang == null) {
 173 			this.debug("Parameter " + item + " not given.");
 174 		}
 175 		return thang;
 176 	}
 177 
 178 	/**
 179 	 * Get a desired parameter. If it is not found or is not a String, it will post an error and return null.
 180 	 * 
 181 	 * @param item
 182 	 *           Name of the parameter
 183 	 * @return the string
 184 	 */
 185 	public String desiredString(String item) {
 186 		Object thang = null;
 187 		try {
 188 			thang = (String) vmc.fetch(item);
 189 		} catch (Exception e) {
 190 			// dont care. null will cause error
 191 		}
 192 		if (thang == null) {
 193 			this.error("Parameter " + item + " not given.");
 194 		} else if (!(thang instanceof String)) {
 195 			this.error("Parameter " + item + " found but not a String.");
 196 			thang = null;
 197 		}
 198 		return (String) thang;
 199 	}
 200 
 201 	/**
 202 	 * Get a optional parameter. If it is found but is not a String, it will post an error and return null. If it is not found, it will just return null, without and error.
 203 	 * 
 204 	 * @param item
 205 	 *           Name of the parameter
 206 	 * @return the string
 207 	 */
 208 	public String optionalString(String item) {
 209 		Object thang = null;
 210 		try {
 211 			thang = (String) vmc.fetch(item);
 212 		} catch (Exception e) {
 213 			// dont care. null will cause error
 214 		}
 215 		if ((thang != null) && !(thang instanceof String)) {
 216 			this.error("Parameter " + item + " found but not a String.");
 217 			thang = null;
 218 		}
 219 		return (String) thang;
 220 	}
 221 
 222 	/**
 223 	 * Get a required parameter.  If it is not found, it will throw an exception.
 224 	 * 
 225 	 * @param item
 226 	 *           Name of the parameter
 227 	 * @return the object
 228 	 * @throws CallException
 229 	 */
 230 	public Object required(String item) throws CallException {
 231 		Object thang = null;
 232 		try {
 233 			thang = (String) vmc.fetch(item);
 234 		} catch (Exception e) {
 235 			// the null will express this
 236 		}
 237 		if (thang == null) {
 238 			throw new CallException(
 239 				this.format("Paramter " + item + " not given."),
 240 				CallException.CODE_CALL_REQUIRED_PARAM_MISSING_FAULT);
 241 		}
 242 		return thang;
 243 	}
 244 
 245 	/**
 246 	 * Get a required parameter that must be a String. If it is not found or it is not a String, it will throw an exception.
 247 	 * 
 248 	 * @param item
 249 	 *           Name of the parameter
 250 	 * @return the string
 251 	 * @throws CallException
 252 	 */
 253 	public String requiredString(String item) throws CallException {
 254 		return (String) this.required(item, String.class);
 255 	}
 256 
 257 	/**
 258 	 * Get a required parameter.  If it is not found, it will throw an exception. It will also make sure it is a certain class type. If not, it will throw an exception.
 259 	 * 
 260 	 * @param item
 261 	 *           Name of the parameter
 262 	 * @param classtype
 263 	 *           Class is should be.
 264 	 * @return the object
 265 	 * @throws CallException
 266 	 */
 267 	public Object required(String item, Class classtype) throws CallException {
 268 		Object thing = this.required(item);
 269 		if (!(classtype.isInstance(thing))) {
 270 			throw new CallException(
 271 				this.format("Parameter " + item + " not required type.  required=" + classtype.getName()),
 272 				CallException.CODE_CALL_REQUIRED_PARAM_CLASSMISMATCH_FAULT);
 273 		}
 274 		return thing;
 275 	}
 276 
 277 	/**
 278 	 * Get a required persist object. If it is not found, it will throw an exception. It will also make sure it is a certain class type. If not, it will throw an exception.
 279 	 * @param item
 280 	 *           Name of the parameter
 281 	 * @param classtype
 282 	 *           Class is should be.
 283 	 * @return the object
 284 	 * @throws CallException
 285 	 */
 286 	public Object requiredPersist(String item, Class classtype) throws CallException {
 287 
 288 		Object thing = null;
 289 
 290 		try {
 291 			thing = (Object) vmc.get(item);
 292 			this.debug("Persist object named " + item + "found.");
 293 		} catch (Exception iii) {
 294 			// the null will express this.
 295 		}
 296 
 297 		// See if we got it and it is ok.
 298 		if (thing == null) {
 299 			throw new CallException(
 300 				this.format("Object named " + item + "does not exist in persist."),
 301 				CallException.CODE_CALL_PERSISTNOTFOUND_FAULT);
 302 
 303 		} else if (!(classtype.isInstance(thing))) {
 304 			throw new CallException(
 305 				this.format("Persist object named " + item + "found but it is not the right type."),
 306 				CallException.CODE_CALL_PERSISTMISMATCH_FAULT);
 307 		}
 308 		return thing;
 309 	}
 310 
 311 }