View Javadoc

1   /*
2    * $Id: XmlConfigHandler.java 117 2004-10-23 18:42:03Z josem $
3    *
4    * Tarsis
5    * Copyright (C) 2002 Talika Open Source Group
6    *
7    * This program is free software; you can redistribute it and/or modify
8    * it under the terms of the GNU General Public License as published by
9    * the Free Software Foundation; either version 2 of the License, or
10   * (at your option) any later version.
11   *
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Public License for more details.
16   *
17   * You should have received a copy of the GNU General Public License
18   * along with this program; if not, write to the Free Software
19   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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      // Constants
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     // Fields
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     // Constructors
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     // Methods
231     // XML Handler
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         // Nothing to do
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         // Nothing to do
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             // Nothing to do
288         }
289         else if (name.equals(INIT_PARAM_TAG)) {
290             processInitParamTag(atts);
291         }
292         else if (name.equals(SECURITY_TAG)) {
293             // Nothing to do
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     // Entity Resolver
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     // Error Handler
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     // Accesors
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     // Helper
453     /**
454      * Process &lt;init-param&gt; 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 &lt;authenticator&gt; 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 &lt;authorizator&gt; 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 &lt;log&gt; 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 &lt;factory&gt; 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 &lt;command-factory&gt; 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 &ltXXXX-param&gt; 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 }