KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > barracuda > core > event > DefaultApplicationAssembler


1 /*
2  * Copyright (C) 2003 Christian Cryder [christianc@granitepeaks.com]
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * $Id: DefaultApplicationAssembler.java,v 1.17 2004/02/01 05:16:27 christianc Exp $
19  */

20 package org.enhydra.barracuda.core.event;
21
22 import java.io.*;
23 import java.lang.reflect.*;
24 import java.util.*;
25 import javax.servlet.*;
26 import javax.servlet.http.*;
27
28 import org.apache.log4j.*;
29 import org.apache.log4j.xml.*;
30 import org.xml.sax.*;
31 import org.xml.sax.helpers.*;
32
33 import org.enhydra.barracuda.core.event.*;
34 import org.enhydra.barracuda.plankton.*;
35 import org.enhydra.barracuda.plankton.xml.*;
36 import org.enhydra.barracuda.core.util.dom.*;
37
38 /**
39  * This class assembles a Barracuda system based on one or more XML
40  * descriptor files. For a sample file look at
41  * <code>/WEB-INF/classes/sample.event-gateway.xml</code>. Event gateway files
42  * are specified in the 'AssemblyDescriptor' init param of the
43  * ApplicationGateway servlet in web.xml. See Barracuda's sample.web.xml for
44  * example usage.
45  *
46  * <p>One may specify a single file or use a pattern to load multiple files.
47  * When loading multiple files, the pattern may consist of a plain directory
48  * such as <code>/WEB-INF/assemblyfiles/</code> (making sure to add the
49  * trailing '/'), a directory plus a partial file name such as
50  * <code>/WEB-INF/event</code>, or even a directory plus a filename with an
51  * asterisk as a wildcard such as <code>/WEB-INF/event*way.xml. The latter case
52  * allows for specifying an alternate suffix to look for in the pattern
53  * matching (for instance if the assembly files don't end in '.xml'). The
54  * former two cases default to using '.xml' as the pattern matching suffix.</p>
55  *
56  * <p>Supported elements of assembly descriptor files are (all attributes required unless otherwise specified):
57  * <dl>
58  * <dt>&lt;event-gateway&gt;</dt>
59  * <dd>- nested in the root &lt;assemble&gt; element and itself</dd>
60  * <dd>- supports nesting of all elements including itself</dd>
61  * <dd>- attributes supported:
62  * <ul>
63  * <li>class</li>
64  * </ul>
65  * </dd>
66  * <dd>- Example usage... &lt;event-gateway class=&quot;o.e.b.core.event.DefaultEventGateway&quot;&gt; ... &lt;/event-gateway&gt;</dd>
67  * <dt>&lt;event-interest&gt;</dt>
68  * <dd>- nested in &lt;event-gateway&gt; elements</dd>
69  * <dd>- supports nesting of &lt;set-parameter&gt; and &lt;constant&gt; elements</dd>
70  * <dd>- attributes supported:
71  * <ul>
72  * <li>factory</li>
73  * <li>event</li>
74  * </ul>
75  * </dd>
76  * <dd>- Example usage... &lt;event-interest factory=&quot;o.e.b.examples.ex4.SampleControlHandler&quot; event=&quot;o.e.b.examples.ex4.events.Test1&quot;&gt; ... &lt;/event-interest&gt;</dd>
77  * <dt>&lt;event-alias&gt;</dt>
78  * <dd>- nested in &lt;event-gateway&gt; elements</dd>
79  * <dd>- no nested elements supported</dd>
80  * <dd>- attributes supported:
81  * <ul>
82  * <li>event</li>
83  * </ul>
84  * </dd>
85  * <dd>- Example usage... &lt;event-alias event=&quot;o.e.b.examples.ex4.events.Test4&quot; /&gt;</dd>
86  * <dt>&lt;constant&gt;</dt>
87  * <dd>- nested in all elements but &lt;event-alias&gt; elements</dd>
88  * <dd>- attributes supported:
89  * <ul>
90  * <li>class</li>
91  * <li>name</li>
92  * <li>delegateRuntimeValue - optional - if set, any provided value is ignored. Setting a &quot;delegate runtime value&quot; means that the value is
93  * not to be taken literally from configuration. Rather, this responsibility is delegated to the application assembler to set the current runtime value.
94  * This is a limited feature and the only delegate runtime value currently supported is the ServletContext object.
95  * </li>
96  * </ul>
97  * </dd>
98  * <dd>- Example usage...
99  * <pre>
100  * &lt;constant class=&quot;o.e.b.core.event.ApplicationGateway&quot; name=&quot;showDebug&quot;&gt;1&lt;/constant&gt;
101  * or
102  * &lt;constant class=&quot;org.some.package.SomeClass&quot; name=&quot;servletContext&quot; delegateRuntimeValue=&quot;true&quot;/&gt;
103  * </pre>
104  * </dd>
105  * <dt>&lt;set-property&gt;</dt>
106  * <dd>- nested in all elements but &lt;event-alias&gt; elements</dd>
107  * <dd>- attributes supported:
108  * <ul>
109  * <li>name</li>
110  * <li>delegateRuntimeValue - optional - if set, any provided value is ignored. Setting a &quot;delegate runtime value&quot; means that the value is
111  * not to be taken literally from configuration. Rather, this responsibility is delegated to the application assembler to set the current runtime value.
112  * This is a limited feature and the only delegate runtime value currently supported is the ServletContext object.
113  * </li>
114  * </ul>
115  * </dd>
116  * <dd>- Example usage...
117  * <pre>
118  * &lt;set-property name=&quot;hello&quot;>Hello World!&lt;/set-property&gt;
119  * or
120  * &lt;set-property name=&quot;servletContext&quot; delegateRuntimeValue=&quot;true&quot;/&gt;
121  * </pre>
122  * </dd>
123  * </dl>
124  */

