1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.talika.tarsis.context;
24
25 import java.io.InputStream;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.LinkedList;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Stack;
33
34 import org.talika.commons.util.BeanHelper;
35 import org.talika.tarsis.command.factory.CommandFactoryService;
36 import org.talika.tarsis.factory.FactoryService;
37 import org.talika.tarsis.log.Logger;
38 import org.talika.tarsis.log.LoggerService;
39 import org.talika.tarsis.security.AuthenticatorService;
40 import org.talika.tarsis.security.AuthorizatorService;
41 import org.xml.sax.Attributes;
42 import org.xml.sax.InputSource;
43 import org.xml.sax.SAXException;
44 import org.xml.sax.SAXParseException;
45 import org.xml.sax.helpers.AttributesImpl;
46 import org.xml.sax.helpers.DefaultHandler;
47
48 /**
49 * Loads context configuration from an XML file.
50 *
51 * @author Jose M. Palomar
52 * @version $Revision: 117 $
53 */
54 public final class XmlConfigHandler extends DefaultHandler {
55
56
57 /**
58 * <tarsis-config> tag.
59 */
60 public static final String CONFIG_TAG = "tarsis-config";
61
62 /**
63 * <init-param> tag.
64 */
65 public static final String INIT_PARAM_TAG = "init-param";
66
67 /**
68 * <security> tag.
69 */
70 public static final String SECURITY_TAG = "security";
71
72 /**
73 * <authenticator> tag.
74 */
75 public static final String AUTHC_TAG = "authenticator";
76
77 /**
78 * <authorizator> tag.
79 */
80 public static final String AUTHZ_TAG = "authorizator";
81
82 /**
83 * <auth-param> tag.
84 */
85 public static final String AUTH_PARAM_TAG = "auth-param";
86
87 /**
88 * <log> tag.
89 */
90 public static final String LOG_TAG = "log";
91
92 /**
93 * <log-param> tag.
94 */
95 public static final String LOG_PARAM_TAG = "log-param";
96
97 /**
98 * <factory> tag.
99 */
100 public static final String FACTORY_TAG = "factory";
101
102 /**
103 * <factory-param> tag.
104 */
105 public static final String FACTORY_PARAM_TAG = "factory-param";
106
107 /**
108 * <command-factory> tag.
109 */
110 public static final String CMD_FACTORY_TAG = "command-factory";
111
112 /**
113 * <command-factory-param> tag.
114 */
115 public static final String CMD_FACTORY_PARAM_TAG = "command-factory-param";
116
117 /**
118 * Name attribute.
119 */
120 public static final String NAME_ATTR = "name";
121
122 /**
123 * Class name attribute.
124 */
125 public static final String CLASS_NAME_ATTR = "className";
126
127 /**
128 * Value attribute.
129 */
130 public static final String VALUE_ATTR = "value";
131
132 /**
133 * Log level attribute.
134 */
135 public static final String LOG_LVL_ATTR = "logLevel";
136
137 /**
138 * Preload attribute.
139 */
140 public static final String PRELOAD_ATTR = "preload";
141
142 /**
143 * Debug log level value.
144 */
145 public static final String DEBUG_VALUE = "debug";
146
147 /**
148 * Info log level value.
149 */
150 public static final String INFO_VALUE = "info";
151
152 /**
153 * Warning log level value.
154 */
155 public static final String WARNING_VALUE = "warning";
156
157 /**
158 * Error log level value.
159 */
160 public static final String ERROR_VALUE = "error";
161
162 /**
163 * Panic log level value.
164 */
165 public static final String PANIC_VALUE = "panic";
166
167 /**
168 * DTD public id.
169 */
170 public static final String DTD_PUBLICID = "-//Talika Open Source Group//Tarsis Config DTD 1.0//ES";
171
172 /**
173 * DTD class path.
174 */
175 public static final String DTD_CLASSPATH = "/org/talika/dtds/tarsis-config_1_0.dtd";
176
177
178 /**
179 * Parsed init parameters map.
180 */
181 private Map initParams;
182
183 /**
184 * Parsed <code>Factory</code> instances map.
185 */
186 private Map factories;
187
188 /**
189 * Parsed <code>Logger</code> instances list.
190 */
191 private List loggers;
192
193 /**
194 * Parsed <code>Authenticator</code> instance.
195 */
196 private AuthenticatorService authc;
197
198 /**
199 * Parsed <code>Authorizator</code> instance.
200 */
201 private AuthorizatorService authz;
202
203 /**
204 * Parsed <code>CommandFactory</code> instance.
205 */
206 private CommandFactoryService commandFactory;
207
208 /**
209 * Tag attributes stack.
210 */
211 private Stack stAtts = new Stack();
212
213 /**
214 * Auxiliar parameters map.
215 */
216 private Map auxParams = new HashMap();
217
218
219 /**
220 * Creates a new <code>XmlConfigHandler</code> object.
221 */
222 public XmlConfigHandler() {
223 this.initParams = new HashMap();
224 this.factories = new HashMap();
225 this.loggers = new LinkedList();
226 this.stAtts = new Stack();
227 this.auxParams = new HashMap();
228 }
229
230
231
232 /**
233 * Receive notification of the beginning of a document.
234 *
235 * @throws SAXException Any SAX exception, possibly wrapping another exception.
236 * @see org.xml.sax.ContentHandler#startDocument()
237 */
238 public void startDocument() throws SAXException {
239
240 }
241
242 /**
243 * Receive notification of the end of a document.
244 *
245 * @throws SAXException Any SAX exception, possibly wrapping another exception.
246 * @see org.xml.sax.ContentHandler#endDocument()
247 */
248 public void endDocument() throws SAXException {
249
250 }
251
252 /**
253 * Receive notification of the beginning of an element.
254 *
255 * @param namespaceURI String The Namespace URI, or the empty string if the
256 * element has no Namespace URI or if Namespace processing is not being performed.
257 * @param localName String The local name (without prefix), or the empty string
258 * if Namespace processing is not being performed.
259 * @param name String The qualified name (with prefix), or the empty string if
260 * qualified names are not available.
261 * @param atts Attributes The attributes attached to the element. If there are no
262 * attributes, it shall be an empty Attributes object.
263 * @throws SAXException Any SAX exception, possibly wrapping another exception.
264 * @see org.xml.sax.ContentHandler#startElement(String, String, String, Attributes)
265 */
266 public void startElement(String namespaceURI, String localName, String name, Attributes atts) throws SAXException {
267 stAtts.push(new AttributesImpl(atts));
268 }
269
270 /**
271 * Receive notification of the end of an element.
272 *
273 * @param namespaceURI String The Namespace URI, or the empty string if the
274 * element has no Namespace URI or if Namespace processing is not being performed.
275 * @param localName String The local name (without prefix), or the empty string
276 * if Namespace processing is not being performed.
277 * @param name String The qualified name (with prefix), or the empty string if
278 * qualified names are not available.
279 * @throws SAXException Any SAX exception, possibly wrapping another exception.
280 * @see org.xml.sax.ContentHandler#endElement(String, String, String)
281 */
282 public void endElement(String namespaceURI, String localName, String name) throws SAXException {
283
284 Attributes atts = (Attributes) stAtts.pop();
285
286 if (name.equals(CONFIG_TAG)) {
287
288 }
289 else if (name.equals(INIT_PARAM_TAG)) {
290 processInitParamTag(atts);
291 }
292 else if (name.equals(SECURITY_TAG)) {
293
294 }
295 else if (name.equals(AUTHC_TAG)) {
296 processAuthenticatorTag(atts);
297 }
298 else if (name.equals(AUTHZ_TAG)) {
299 processAuthorizatorTag(atts);
300 }
301 else if (name.equals(AUTH_PARAM_TAG)) {
302 processParamTag(atts);
303 }
304 else if (name.equals(LOG_TAG)) {
305 processLogTag(atts);
306 }
307 else if (name.equals(LOG_PARAM_TAG)) {
308 processParamTag(atts);
309 }
310 else if (name.equals(FACTORY_TAG)) {
311 processFactoryTag(atts);
312 }
313 else if (name.equals(FACTORY_PARAM_TAG)) {
314 processParamTag(atts);
315 }
316 else if (name.equals(CMD_FACTORY_TAG)) {
317 processCommandFactoryTag(atts);
318 }
319 else if (name.equals(CMD_FACTORY_PARAM_TAG)) {
320 processParamTag(atts);
321 }
322
323 }
324
325
326 /**
327 * Allow the application to resolve external entities.
328 *
329 * @param publicId String The public identifier of the external entity being
330 * referenced, or <code>null</code> if none was supplied.
331 * @param systemId String The system identifier of the external entity being
332 * referenced.
333 * @return InputSource A Java-specific IO exception, possibly the result of
334 * creating a new <code>InputStream</code> or <code>Reader</code> for the
335 * <code>InputSource</code>.
336 * @see org.xml.sax.EntityResolver#resolveEntity(String, String)
337 */
338 public InputSource resolveEntity (String publicId, String systemId) {
339
340 if (publicId.equals(DTD_PUBLICID)) {
341
342 InputStream is = this.getClass().getResourceAsStream(DTD_CLASSPATH);
343 if (is != null) {
344 return new InputSource(is);
345 }
346
347 }
348
349 return null;
350
351 }
352
353
354 /**
355 * Receive notification of a warning.
356 *
357 * @param spe SAXParseException The warning information encapsulated in a SAX
358 * parse exception.
359 * @throws SAXException Any SAX exception, possibly wrapping another exception.
360 * @see org.xml.sax.ErrorHandler#warning(SAXParseException)
361 */
362 public void warning(SAXParseException spe) throws SAXException {
363 }
364
365 /**
366 * Receive notification of a recoverable error.
367 *
368 * @param spe SAXParseException The error information encapsulated in a SAX parse
369 * exception.
370 * @throws SAXException Any SAX exception, possibly wrapping another exception.
371 * @see org.xml.sax.ErrorHandler#error(SAXParseException)
372 */
373 public void error(SAXParseException spe) throws SAXException {
374 throw new SAXException("** Configuration parse error\n" +
375 " at [" + spe.getLineNumber() +
376 ":" + spe.getColumnNumber() +
377 "] in " + spe.getSystemId(), spe);
378 }
379
380 /**
381 * Receive notification of a non-recoverable error.
382 *
383 * @param spe SAXParseException The error information encapsulated in a SAX parse
384 * exception.
385 * @throws SAXException Any SAX exception, possibly wrapping another exception.
386 * @see org.xml.sax.ErrorHandler#fatalError(SAXParseException)
387 */
388 public void fatalError(SAXParseException spe) throws SAXException {
389 throw new SAXException("** Configuration parse error\n" +
390 " at [" + spe.getLineNumber() +
391 ":" + spe.getColumnNumber() +
392 "] in " + spe.getSystemId(), spe);
393 }
394
395
396 /**
397 * Returns parsed init parameters map.
398 *
399 * @return Map parsed init parameters map.
400 */
401 public Map getInitParameters() {
402 return Collections.unmodifiableMap(initParams);
403 }
404
405 /**
406 * Returns parsed <code>Logger</code> instances list.
407 *
408 * @return Collection parsed <code>Logger</code> instances list.
409 */
410 public Collection getLoggers() {
411 return Collections.unmodifiableCollection(loggers);
412 }
413
414 /**
415 * Returns parsed <code>Authenticator</code> instance.
416 *
417 * @return AuthenticatorService parsed <code>Authenticator</code> instance or
418 * <code>null</code> if none have been parsed.
419 */
420 public AuthenticatorService getAuthenticathor() {
421 return authc;
422 }
423
424 /**
425 * Returns parsed <code>Authorizator</code> instance.
426 *
427 * @return AuthorizatorService parsed <code>AuthorizatorService</code> instance
428 * or <code>null</code> if non hava been parsed.
429 */
430 public AuthorizatorService getAuthorizator() {
431 return authz;
432 }
433
434 /**
435 * Returns parsed <code>Factory</code> isntances map.
436 *
437 * @return Map parsed <code>Factory</code> isntances map.
438 */
439 public Map getFactories() {
440 return Collections.unmodifiableMap(factories);
441 }
442
443 /**
444 * Returns parsed <code>CommandFactory</code> instance.
445 *
446 * @return CommandFactoryService parsed <code>CommandFactory</code> instance.
447 */
448 public CommandFactoryService getCommandFactory() {
449 return commandFactory;
450 }
451
452
453 /**
454 * Process <init-param> tag.
455 *
456 * @param atts Attributes tag attributes.
457 */
458 protected void processInitParamTag(Attributes atts) {
459
460 String name = atts.getValue(NAME_ATTR);
461 String value = atts.getValue(VALUE_ATTR);
462
463 initParams.put(name, value);
464
465 }
466
467 /**
468 * Process <authenticator> tag.
469 *
470 * @param atts Attributes tag attributes.
471 * @throws SAXException if there is an error while processing tag.
472 */
473 protected void processAuthenticatorTag(Attributes atts) throws SAXException {
474
475 String className = atts.getValue(CLASS_NAME_ATTR);
476
477 try {
478 BeanHelper bean = new BeanHelper(className);
479 authc = (AuthenticatorService) bean.getInstance();
480 bean.setProperties(authc, auxParams);
481 }
482 catch (Exception e) {
483 throw new SAXException("Error in authenticathor " + className + " load", e);
484 }
485
486 auxParams.clear();
487
488 }
489
490 /**
491 * Process <authorizator> tag.
492 *
493 * @param atts Attributes tag attributes.
494 * @throws SAXException if there is an error while processing tag.
495 */
496 protected void processAuthorizatorTag(Attributes atts) throws SAXException {
497
498 String className = atts.getValue(CLASS_NAME_ATTR);
499
500 try {
501 BeanHelper bean = new BeanHelper(className);
502 authz = (AuthorizatorService) bean.getInstance();
503 bean.setProperties(authz, auxParams);
504 }
505 catch (Exception e) {
506 throw new SAXException("Error in authorizator " + className + " load", e);
507 }
508
509 auxParams.clear();
510
511 }
512
513 /**
514 * Process <log> tag.
515 *
516 * @param atts Attributes tag attributes.
517 * @throws SAXException if there is an error while processing tag.
518 */
519 protected void processLogTag(Attributes atts) throws SAXException {
520
521 String className = atts.getValue(CLASS_NAME_ATTR);
522 String logLvlStr = atts.getValue(LOG_LVL_ATTR);
523
524 LoggerService logger = null;
525 try {
526 BeanHelper bean = new BeanHelper(className);
527 logger = (LoggerService) bean.getInstance();
528 bean.setProperties(logger, auxParams);
529
530 if (logLvlStr.equals(DEBUG_VALUE)) {
531 logger.setLogLevel(Logger.DEBUG);
532 }
533 else if (logLvlStr.equals(INFO_VALUE)) {
534 logger.setLogLevel(Logger.INFO);
535 }
536 else if (logLvlStr.equals(WARNING_VALUE)) {
537 logger.setLogLevel(Logger.WARNING);
538 }
539 else if (logLvlStr.equals(ERROR_VALUE)) {
540 logger.setLogLevel(Logger.ERROR);
541 }
542 else if (logLvlStr.equals(PANIC_VALUE)) {
543 logger.setLogLevel(Logger.PANIC);
544 }
545
546 }
547 catch (Exception e) {
548 throw new SAXException("Error in logger " + className + " load", e);
549 }
550
551 loggers.add(logger);
552
553 auxParams.clear();
554
555 }
556
557 /**
558 * Process <factory> tag.
559 *
560 * @param atts Attributes tag attributes.
561 * @throws SAXException if there is an error while processing tag.
562 */
563 protected void processFactoryTag(Attributes atts) throws SAXException {
564
565 String name = atts.getValue(NAME_ATTR);
566 String className = atts.getValue(CLASS_NAME_ATTR);
567
568 FactoryService factory = null;
569 try {
570 BeanHelper bean = new BeanHelper(className);
571 factory = (FactoryService) bean.getInstance();
572 bean.setProperties(factory, auxParams);
573 }
574 catch (Exception e) {
575 throw new SAXException("Error in factory " + className + " load", e);
576 }
577
578 factories.put(name, factory);
579
580 auxParams.clear();
581
582 }
583
584 /**
585 * Process <command-factory> tag.
586 *
587 * @param atts Attributes tag attributes.
588 * @throws SAXException if there is an error while processing tag.
589 */
590 protected void processCommandFactoryTag(Attributes atts) throws SAXException {
591
592 String className = atts.getValue(CLASS_NAME_ATTR);
593 String preload = atts.getValue(PRELOAD_ATTR);
594
595 try {
596 BeanHelper bean = new BeanHelper(className);
597 commandFactory = (CommandFactoryService) bean.getInstance();
598 bean.setProperties(commandFactory, auxParams);
599 }
600 catch (Exception e) {
601 throw new SAXException("Error in command factory " + className + " load", e);
602 }
603
604 auxParams.clear();
605
606 }
607
608 /**
609 * Process <XXXX-param> tags.
610 *
611 * @param atts Attributes tag attributes.
612 */
613 protected void processParamTag(Attributes atts) {
614
615 String name = atts.getValue(NAME_ATTR);
616 String value = atts.getValue(VALUE_ATTR);
617
618 auxParams.put(name, value);
619
620 }
621
622 }