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;
22
23 import java.io.FileInputStream;
24 import java.io.FileOutputStream;
25
26 import org.apache.commons.collections.ExtendedProperties;
27
28 import autohit.common.AutohitBasicLogManager;
29 import autohit.common.AutohitErrorCodes;
30 import autohit.common.AutohitException;
31 import autohit.common.AutohitLogDrain;
32 import autohit.common.AutohitLogDrainDefault;
33 import autohit.common.AutohitLogDrainRouting;
34 import autohit.common.AutohitLogInjectorWrapper;
35 import autohit.common.AutohitProperties;
36 import autohit.common.Utils;
37 import autohit.common.channels.Controller;
38 import autohit.common.channels.Injector;
39 import autohit.creator.compiler.SimCompiler;
40 import autohit.creator.compiler.XmlCompiler;
41 import autohit.server.command.CommandRegistry;
42 import autohit.universe.Universe;
43 import autohit.universe.UniverseFactory;
44 import autohit.vm.VMLoader;
45
46 /**
47 * A simple system context for a server or invoker.
48 * <p><pre>
49 * It includes:
50 * a basic log manager (@see #logger)
51 * a root logger
52 * a basic properties set (@see #prop)
53 * a single script SIM compiler (@see #compiler)
54 * a universe factory (@see #uf)
55 * a LOCAL universe server
56 * a Kernel (uninitialized!)
57 * a root loader (uninitialized!)
58 * </pre><p>
59 * It requires the root property be set.
60 *
61 * @author Erich P. Gatejen
62 * @version 1.0
63 * <i>Version History</i>
64 * <code>EPG - Initial - 25Apr03
65 *
66 */
67 public class SimpleSystemContext implements SystemContext {
68
69 /**
70 * Primary log manager
71 */
72 public AutohitBasicLogManager logManager;
73
74 /**
75 * Root log injector
76 */
77 public AutohitLogInjectorWrapper logger;
78
79 /**
80 * Script compiler. Keep at least one around.
81 */
82 public SimCompiler compiler;
83
84 /**
85 * Our simple little universe.
86 */
87 public Universe uni;
88
89 /**
90 * The system properties set
91 */
92 public ExtendedProperties prop;
93
94 /**
95 * Invoker properties set
96 */
97 public ExtendedProperties invokerprop;
98
99 /**
100 * Universe factory
101 */
102 public UniverseFactory uf;
103
104 /**
105 * Channel controller
106 */
107 public Controller cc;
108
109 /**
110 * Kernel
111 */
112 public Kernel k;
113
114 /**
115 * Kernel
116 */
117 private VMLoader loader;
118
119 /**
120 * Debugging flag
121 */
122 public boolean debug;
123
124 /**
125 * Root path
126 */
127 public String root;
128
129 /**
130 * Unique number counter -- it will be unique for all instances of SimpleSystemContext.
131 */
132 public static int uniqueN = 0;
133
134 /**
135 * Default Constructor.
136 */
137 public SimpleSystemContext() throws Exception {
138 // Doesn't do anything
139 }
140
141 /**
142 * Properties constructor. Give it a full path to the
143 * properties file.
144 */
145 public void init(ExtendedProperties props) throws Exception {
146
147 // save 'em
148 prop = props;
149
150 // defaults
151 debug = false;
152
153 // Make my universe factory
154 uf = new UniverseFactory();
155
156 // Make a channel controller
157 cc = new Controller();
158
159 // BUILD LOG MANAGER ---------------------------------------
160
161 int ald_line_size = AutohitProperties.LOGS_LINE_SIZE_DEFAULT;
162
163 // LINE SIZE?
164 String logsize =
165 (String) Utils.testGetProperty(
166 AutohitProperties.LOGS_LINE_SIZE,
167 prop);
168 if (logsize != null) {
169 try {
170 ald_line_size = Integer.parseInt(logsize);
171 } catch (Exception e) {
172 // No where to report it anyway
173 }
174 }
175
176 // If a log type is file, use a file otherwise use console,
177 // even if not set.
178 String logprop =
179 (String) Utils.testGetProperty(
180 AutohitProperties.LOGS_TYPE_CONTROL,
181 prop);
182 String logClientprop =
183 (String) Utils.testGetProperty(
184 AutohitProperties.LOGS_TYPE_CLIENT,
185 prop);
186 AutohitLogDrain controlDrain;
187 AutohitLogDrain clientDrain;
188
189 // CONTROL DRAIN
190 if ((logprop == null)
191 || (logprop.equals(AutohitProperties.LOGS_TYPE__FILE))) {
192 try {
193 logprop =
194 (String) Utils.testGetProperty(
195 AutohitProperties.LOGS_LOCATION_CONTROL + AutohitProperties.literal_FS_LOG_EXTENSION,
196 prop);
197 FileOutputStream fco = new FileOutputStream(logprop, true);
198 controlDrain = new AutohitLogDrainDefault();
199 controlDrain.init(fco, ald_line_size);
200 } catch (Exception e) {
201 // If something goes wrong, default to console
202 controlDrain = new AutohitLogDrainDefault();
203 controlDrain.init(System.err, ald_line_size);
204 }
205 } else {
206 controlDrain = new AutohitLogDrainDefault(); // drain to stderr
207 controlDrain.init(System.err, ald_line_size);
208 }
209 // CLIENT DRAIN
210 if ((logClientprop == null)
211 || (logClientprop.equals(AutohitProperties.LOGS_TYPE__FILE))) {
212 try {
213 logClientprop =
214 (String) Utils.testGetProperty(
215 AutohitProperties.LOGS_LOCATION_CLIENT,
216 prop);
217 FileOutputStream fco =
218 new FileOutputStream(logClientprop, true);
219 AutohitLogDrainRouting rclientDrain = new AutohitLogDrainRouting();
220 rclientDrain.init(fco, ald_line_size);
221 rclientDrain.setup(logClientprop);
222 clientDrain = rclientDrain;
223 } catch (Exception e) {
224 // If something goes wrong, default to console
225 clientDrain = new AutohitLogDrainDefault();
226 clientDrain.init(System.err, ald_line_size);
227 System.out.println("SimpleSystemContext:Could not build AutohitLogDrainRouting. Using stderr instead. message=" + e.getMessage());
228 }
229 } else {
230 clientDrain = new AutohitLogDrainDefault(); // drain to stderr
231 clientDrain.init(System.err, ald_line_size);
232 }
233 logManager = new AutohitBasicLogManager(controlDrain, clientDrain);
234
235 // CONFIGURE LOGGERS -----------------------------------------
236 // Get root logger. Set some attributes
237 logger = logManager.getRootLogger();
238
239 // Configure the logger
240 logger.info(
241 "Root logger starting.",
242 AutohitErrorCodes.CODE_INFORMATIONAL_OK_VERBOSE);
243 logprop =
244 (String) Utils.testGetProperty(
245 AutohitProperties.LOGS_PRETTY_PRINT,
246 prop);
247 if ((logprop != null) && (logprop.equals("true"))) {
248 logger.info(
249 "Root logger pretty-print = true.",
250 AutohitErrorCodes.CODE_INFORMATIONAL_OK_VERBOSE);
251 logManager.pretty(true);
252 }
253 logprop =
254 (String) Utils.testGetProperty(
255 AutohitProperties.LOGS_TIMESTAMP,
256 prop);
257 if ((logprop != null) && (logprop.equals("true"))) {
258 logger.info(
259 "Root logger timestamp = true.",
260 AutohitErrorCodes.CODE_INFORMATIONAL_OK_VERBOSE);
261 logManager.stampit(true);
262 }
263
264 logprop =
265 (String) Utils.testGetProperty(
266 AutohitProperties.LOGS_LINE_LIMIT,
267 prop);
268 if (logprop != null) {
269 try {
270 int ll = Integer.parseInt(logprop);
271 logger.info(
272 "Root logger line limit set to " + ll,
273 AutohitErrorCodes.CODE_INFORMATIONAL_OK_VERBOSE);
274 logManager.getDrain().setLineLimit(ll);
275 logManager.getClientDrain().setLineLimit(ll);
276 } catch (Exception e) {
277 logger.error(
278 "Value for "
279 + AutohitProperties.LOGS_LINE_LIMIT
280 + " cannot be parsed as an integer. Using default. Value="
281 + logprop,
282 AutohitErrorCodes.CODE_CONFIGURATION_ERROR);
283 }
284 }
285
286 // Are we debugging???
287 logprop =
288 (String) Utils.testGetProperty(
289 AutohitProperties.SYSTEM_DEBUG,
290 prop);
291 if ((logprop != null) && (logprop.equals("true"))) {
292 logger.info(
293 "DEBUGGING IS ON.",
294 AutohitErrorCodes.CODE_INFORMATIONAL_OK);
295 logManager.debugOn();
296 debug = true;
297 }
298
299 logger.debug(
300 "DEBUGGING root logger up.",
301 AutohitErrorCodes.CODE_INFORMATIONAL_OK);
302 logger.info(
303 "Root logger up.",
304 AutohitErrorCodes.CODE_INFORMATIONAL_OK_VERBOSE);
305
306 // At this point, log any exceptions and abort
307 try {
308
309 // Check for
310 root =
311 (String) Utils.testGetProperty(
312 AutohitProperties.ROOT_PATH,
313 prop);
314 if (root == null) {
315 logger.error(
316 "ERROR. Root property not set!",
317 AutohitErrorCodes.CODE_STARTUP_CONFIGURATION_FAULT);
318 throw new AutohitException(
319 "Required root property not set.",
320 AutohitException.CODE_STARTUP_CONFIGURATION_FAULT);
321 }
322
323 // BUILD COMPILER
324 compiler = new SimCompiler(this);
325
326 // Get universe config
327 String handle =
328 (String) Utils.testGetProperty(
329 AutohitProperties.DEFAULT_UNIVERSE_HANDLE,
330 prop);
331 if (handle == null) {
332 handle = AutohitProperties.literal_DEFAULT_UNIVERSE_HANDLE;
333 }
334 String upath =
335 (String) Utils.testGetProperty(
336 AutohitProperties.DEFAULT_UNIVERSE_PATH,
337 prop);
338 if (upath == null) {
339 upath = AutohitProperties.literal_DEFAULT_UNIVERSE_PATH;
340 }
341 String uprop =
342 (String) Utils.testGetProperty(
343 AutohitProperties.DEFAULT_UNIVERSE_PROP,
344 prop);
345 if (uprop == null) {
346 uprop = AutohitProperties.literal_DEFAULT_UNIVERSE_PROP;
347 }
348
349 // INVOKER PROPERTIES
350 invokerprop = new ExtendedProperties();
351
352 // BUILD OUR UNIVERSE
353 uni = uf.create(handle, root + upath + "/" + uprop);
354
355 // BUILD THE ROOT KERNEL
356 k = new Kernel();
357 k.init(this);
358
359 // BUILD THE LOADER
360 loader = new VMLoader();
361 loader.init(this);
362
363 } catch (Exception e) {
364 logger.error(
365 "ERROR during context instantiation. Aborting. Exception="
366 + e.getMessage(),
367 AutohitErrorCodes.CODE_STARTUP_FAULT);
368 throw e;
369 }
370 }
371
372 /**
373 * Load properties. It will delete any previously loaded properties.
374 * @param props a properties set
375 */
376 public void loadProperties(ExtendedProperties props) throws Exception {
377 prop.combine(props);
378 }
379
380 /**
381 * Get the default universe
382 * @return Universe service interface
383 */
384 public Universe getUniverse() {
385 return uni;
386 }
387
388 /**
389 * Get a universe service by handle. This implementation ignores the
390 * handle and returns the only universe we have.
391 * @param handle handle to the universe
392 * @return Universe service interface
393 */
394 public Universe getUniverse(String handle) {
395 // ignore the handle. We only have one.
396 return uni;
397 }
398
399 /**
400 * Get the XML compiler
401 * @return XmlCompiler base class
402 */
403 public XmlCompiler getCompiler() {
404 return compiler;
405 }
406
407 /**
408 * Get a reference to a generic, root log injector
409 * @return XmlCompiler base class
410 */
411 public AutohitLogInjectorWrapper getRootLogger() {
412 return logger;
413 }
414
415 /**
416 * Cheat. The logger will be our even dispacter
417 * @return Injector reference
418 */
419 public Injector getEventDispatcher() {
420 return (Injector) logger;
421 }
422
423 /**
424 * Get properties set
425 * @return reference to the properties set
426 */
427 public ExtendedProperties getPropertiesSet() {
428 return prop;
429 }
430
431 /**
432 * Get log manager reference
433 * @return reference to the properties set
434 */
435 public AutohitBasicLogManager getLogManager() {
436 return logManager;
437 }
438
439 /**
440 * Get the Kernel
441 * @return reference to the kernel
442 */
443 public Kernel getKernel() {
444 return k;
445 }
446
447 /**
448 * Get the VM Loader
449 * @return reference to the kernel
450 */
451 public VMLoader getLoader() {
452 return loader;
453 }
454
455 /**
456 * Get the command registry as a properties set. It is not cached.
457 * this implementation will always return the default set.
458 * @return properties set representing the registry. it will return null if it cannot be loaded
459 */
460 public CommandRegistry getCommandRegistry() {
461
462 CommandRegistry rset = null;
463 try {
464 rset =
465 new CommandRegistry(
466 new FileInputStream(
467 root + AutohitProperties.COMMAND_DEFAULT_REGISTRY));
468
469 } catch (Exception e) {
470 // don't care. it will return null.
471 logger.error(
472 "FAULT! Fauled to create a CommandRegistry! message="
473 + e.getMessage(),
474 AutohitErrorCodes.CODE_COMMAND_REGISTRY_FAULT);
475 }
476 return rset;
477 }
478
479 /**
480 * Unique number
481 * @return an integer number unique (at least) to this Context
482 */
483 public synchronized int uniqueInteger() {
484 uniqueN++;
485 return uniqueN;
486 }
487
488 /**
489 * Get debugging state
490 * @return true if debugging active
491 */
492 public boolean debuggingState() {
493 return debug;
494 }
495
496 /**
497 * Get a reference to the invoker properties set. Generally, only
498 * invokers should add anything to the set. It should be safe for anyone
499 * to read from it. It is up to the invoker to maintain its contents.
500 * @return reference to the invoker properties set
501 */
502 public ExtendedProperties getInvokerProperties() {
503 return invokerprop;
504 }
505
506 }
|