125 public class DefaultApplicationAssembler extends DefaultHandler implements ApplicationAssembler {
126
127     //public constants
128
protected static final Logger logger = Logger.getLogger(DefaultApplicationAssembler.class.getName());
129     
130     //private constants
131
public static String JavaDoc DEFAULT_PARSER = "org.apache.xerces.parsers.SAXParser";
132
133     //recognized tags
134
private static final String JavaDoc CONSTANT = "constant";
135     private static final String JavaDoc EVENT_ALIAS = "event-alias";
136     private static final String JavaDoc EVENT_GATEWAY = "event-gateway";
137     private static final String JavaDoc EVENT_INTEREST = "event-interest";
138     private static final String JavaDoc SET_PROPERTY = "set-property";
139
140     //recognized attributes
141
private static final String JavaDoc CLASS = "class";
142     private static final String JavaDoc DELEGATE = "delegateRuntimeValue";
143     private static final String JavaDoc EVENT = "event";
144     private static final String JavaDoc FACTORY = "factory";
145     private static final String JavaDoc NAME = "name";
146
147
148     /**
149      * Assemble the system, given the root EventGateway and the
150      * XML assembly decriptor name. The default parser will be
151      * used.
152      *
153      * @param irootGateway the root EventGateway (req)
154      * @param iservletConfig the ServletConfig object (may be null, if invoking
155      * from other than a servlet environment)
156      * @param iassemblySourceFile the XML assembly descriptor (req)
157      */

158     public void assemble(EventGateway irootGateway, ServletConfig iservletConfig, String JavaDoc iassemblySourceFile) {
159         assemble(irootGateway, iservletConfig, iassemblySourceFile, null);
160     }
161
162     /**
163      * Assemble the system, given the root EventGateway, an
164      * XML assembly decriptor name, and a specific SAX parser
165      * class.
166      *
167      * @param irootGateway the root EventGateway (req)
168      * @param iservletConfig the ServletConfig object (may be null, if invoking
169      * from other than a servlet environment)
170      * @param iassemblySourceFile the XML assembly descriptor (req)
171      * @param iparserClass the SAX parser class (if null, defaults to DEFAULT_PARSER)
172      */

173     public void assemble(EventGateway irootGateway, ServletConfig iservletConfig, String JavaDoc iassemblySourceFile, String JavaDoc iparserClass) {
174         //Setup the assemblerXmlReader
175
AssemblerXMLReader assemblerXmlReader = new AssemblerXMLReader(iparserClass, irootGateway);
176         assemblerXmlReader.setup();
177
178         if (logger.isInfoEnabled()) logger.info("Assembling system from input source");
179         if (logger.isDebugEnabled()) logger.debug("assembly path is: " + iassemblySourceFile);
180         try {
181             if (iservletConfig != null) {
182                 //running as a webapp
183

184                 ServletContext context = iservletConfig.getServletContext();
185                 assemblerXmlReader.setServletContext(context); //give config access to the ServletContext
186
if (!hasMethod("getResourcePaths", context.getClass(), new Class JavaDoc[]{String JavaDoc.class})) {
187                     //servlet 2.2...only support loading single assembly descriptor
188
InputStream is = getAssemblyResourceAsStream(context, iassemblySourceFile);
189                     if (is != null) {
190                         assemblerXmlReader.processXmlFile(is);
191                     }
192                 } else {
193                     //servlet 2.3+...support multiple assembly descriptors
194
//make sure we prepend "/" so string parsing is easier below
195
String JavaDoc normalizedResourcePath = "/"+getNormalizedPath(iassemblySourceFile);
196     
197                     //variables used for comparson against paths returned by context.getResourcePaths()
198
String JavaDoc dirPath = normalizedResourcePath.substring(0, normalizedResourcePath.lastIndexOf("/")+1);
199                     String JavaDoc fileMatch = normalizedResourcePath.substring(normalizedResourcePath.lastIndexOf("/")+1);
200                     String JavaDoc beginMatch = fileMatch; //default value
201
String JavaDoc endMatch = ".xml"; //default value
202
if (fileMatch.indexOf(".") != -1) endMatch = fileMatch; //covers single file with suffix other than ".xml"
203

204                     //take into account a wildcard (*) pattern match such as /WEB-INF/event*way.xml
205
if (fileMatch.indexOf("*") != -1) {
206                         beginMatch = fileMatch.substring(0, fileMatch.indexOf("*"));
207                         endMatch = fileMatch.substring(fileMatch.indexOf("*")+1);
208                         //take care of cases such as /WEB-INF/* or /WEB-INF/event*
209
if (!(endMatch.length() > 0)) endMatch = ".xml"; //fall back to default value
210
}
211     
212                     if (logger.isDebugEnabled()) logger.debug("dirPath is : " + dirPath);
213                     if (logger.isDebugEnabled()) logger.debug("fileMatch is: " + fileMatch);
214                     if (logger.isDebugEnabled()) logger.debug("beginMatch is: " + beginMatch);
215                     if (logger.isDebugEnabled()) logger.debug("endMatch is: " + endMatch);
216     
217                     Set paths = context.getResourcePaths(dirPath);
218                     if (logger.isDebugEnabled()) logger.debug("resource paths returned: " + paths.size());
219                     Iterator iter = paths.iterator();
220                     while (iter.hasNext()) {
221                         String JavaDoc currentPath = (String JavaDoc)iter.next();
222                         if (logger.isDebugEnabled()) logger.debug("current path is: " + currentPath);
223                         if (currentPath.indexOf(dirPath+beginMatch) != -1 && currentPath.endsWith(endMatch)) {
224                             InputStream is = getAssemblyResourceAsStream(context, currentPath);
225                             if (is != null) {
226                                 assemblerXmlReader.processXmlFile(is);
227                             }
228                         }
229                     }
230                 }
231             } else {
232                 //not running as a webapp
233
//assumes that iassemblySourceFile points to a single xml file
234
//and that it is a relative path available within the class loader
235
//or it is an absolute file path to be loaded via File IO
236
InputStream is = getAssemblyResourceAsStream(null, iassemblySourceFile);
237                 if (is != null) {
238                     assemblerXmlReader.processXmlFile(is);
239                 }
240             }
241             if (logger.isInfoEnabled()) logger.info("Assembly complete!");
242         } catch (Exception JavaDoc e) {
243             logger.warn("Error assembling system!", e);
244             e.printStackTrace(System.err);
245         }
246     }
247
248     private static boolean hasMethod(String JavaDoc methodName, Class JavaDoc clazz, Class JavaDoc[] parameterTypes) {
249         Method method = null;
250         try {
251             method = clazz.getMethod(methodName, parameterTypes);
252         } catch (Exception JavaDoc e) {}
253         if (method != null) return true;
254         return false;
255     }
256
257     private static InputStream getAssemblyResourceAsStream(ServletContext context, String JavaDoc resource) {
258         InputStream is = null;
259         String JavaDoc normalizedResourcePath = getNormalizedPath(resource);
260         //Attempt to load from the WEB-INF Dir
261
if (context!=null) {
262             //first assume that the file was given the full path specified relative to the root of the webapp.
263
//eg... "/WEB-INF/myresource.xml" or "WEB-INF/myresource.xml"
264
if (logger.isDebugEnabled()) logger.debug("Attempting to load assembly file via servlet context at: /"+normalizedResourcePath);
265             is = context.getResourceAsStream("/" + normalizedResourcePath);
266
267             //'is' should be non-null at this point. Probably could get rid of
268
//immediately below, but leaving for posterity
269
if (is==null) {
270                 //maybe only the filename is provided with no extra path. Alternatively, maybe the path
271
//given was a path relative to /WEB-INF/ rather than the root of the webapp. Try loading from /WEB-INF/.
272
if (logger.isDebugEnabled()) logger.debug("Attempting to load assembly file via servlet context at: /WEB-INF/"+normalizedResourcePath);
273                 is = context.getResourceAsStream("/WEB-INF/" + normalizedResourcePath);
274                 if (is==null) {
275                     //maybe only the filename is provided with no extra path. Alternatively, maybe the path
276
//given was a package path, in which case the path would be relative to /WEB-INF/classes/
277
//rather than the root of the webapp. Try loading from /WEB-INF/classes/.
278
if (logger.isDebugEnabled()) logger.debug("Attempting to load assembly file via servlet context at: /WEB-INF/classes/"+normalizedResourcePath);
279                     is = context.getResourceAsStream("/WEB-INF/classes/" + normalizedResourcePath);
280                 }
281             }
282         }
283         
284         //resource does not exist inside the webapp at the path specified. Try loading via the classloader.
285
if (is==null) {
286             if (logger.isDebugEnabled()) logger.debug("Attempting to load assembly file inside the local classloader: "+normalizedResourcePath);
287             is = DefaultApplicationAssembler.class.getClassLoader().getResourceAsStream(normalizedResourcePath);
288             if (is==null) {
289                 //this should only get triggered in the case that this class exists in a parent
290
//classloader and the resource exists in a child classloader. eg... in the WebappClassloader.
291
if (logger.isDebugEnabled()) logger.debug("Attempting to load assembly file inside all available classloaders: "+normalizedResourcePath);
292                 is = Thread.currentThread().getContextClassLoader().getResourceAsStream(normalizedResourcePath);
293             }
294         }
295         
296         //Not a webapp or path specified is outside of the webapp. Attempt to load using the full file path
297
if (is==null) {
298             if (logger.isDebugEnabled()) logger.debug("Attempting to load assembly file via file IO at: "+resource);
299             File f = new File(resource);
300             try {
301                 is = new FileInputStream(f);
302             } catch (FileNotFoundException fnfe) {}
303         }
304
305         if (is==null) {
306             logger.warn("Unable to load assembly file"+resource);
307         }
308         return is;
309     }
310
311     //Take a path a normalize it... eg. make WEB-INF/somefile.xml and /WEB-INF/somefile.xml equivalent
312
private static String JavaDoc getNormalizedPath(String JavaDoc resourcePath) {
313         String JavaDoc path = resourcePath;
314         if (path!=null) {
315             if (path.startsWith("/")) path = (path.length() > 1) ? path.substring(1) : "";
316         }
317         return path;
318     }
319
320     /**
321      * This class basically assembles a Barracuda system based on
322      * an XML descriptor file.
323      */

324     class AssemblerXMLReader extends DefaultHandler {
325         ServletContext servletContext;
326         String JavaDoc parserClass = null; //The Dom Parser
327
EventGateway rootGateway = null;
328         EventGateway curGateway = null;
329         Stack objStack = null;
330         DOMLoader domLoader = null;
331         boolean needPropVal = false;
332         String JavaDoc className = null;
333         String JavaDoc propName = null;
334         String JavaDoc propVal = null;
335         String JavaDoc propDelegate = null;
336         int depth = 0;
337
338         XMLReader parser = null; //Since the 'ProcessXml' method can be called multiple times,
339
// a single instance of the XmlReader is needed.
340

341         //default constructor
342
public AssemblerXMLReader() {}
343
344         public AssemblerXMLReader(String JavaDoc parserClass, EventGateway rootGateway) {
345             setParserClass(parserClass);
346             setRootGateway(rootGateway);
347         }
348
349         /**
350          * Sets the SAX Parser
351          * @param parserClass the SAX parser class (if null, defaults to DEFAULT_PARSER)
352          */

353         public void setParserClass(String JavaDoc parserClass) {
354             this.parserClass = parserClass;
355         }
356
357         /**
358          * Sets the EventGateway that should be used
359          * @param rootGateway the root EventGateway (req)
360          */

361         public void setRootGateway(EventGateway rootGateway) {
362             this.rootGateway = rootGateway;
363         }
364
365         /**
366          * optionally set ServletContext to make it available for
367          * setting as a runtime delegate value. Eg...
368          * &lt;set-property name=&amp;servletContext&amp; delegateRuntimeValue=&amp;true&amp;/&gt;
369          */

370         public void setServletContext(ServletContext iservletContext) {
371             this.servletContext = iservletContext;
372         }
373
374         /**
375          * Initialization stuff... (Need a better description here!)
376          */

377         public void setup() {
378             try {
379                 if (parserClass==null) parserClass = DEFAULT_PARSER;
380                 logger.info("Instantiating parser ("+parserClass+")");
381                 parser = (XMLReader) Class.forName(parserClass, true, Thread.currentThread().getContextClassLoader()).newInstance();
382             } catch (Exception JavaDoc e) {
383                 logger.warn("Error assembling system!", e);
384                 e.printStackTrace(System.err);
385             }
386         }
387
388         //This is the core method...
389
public void processXmlFile(InputStream is) {
390             try {
391                 //get the source file
392
InputSource source = new InputSource(is);
393     
394                 //parse the file
395
logger.info("Parsing the source file...");
396                 parser.setContentHandler(this);
397                 parser.setErrorHandler(this);
398                 parser.parse(source);
399             } catch (org.xml.sax.SAXParseException JavaDoc spe) {
400                 logger.warn("Error assembling system!", spe);
401                 spe.printStackTrace(System.err);
402             } catch (org.xml.sax.SAXException JavaDoc se) {
403                 if (se.getException() != null) {
404                     logger.warn("Error assembling system!", se.getException());
405                     se.getException().printStackTrace(System.err);
406                 } else {
407                     logger.warn("Error assembling system!", se);
408                     se.printStackTrace(System.err);
409                 }
410             } catch (Exception JavaDoc e) {
411                 logger.warn("Error assembling system!", e);
412                 e.printStackTrace(System.err);
413             }
414         }
415
416         public void startDocument() {
417             curGateway = rootGateway;
418             objStack = new Stack();
419             objStack.push(curGateway);
420         }
421
422         public void startElement(String JavaDoc uri, String JavaDoc local, String JavaDoc raw, Attributes attrs) throws SAXException {
423             String JavaDoc curTag = local;
424             logger.debug("uri:"+uri+" local:"+local+" raw:"+raw+" attrs:"+attrs);
425
426             //event-gateway
427
if (curTag.equals(EVENT_GATEWAY)) {
428
429                 //figure out what the new gateway is
430
depth++;
431                 EventGateway eg = null;
432                 String JavaDoc eventGatewayClassName = attrs.getValue(CLASS);
433                 logger.debug("Creating event gateway: "+eventGatewayClassName);
434                 try {
435                     eg = (EventGateway) Class.forName(eventGatewayClassName, true, Thread.currentThread().getContextClassLoader()).newInstance();
436                     objStack.push(eg);
437                 } catch (Exception JavaDoc e) {
438                     String JavaDoc msg = "Error instantiating event gateway";
439                     logger.warn(msg+": ", e);
440                     throw new SAXException(msg, e);
441                 }
442
443                 //add the event gateway to the current gateway and
444
//then make the new gateway the current gateway
445
logger.debug("Adding event gateway: "+eg.getClass().getName());
446                 if (curGateway!=null) curGateway.add(eg);
447                 curGateway = eg;
448
449             //event-interest
450
} else if (curTag.equals(EVENT_INTEREST)) {
451                 //figure out what factory we want to add
452
String JavaDoc listenerFactoryClassName = attrs.getValue(FACTORY);
453
454                 //now see if the factory name is a property within the current Gateway
455
ListenerFactory lf = null;
456                 try {
457                     Field field = curGateway.getClass().getField(listenerFactoryClassName);
458                     if (field!=null) {
459                         logger.debug("Getting listener factory from gateway: "+field);
460                         lf = (ListenerFactory) field.get(curGateway);
461                     }
462                 } catch (Exception JavaDoc e) {
463                     logger.debug("Failed! "+e+" (this err is not fatal)");
464                 }
465
466                 //if not, we assume it's a class name and try to instantiate it
467
if (lf==null) {
468                     logger.debug("Creating listener factory: "+listenerFactoryClassName);
469                     try {
470                         lf = (ListenerFactory) Class.forName(listenerFactoryClassName, true, Thread.currentThread().getContextClassLoader()).newInstance();
471 //csc_122202.1 objStack.push(lf);
472
} catch (Exception JavaDoc e) {
473                         String JavaDoc msg = "Error instantiating listener factory";
474                         logger.warn(msg+": ",e);
475                         throw new SAXException(msg, e);
476                     }
477                 }
478
479                 //now push the listener factory onto the stack
480
if (lf!=null) objStack.push(lf); //csc_122202.1 - thanks to Srinivas Yermal [syermal@encover.com] for this patch
481

482
483                 //see if there is a specific event to register for
484
String JavaDoc eventClassName = attrs.getValue(EVENT);
485                 Class JavaDoc ev = null;
486                 if (eventClassName!=null) {
487                     logger.debug("Creating event class: "+eventClassName);
488                     try {
489                         ev = Class.forName(eventClassName, true, Thread.currentThread().getContextClassLoader());
490                     } catch (Exception JavaDoc e) {
491                         String JavaDoc msg = "Error creating event class";
492                         logger.warn(msg+": ",e);
493                         throw new SAXException(msg, e);
494                     }
495                 }
496
497                 //now actually specify interests
498
if (ev!=null) curGateway.specifyLocalEventInterests(lf, ev);
499                 else curGateway.specifyLocalEventInterests(lf);
500
501             //event-alias
502
} else if (curTag.equals(EVENT_ALIAS)) {
503                 //see if there is a specific event to register for
504
String JavaDoc eventClassName = attrs.getValue(EVENT);
505                 Class JavaDoc ev = null;
506                 logger.debug("Creating event class: "+eventClassName);
507                 try {
508                     ev = Class.forName(eventClassName, true, Thread.currentThread().getContextClassLoader());
509                 } catch (Exception JavaDoc e) {
510                     String JavaDoc msg = "Error creating event class";
511                     logger.warn(msg+": ",e);
512                     throw new SAXException(msg, e);
513                 }
514
515                 //now actually specify alias'
516
curGateway.specifyLocalEventAliases(ev);
517
518             //set-property
519
} else if (curTag.equals(SET_PROPERTY)) {
520                 //get the property name
521
propName = attrs.getValue(NAME);
522                 propDelegate = attrs.getValue(DELEGATE);
523                 propVal = null;
524                 needPropVal = (propDelegate == null) ? true : false;
525
526             //constant
527
} else if (curTag.equals(CONSTANT)) {
528                 className = attrs.getValue(CLASS);
529                 propName = attrs.getValue(NAME);
530                 propDelegate = attrs.getValue(DELEGATE);
531                 propVal = null;
532                 needPropVal = (propDelegate == null) ? true : false;
533             }
534         }
535
536         public void endElement(String JavaDoc uri, String JavaDoc local, String JavaDoc raw) throws SAXException {
537             String JavaDoc curTag = local;
538
539             //event-gateway
540
if (curTag.equals(EVENT_GATEWAY)) {
541                 logger.debug("Finished w/ gateway: " + curGateway.getClass().getName());
542                 curGateway = curGateway.getParent();
543                 objStack.pop();
544                 depth--;
545
546             //event-interest
547
} else if (curTag.equals(EVENT_INTEREST)) {
548                 objStack.pop();
549
550             //set-property
551
} else if (curTag.equals(SET_PROPERTY)) {
552                 Object JavaDoc parent = objStack.peek();
553                 try {
554                     String JavaDoc methodName = propName;
555                     logger.debug("methodName:" + methodName);
556                     Class JavaDoc clazz = parent.getClass();
557                     Method methods[] = clazz.getMethods();
558                     boolean success = false;
559                     boolean delegate = Boolean.valueOf(propDelegate).booleanValue();
560                     if (logger.isDebugEnabled()) logger.debug("delegate a runtime value? " + delegate);
561
562                     for (int i=0; i<methods.length; i++) {
563                         Method m = methods[i];
564                         if (!m.getName().equalsIgnoreCase("set" + propName)) continue;
565                         methodName = m.getName();
566                         Class JavaDoc paramTypes[] = m.getParameterTypes();
567                         if (paramTypes.length>1) continue;
568                         Class JavaDoc paramType = paramTypes[0];
569                         if (logger.isDebugEnabled()) logger.debug("method:" + methodName + " paramType:" + paramType);
570                         success = setMethod(parent, m, paramType, propVal, delegate);
571                         if (!success) continue;
572                         if (logger.isDebugEnabled()) {
573                             if (delegate) logger.debug("delegate runtime setting of " + parent + "." + methodName + "(\"" + paramType + "\") successful");
574                             else logger.debug(parent + "." + methodName + "(\"" + propVal + "\") successful");
575                         }
576                         break;
577                     }
578
579                     if (!success) {
580                         Field field = clazz.getField(propName);
581                         Class JavaDoc paramType = field.getType();
582                         success = setField(parent, field, paramType, propVal, delegate);
583                         if (success) {
584                             if (logger.isDebugEnabled()) {
585                                 if (delegate) logger.debug("delegate runtime setting of " + parent + "." + propName + " of type " + paramType + " successful");
586                                 else logger.debug(parent + "." + propName + "=\"" + propVal + "\" successful");
587                             }
588                         } else {
589                             throw new SAXException(""); //message is already provided below...
590
}
591                     }
592                 } catch (Exception JavaDoc e) {
593                     String JavaDoc msg = "Error setting " + propName + " in parent:" + parent;
594                     logger.warn(msg+": ",e);
595                     throw new SAXException(msg, e);
596                 }
597             } else if(curTag.equals(CONSTANT)) {
598                 Class JavaDoc clazz = null;
599                 boolean delegate = Boolean.valueOf(propDelegate).booleanValue();
600                 try {
601                     clazz = Class.forName(className, true, Thread.currentThread().getContextClassLoader());
602                     if (logger.isDebugEnabled()) logger.debug("class:" + className);
603                     Field field = clazz.getField(propName);
604                     Class JavaDoc paramType = field.getType();
605                     if (logger.isDebugEnabled()) logger.debug("field:" + propName);
606                     boolean success = setField(clazz, field, paramType, propVal, delegate);
607                     if (success) {
608                         if (logger.isDebugEnabled()) {
609                             if (delegate) logger.debug("delegate runtime setting of " + clazz + "." + propName + " of type " + paramType + " successful");
610                             else logger.debug(clazz + "." + propName + "=\"" + propVal + "\" successful");
611                         }
612                     } else {
613                         throw new SAXException(""); //message is already provided below...
614
}
615                 } catch(Exception JavaDoc e) {
616                     String JavaDoc msg = "Error setting " + propName + " in target:" + clazz;
617                     logger.warn(msg+": ",e);
618                     throw new SAXException(msg, e);
619                 }
620             }
621         }
622
623         public void characters(char ch[], int start, int length) {
624             if(needPropVal) {
625                 propVal = XMLUtil.fromXMLUnicodeString(new String JavaDoc(ch, start, length));
626                 needPropVal = false;
627             } else {
628                 logger.debug("[characters] " + new String JavaDoc(ch, start, length));
629             }
630         }
631
632         public void ignorableWhitespace(char ch[], int start, int length) {
633             logger.debug("[whitespace] " + new String JavaDoc(ch, start, length));
634         }
635
636         public void warning(SAXParseException ex) {
637             System.err.println("[Warning] " + getLocationString(ex) + ": " + ex.getMessage());
638         }
639
640         public void error(SAXParseException ex) {
641             System.err.println("[Error] " + getLocationString(ex) + ": " + ex.getMessage());
642         }
643
644         public void fatalError(SAXParseException ex) throws SAXException {
645             System.err.println("[Fatal Error] " + getLocationString(ex) + ": " + ex.getMessage());
646         }
647
648         private String JavaDoc getLocationString(SAXParseException ex) {
649             StringBuffer JavaDoc str = new StringBuffer JavaDoc();
650             String JavaDoc systemId = ex.getSystemId();
651             if (systemId!=null) {
652                 int index = systemId.lastIndexOf(47);
653                 if (index!=-1) systemId = systemId.substring(index + 1);
654                 str.append(systemId);
655             }
656             str.append(':');
657             str.append(ex.getLineNumber());
658             str.append(':');
659             str.append(ex.getColumnNumber());
660             return str.toString();
661         }
662
663         public boolean setMethod(Object JavaDoc target, Method m, Class JavaDoc paramType, String JavaDoc propVal, boolean delegate) throws InvocationTargetException, IllegalAccessException JavaDoc {
664             if (paramType.equals(String JavaDoc.class)) {
665                 m.invoke(target, new Object JavaDoc[] {propVal});
666                 return true;
667             } else if (paramType.equals(boolean.class) || paramType.equals(Boolean JavaDoc.class)) {
668                 m.invoke(target, new Object JavaDoc[] {new Boolean JavaDoc(propVal)});
669                 return true;
670             } else if (paramType.equals(byte.class) || paramType.equals(Byte JavaDoc.class)) {
671                 m.invoke(target, new Object JavaDoc[] {new Byte JavaDoc(propVal)});
672                 return true;
673             } else if (paramType.equals(char.class) || paramType.equals(Character JavaDoc.class)) {
674                 byte b[] = propVal.getBytes();
675                 m.invoke(target, new Object JavaDoc[] {new Character JavaDoc((char)b[0])});
676                 return true;
677             } else if (paramType.equals(double.class) || paramType.equals(Double JavaDoc.class)) {
678                 m.invoke(target, new Object JavaDoc[] {new Double JavaDoc(propVal)});
679                 return true;
680             } else if (paramType.equals(float.class) || paramType.equals(Float JavaDoc.class)) {
681                 m.invoke(target, new Object JavaDoc[] {new Float JavaDoc(propVal)});
682                 return true;
683             } else if (paramType.equals(int.class) || paramType.equals(Integer JavaDoc.class)) {
684                 m.invoke(target, new Object JavaDoc[] {new Integer JavaDoc(propVal)});
685                 return true;
686             } else if (paramType.equals(long.class) || paramType.equals(Long JavaDoc.class)) {
687                 m.invoke(target, new Object JavaDoc[] {new Long JavaDoc(propVal)});
688                 return true;
689             } else if (paramType.equals(short.class) || paramType.equals(Short JavaDoc.class)) {
690                 m.invoke(target, new Object JavaDoc[] {new Short JavaDoc(propVal)});
691                 return true;
692
693             //begin delegate runtime value setting
694
} else if (delegate && paramType.equals(ServletContext.class)) {
695                 m.invoke(target, new Object JavaDoc[] {servletContext});
696                 return true;
697             } else {
698                 return false;
699             }
700         }
701
702         public boolean setField(Object JavaDoc target, Field field, Class JavaDoc paramType, String JavaDoc propVal, boolean delegate) throws IllegalAccessException JavaDoc {
703             if (paramType.equals(String JavaDoc.class)) {
704                 field.set(target, propVal);
705                 return true;
706             } else if (paramType.equals(boolean.class) || paramType.equals(Boolean JavaDoc.class)) {
707                 field.set(target, new Boolean JavaDoc(propVal));
708                 return true;
709             } else if (paramType.equals(byte.class) || paramType.equals(Byte JavaDoc.class)) {
710                 field.set(target, new Byte JavaDoc(propVal));
711                 return true;
712             } else if (paramType.equals(char.class) || paramType.equals(Character JavaDoc.class)) {
713                 byte b[] = propVal.getBytes();
714                 field.set(target, new Character JavaDoc((char)b[0]));
715                 return true;
716             } else if (paramType.equals(double.class) || paramType.equals(Double JavaDoc.class)) {
717                 field.set(target, new Double JavaDoc(propVal));
718                 return true;
719             } else if (paramType.equals(float.class) || paramType.equals(Float JavaDoc.class)) {
720                 field.set(target, new Float JavaDoc(propVal));
721                 return true;
722             } else if (paramType.equals(int.class) || paramType.equals(Integer JavaDoc.class)) {
723                 field.set(target, new Integer JavaDoc(propVal));
724                 return true;
725             } else if (paramType.equals(long.class) || paramType.equals(Long JavaDoc.class)) {
726                 field.set(target, new Long JavaDoc(propVal));
727                 return true;
728             } else if (paramType.equals(short.class) || paramType.equals(Short JavaDoc.class)) {
729                 field.set(target, new Short JavaDoc(propVal));
730                 return true;
731
732             //begin delegate runtime value setting
733
} else if (delegate && paramType.equals(ServletContext.class)) {
734                 field.set(target, servletContext);
735                 return true;
736             } else {
737                 return false;
738             }
739         }
740     }
741 //kpd_101202.1_end
742

743
744
745
746     public static void main(String JavaDoc[] args) {
747         try {
748             //manually configure the log4j stuff
749
DOMConfigurator.configure("../WEB-INF/log4j.xml");
750
751             //manually run the assembler
752
new DefaultApplicationAssembler().assemble(null, null, "../WEB-INF/event-gateway.xml");
753         } catch (Exception JavaDoc e) {
754             System.out.println("Unexpected Exception: "+e);
755             e.printStackTrace();
756         }
757     }
758
759 }
760
Popular Tags