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