KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > barracuda > plankton > data > ObjectRepositoryAssembler


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: ObjectRepositoryAssembler.java,v 1.11 2004/02/01 05:16:28 christianc Exp $
19  */

20 package org.enhydra.barracuda.plankton.data;
21
22 import java.io.*;
23 import java.lang.*;
24 import java.lang.reflect.*;
25 import java.util.*;
26 import javax.servlet.*;
27 import javax.servlet.http.*;
28
29 import javax.xml.parsers.*;
30 import org.xml.sax.*;
31 import org.xml.sax.helpers.*;
32 import org.apache.log4j.*;
33 import org.apache.log4j.xml.*;
34
35 import org.enhydra.barracuda.plankton.*;
36 import org.enhydra.barracuda.plankton.xml.*;
37
38
39 /**
40  * This class basically assembles objects into the default ObjectRepository based on
41  * an XML descriptor file. For a sample file look at /WEB-INF/object-repository.xml.
42  * This class demonstrates all the basic functionality, so please be sure to look there
43  * first if you have questions. You may want to run TestObjectRepository.xml to see
44  * it in action.
45  *
46  * <p>In a nutshell, the ObjectRepositoryAssembler is a lightweight scripting mechanism
47  * that makes it possible to instantiate objects, set properties, invoke methods, and
48  * then register objects in the global object repository if you so desire (hence the
49  * class name). This class is extremely useful for configuration, so it will be well
50  * worth your time to learn how it works.
51  *
52  * <p>There are only a few basic tags:
53  * <ul>
54  * <li>
55  * <strong>object</strong> - this tag asks the assembler to instantiate an
56  * object, using the name, class, and arg parameters specified. The object
57  * will be instantiated directly after the start tag is processed (ie. before
58  * any method tags, since the object must exist in order for the methods
59  * to be invoked). If the class referenced has no public constructors, a reference
60  * to the class will be saved, allowing you to invoke public static methods.
61  *
62  * <p>Attributes:<ul>
63  * <li>
64  * <strong>name</strong> - If you specify an object name (ie. '$obj1'),
65  * a reference to the object will be saved for the duration of the
66  * assembly process, allowing you to refer to the object elsewhere
67  * (ie. as a parameter of another method). Note that $this is a reserved
68  * name (the only one actually), which will give you a handle to the
69  * ObjectRepositoryAssembler object, which also happens to be a servlet, thus
70  * making it possible to grab a reference to the ServletConfig object (if you
71  * are assembling in Standalone Application mode, the ServletConfig object
72  * will obviously not be avialable)
73  * </li><li>
74  * <strong>class</strong> - The name of the object to be instantiated. Note that
75  * if no class name is specified, the assembler looks in the object map
76  * for an existing object that matches of this name. This means that if you
77  * specify the class attribute, you will necessarily be forcing instantiation.
78  * So if you want to invoke methods on an existing object, DON'T provide the
79  * class name)
80  * </li><li>
81  * <strong>arg, arg0...arg9</strong> - You can pass args into the object
82  * constructor as well if need be. Frequently, the args might refer to other
83  * named objects.
84  * </li>
85  * </ul>
86  * </li>
87  * <li>
88  * <strong>method</strong> - this tag invokes a method on the object currently
89  * in scope. The method is not actually invoked until the end tag is hit
90  * (allowing us to get any param tags that might accompany the method).
91  *
92  * <p>Attributes:<ul>
93  * <li>
94  * <strong>name</strong> - name of the method to be invoked
95  * </li><li>
96  * <strong>return</strong> - if the method returns an object you can give it
97  * a return name which will cause the object to be available for later reference
98  * by the return name
99  * </li><li>
100  * <strong>arg, arg0...arg9</strong> - You can pass args into the object
101  * constructor as well if need. Frequently, the args might refer to other
102  * named objects.
103  * </li>
104  * </ul>
105  *
106  * <p>In addition to using arg attributes, you can use the value of the method
107  * tag (ie. if you only have one param), or you can use multiple param
108  * tags.
109  * </li>
110  * <li>
111  * <strong>prop</strong> - this tag allows you to set a property in an object (static
112  * or otherwise). The property is not actually set until the end tag is hit
113  * (allowing us to get any param tags that might accompany the prop).
114  *
115  * <p>Attributes:<ul>
116  * <li>
117  * <strong>name</strong> - name of the property to be set
118  * </li>
119  * </ul>
120  *
121  * <p>Unlike the method attribute, prop doesn't take arguments. Instead, you use the
122  * value of the prop to specify what the value should be set to. Right now, Strings,
123  * Integers, Shorts, Longs, Doubles, and Booleans are supported. If you need to set
124  * something of a different type, email the list (its easy to add support for additional
125  * types).
126  * </li>
127  * <li>
128  * <strong>param</strong> - this tag specifies a parameter for a method. Note that
129  * the param type checking is not very sophisticated; if the param is an instance
130  * of a String (as opposed to a reference to a named object), the assembler
131  * will try it first as an int (if possible), else as a String.
132  *
133  * <p>Attributes: n/a
134  * </li>
135  * <li>
136  * <strong>register</strong> - this tag asks the assembler to place the specified
137  * object into the default object repository (usually the global obj repos).
138  *
139  * <p>Attributes:<ul>
140  * <li>
141  * <strong>key</strong> - the key value which may be used to retrieve the object
142  * from the default object repository
143  * </li><li>
144  * <strong>val</strong> - a reference to the item to be placed in the default
145  * object repository (ie. $obj1)
146  * </li>
147  * </ul>
148  * </li>
149  * </ul>
150  */

151 public class ObjectRepositoryAssembler extends HttpServlet {
152
153     //public constants
154
protected static final Logger logger = Logger.getLogger(ObjectRepositoryAssembler.class.getName());
155
156     //private constants
157
public static String JavaDoc ASSEMBLY_DESCRIPTOR = "AssemblyDescriptor";
158     public static String JavaDoc SAX_PARSER = "SAXParser";
159     public static String JavaDoc DEFAULT_DESCRIPTOR = "object-repository.xml";
160     public static String JavaDoc DEFAULT_PARSER = "org.apache.xerces.parsers.SAXParser"; //not used any more
161
public static String JavaDoc LOG_HEARTBEAT_STR = "LogHeartbeat";
162     public static String JavaDoc GLOBAL_CONTINUE_ON_ERR = "ContinueAssemblyOnError"; //csc_041603.2
163

164     //recognized tags
165
private static final String JavaDoc OBJECT = "object";
166     private static final String JavaDoc METHOD = "method";
167     private static final String JavaDoc PROP = "prop";
168     private static final String JavaDoc PARAM = "param";
169     private static final String JavaDoc RETURN = "return";
170     private static final String JavaDoc REGISTER = "register";
171
172     //recognized attributes
173
private static final String JavaDoc NAME = "name";
174     private static final String JavaDoc CLASS = "class";
175     private static final String JavaDoc ARG = "arg";
176     private static final String JavaDoc KEY = "key";
177     private static final String JavaDoc VAL = "val";
178     private static final String JavaDoc CONTINUE_ON_ERR = "continue_on_err"; //csc_041603.2
179

180     //reserved objMap vars
181
private static final String JavaDoc THIS = "$this";
182
183     //private vars
184
protected boolean logHeartbeat = false;
185     public static boolean globalContinueOnErr = false; //csc_041603.2
186

187     public static Class JavaDoc TEST_CLASS = Object JavaDoc.class;
188     public static String JavaDoc TEST_STRING = null;
189     public static String JavaDoc TEST_STRING2 = null;
190     public static String JavaDoc TEST_STRING3 = null;
191     public static int TEST_INT = -1;
192     public static Integer JavaDoc TEST_INT2 = new Integer JavaDoc(-1);
193     public static short TEST_SHORT = -1;
194     public static Short JavaDoc TEST_SHORT2 = new Short JavaDoc((short)-1);
195     public static long TEST_LONG = -1;
196     public static Long JavaDoc TEST_LONG2 = new Long JavaDoc(-1);
197     public static double TEST_DOUBLE = -1;
198     public static Double JavaDoc TEST_DOUBLE2 = new Double JavaDoc(-1);
199     public static float TEST_FLOAT = -1;
200     public static Float JavaDoc TEST_FLOAT2 = new Float JavaDoc(-1);
201     public static boolean TEST_BOOLEAN = false;
202     public static Boolean JavaDoc TEST_BOOLEAN2 = Boolean.FALSE;
203     public static String JavaDoc TEST_STRING88 = null;
204     public static String JavaDoc TEST_STRING99 = null;
205     public static void setTestString2(String JavaDoc s1) {TEST_STRING2 = s1;}
206     public static void setTestString3(String JavaDoc s1, String JavaDoc s2) {TEST_STRING3 = s1+s2;}
207     
208     //--------------- ObjectRepositoryAssembler ------------------
209
/**
210      * Assemble the system into the default ObjectRepository given the
211      * XML assembly decriptor name. The default parser will be
212      * used.
213      *
214      * @param iassemblySourceFile the XML assembly descriptor (if null defaults
215      * to DEFAULT_DESCRIPTOR)
216      */

217     public void assemble(String JavaDoc iassemblySourceFile) {
218         assemble(null, iassemblySourceFile);
219     }
220
221     /**
222      * Assemble the system into the default ObjectRepository given the
223      * XML assembly decriptor name. The default parser will be
224      * used.
225      *
226      * @param iservletConfig the ServletConfig object (may be null if you are
227      * calling this from other than a servlet environment)
228      * @param iassemblySourceFile the XML assembly descriptor (if null defaults
229      * to DEFAULT_DESCRIPTOR)
230      */

231     public void assemble(ServletConfig iservletConfig, String JavaDoc iassemblySourceFile) {
232         assemble(null, iservletConfig, iassemblySourceFile);
233     }
234
235     /**
236      * Assemble the system, given a specified ObjectRepository and the
237      * XML assembly decriptor name. The default parser will be
238      * used.
239      *
240      * @param ior the repository we wish to assemble into (if null
241      * defaults to default ObjectRepository)
242      * @param iservletConfig the ServletConfig object (may be null if you are
243      * calling this from other than a servlet environment)
244      * @param iassemblySourceFile the XML assembly descriptor (if null defaults
245      * to DEFAULT_DESCRIPTOR)
246      */

247     public void assemble(ObjectRepository ior, ServletConfig iservletConfig, String JavaDoc iassemblySourceFile) {
248         assemble(ior, iservletConfig, iassemblySourceFile, null);
249     }
250
251     /**
252      * Assemble the system, given the root EventGateway, an
253      * XML assembly decriptor name, and a specific SAX parser
254      * class.
255      *
256      * @param ior the repository we wish to assemble into (if null
257      * defaults to default ObjectRepository)
258      * @param iservletConfig the ServletConfig object (may be null if you are
259      * calling this from other than a servlet environment)
260      * @param iassemblySourceFile the XML assembly descriptor (if null defaults
261      * to DEFAULT_DESCRIPTOR)
262      * @param iparserClass the SAX parser factory class (if null, defaults to DEFAULT_PARSER)
263      */

264     public void assemble(ObjectRepository ior, ServletConfig iservletConfig, String JavaDoc iassemblySourceFile, String JavaDoc iparserClass) {
265         if (ior==null) ior = ObjectRepository.getGlobalRepository();
266         if (iassemblySourceFile==null) iassemblySourceFile = DEFAULT_DESCRIPTOR;
267         if (iparserClass==null) iparserClass = DEFAULT_PARSER;
268
269
270         InputStream is = null; //This is the InputStream that is eventually passed to the AssemblerXmlReader.
271

272         try {
273             //Setup the assemblerXmlReader
274
AssemblerXMLReader assemblerXmlReader = new AssemblerXMLReader(iparserClass, ior);
275             assemblerXmlReader.setup();
276
277             String JavaDoc normalizedFilePath = getNormalizedPath(iassemblySourceFile);
278             //Attempt to load from the WEB-INF Dir
279
if (iservletConfig!=null) {
280                 //first assume that the file was given the full path specified relative to the root of the webapp.
281
//eg... "/WEB-INF/myresource.xml" or "WEB-INF/myresource.xml"
282
if (logger.isDebugEnabled()) logger.debug("Attempting to load assembly file via servlet context at: /"+normalizedFilePath);
283                 is = iservletConfig.getServletContext().getResourceAsStream("/" + normalizedFilePath);
284                 if (is==null) {
285                     //maybe only the filename is provided with no extra path. Alternatively, maybe the path
286
//given was a path relative to /WEB-INF/ rather than the root of the webapp. Try loading from /WEB-INF/.
287
if (logger.isDebugEnabled()) logger.debug("Attempting to load assembly file via servlet context at: /WEB-INF/"+normalizedFilePath);
288                     is = iservletConfig.getServletContext().getResourceAsStream("/WEB-INF/" + normalizedFilePath);
289                     if (is==null) {
290                         //maybe only the filename is provided with no extra path. Alternatively, maybe the path
291
//given was a package path, in which case the path would be relative to /WEB-INF/classes/
292
//rather than the root of the webapp. Try loading from /WEB-INF/classes/.
293
if (logger.isDebugEnabled()) logger.debug("Attempting to load assembly file via servlet context at: /WEB-INF/classes/"+normalizedFilePath);
294                         is = iservletConfig.getServletContext().getResourceAsStream("/WEB-INF/classes/" + normalizedFilePath);
295                     }
296                 }
297             }
298
299             //resource does not exist inside the webapp at the path specified. Try loading via the classloader.
300
if (is==null) {
301                 if (logger.isDebugEnabled()) logger.debug("Attempting to load assembly file inside the local classloader: "+normalizedFilePath);
302                 is = this.getClass().getClassLoader().getResourceAsStream(normalizedFilePath);
303                 if (is==null) {
304                     //this should only get triggered in the case that this class exists in a parent
305
//classloader and the resource exists in a child classloader. eg... in the WebappClassloader.
306
if (logger.isDebugEnabled()) logger.debug("Attempting to load assembly file inside all available classloaders: "+normalizedFilePath);
307                     Thread.currentThread().getContextClassLoader().getResourceAsStream(normalizedFilePath);
308                 }
309             }
310
311             //Not a webapp or path specified is outside of the webapp. Attempt to load using the full file path
312
if (is==null) {
313                 if (logger.isDebugEnabled()) logger.debug("Attempting to load assembly file via file IO at: "+iassemblySourceFile);
314                 File f = new File(iassemblySourceFile);
315                 is = new FileInputStream(f);
316             }
317
318             if (is!=null) {
319                 String JavaDoc logString = "Configuring "+ior.getName()+" from File: "+iassemblySourceFile;
320                 if (iservletConfig != null) iservletConfig.getServletContext().log(logString);
321                 if (logHeartbeat) System.out.println(logString);
322                 if (logger.isDebugEnabled()) logger.debug(logString);
323             }
324             assemblerXmlReader.processXmlFile(is);
325
326         } catch (Exception JavaDoc e) {
327             logger.warn("Error assembling system!", e);
328             e.printStackTrace(System.err);
329         }
330
331     }
332
333     //Take a path a normalize it... eg. make WEB-INF/somefile.xml and /WEB-INF/somefile.xml equivalent
334
private static String JavaDoc getNormalizedPath(String JavaDoc filePath) {
335         if (filePath!=null) {
336             if (filePath.startsWith("/")) filePath = (filePath.length() > 1) ? filePath.substring(1) : "";
337         }
338         return filePath;
339     }
340
341     //--------------- DefaultHandler -----------------------------
342
public class AssemblerXMLReader extends DefaultHandler {
343         String JavaDoc parserClass = null;
344         ObjectRepository or = null;
345         Stack objStack = null;
346         boolean needPropVal = false;
347         String JavaDoc className = null;
348         String JavaDoc propName = null;
349         String JavaDoc propVal = null;
350         int depth = 0;
351         Map objMap = new HashMap();
352         List argList = new ArrayList();
353         String JavaDoc methodName = null;
354         String JavaDoc returnName = null;
355         int paramCntr = -1;
356         boolean localContinueOnErr = false; //csc_041603.2
357
String JavaDoc skipUntilTagName = null; //csc_041603.2
358

359         XMLReader parser = null; //Since the 'ProcessXml' method can be called multiple times,
360
// a single instance of the XmlReader is needed.
361

362         public AssemblerXMLReader() {
363             objMap.put(THIS, ObjectRepositoryAssembler.this);
364         }
365
366         public AssemblerXMLReader(String JavaDoc parserClass, ObjectRepository ior) {
367             objMap.put(THIS, ObjectRepositoryAssembler.this);
368             setParserClass(parserClass);
369             setObjectRepository(ior);
370         }
371
372         /**
373          * Sets the SAX Parser
374          * @param iparserClass the SAX parser class (if null, defaults to DEFAULT_PARSER)
375          */

376         public void setParserClass(String JavaDoc iparserClass) {
377             this.parserClass = iparserClass;
378         }
379
380         /**
381          * Sets the ObjectRepository that should be used
382          * @param ior the object repository
383          */

384         public void setObjectRepository(ObjectRepository ior) {
385             this.or = ior;
386         }
387
388         /**
389          * Initialization stuff... (Need a better description here!)
390          */

391         public void setup() {
392             try {
393                 if (parserClass==null) parserClass = DEFAULT_PARSER;
394 // logger.info("Instantiating parser ("+parserClass+")");
395
// parser = (XMLReader) Thread.currentThread().getContextClassLoader().loadClass(parserClass).newInstance();
396
SAXParserFactory spf = SAXParserFactory.newInstance();
397                 logger.info("Using sax parser factory "+spf);
398                 spf.setNamespaceAware(true);
399                 parser = spf.newSAXParser().getXMLReader();
400                 logger.info("Using sax parser impl "+parser);
401             } catch (Exception JavaDoc e) {
402                 logger.warn("Error assembling system!", e);
403                 e.printStackTrace(System.err);
404             }
405         }
406
407         //This is the core method...
408
public void processXmlFile(InputStream is) {
409             try {
410                 //get the source file
411
InputSource source = new InputSource(is);
412
413                 //parse the file
414
logger.info("Assembling source file...");
415                 parser.setContentHandler(this);
416                 parser.setErrorHandler(this);
417                 parser.parse(source);
418                 logger.info("Assembly complete!");
419
420             } catch (org.xml.sax.SAXParseException JavaDoc spe) {
421                 logger.warn("Error assembling system!", spe);
422                 spe.printStackTrace(System.err);
423             } catch (org.xml.sax.SAXException JavaDoc se) {
424                 if (se.getException() != null) {
425                     logger.warn("Error assembling system!", se.getException());
426                     se.getException().printStackTrace(System.err);
427                 } else {
428                     logger.warn("Error assembling system!", se);
429                     se.printStackTrace(System.err);
430                 }
431             } catch (Exception JavaDoc e) {
432                 logger.warn("Error assembling system!", e);
433                 e.printStackTrace(System.err);
434             }
435         }
436
437         public void startDocument() {
438             objStack = new Stack();
439         }
440
441         public void startElement(String JavaDoc uri, String JavaDoc local, String JavaDoc raw, Attributes attrs) throws SAXException {
442             String JavaDoc curTag = local;
443             logger.debug("Starting w/: " + curTag);
444             logger.debug("uri:"+uri+" local:"+local+" raw:"+raw+" attrs:"+attrs);
445
446             //csc_041603.2_start
447
if (skipUntilTagName!=null) {
448                 logger.warn("Skipping start tag <"+curTag+"> because of error handling <"+skipUntilTagName+">");
449                 return;
450             }
451             String JavaDoc continue_on_err = attrs.getValue(CONTINUE_ON_ERR);
452             localContinueOnErr = (continue_on_err!=null &&
453                                   (continue_on_err.toLowerCase().equals("true") ||
454                                    continue_on_err.toLowerCase().equals("yes") ||
455                                    continue_on_err.toLowerCase().equals("1")));
456             boolean continueOnErr = (globalContinueOnErr || localContinueOnErr);
457             //csc_041603.2_end
458

459
460             //object - we need to create a new object and store it in the object map
461
if (curTag.equals(OBJECT)) {
462
463                 //start by getting the attrs and any args
464
depth++;
465                 String JavaDoc objname = attrs.getValue(NAME);
466                 String JavaDoc clname = attrs.getValue(CLASS);
467                 Object JavaDoc arg = resolve(attrs.getValue(ARG));
468                 
469                 //if you reference this, the class and arg attributes should be ignored
470
if (THIS.equals(objname)) {
471                     clname = null;
472                     arg = null;
473                     
474                 //otherwise, go ahead and build the arglist
475
} else {
476                     if (arg!=null) argList.add(arg);
477                     for (int i=0; i<10; i++) {
478                         arg = resolve(attrs.getValue(ARG+i));
479                         if (arg!=null) argList.add(arg);
480                     }
481                 }
482                 
483                 //first see if we can get the object from the map (this makes it possible
484
//to reference a previously instantiated object). We only do this, however, if the
485
//class name is NOT specified
486
Class JavaDoc cl = null;
487                 Object JavaDoc obj = null;
488                 if (objname!=null && clname==null) obj = objMap.get(objname);
489                 if (obj!=null) {
490                     cl = obj.getClass();
491                     logger.info("Using existing obj "+obj.getClass().getName()+"@"+Integer.toHexString(obj.hashCode()));
492                 }
493
494                 //now try and instantiate it
495
if (obj==null) try {
496                     if (logger.isDebugEnabled()) {
497                         logger.debug("Trying to create new --> objname:"+objname+" clname:"+clname);
498                         if (argList.size()>0) {
499                             String JavaDoc s = " args:";
500                             String JavaDoc sep = "";
501                             for (int i=0; i<argList.size(); i++) {
502                                 s = s+sep+argList.get(i);
503                                 sep = ", ";
504                             }
505                             logger.debug(s);
506                         }
507                     }
508
509                     //jrk_20020414.2_start
510
//Class.forName is java1. Since Java2, use
511
//Thread.currentThread().getContextClassLoader().loadClass("MyClass")
512
//This should fix some classloading issues in Engines with multiple
513
//class loaders (eg.. Tomcat-3.3.x and Tomcat-4.x.x)
514
//cl = Class.forName(clname);
515
cl = Thread.currentThread().getContextClassLoader().loadClass(clname);
516                     //jrk_20020414.2_end
517

518                     if (argList.size()<1) {
519                         try {
520                             obj = cl.newInstance();
521                             logger.info("Instantiating "+obj.getClass().getName());
522                         
523                         //this err occurs when the class has no public constructor; in that case, we
524
//want to save a reference to the class, and then only allow static methods to
525
//be invoked
526
} catch (IllegalAccessException JavaDoc e) {
527                             obj = cl;
528                             logger.info("Creating handle to class "+cl.getName()+" (for subsequent static invocation)");
529                         }
530                     } else {
531                         Object JavaDoc args[] = new Object JavaDoc[argList.size()];
532                         Class JavaDoc argcl[] = new Class JavaDoc[argList.size()];
533                         for (int i=0; i<argList.size(); i++) {
534                             args[i] = argList.get(i);
535                             argcl[i] = argList.get(i).getClass();
536                         }
537
538                         if (logger.isDebugEnabled()) {
539                             StringBuffer JavaDoc sb = new StringBuffer JavaDoc("Looking for constructor "+clname+"{");
540                             String JavaDoc sep = "";
541                             for (int i=0; i<argList.size(); i++) {
542                                 sb.append(sep+argcl[i].getName());
543                                 sep = ", ";
544                             }
545                             sb.append("}");
546                             logger.debug(sb.toString());
547                         }
548                         Constructor constructor = null;
549                         try {
550                             constructor = cl.getConstructor(argcl);
551                         } catch (Exception JavaDoc e) {
552                         }
553                         obj = constructor.newInstance(args);
554                         logger.info("Instantiating "+obj.getClass().getName()+"@"+Integer.toHexString(obj.hashCode()));
555                     }
556                 } catch (Exception JavaDoc e) {
557                     String JavaDoc msg = "Error instantiating object";
558                     logger.warn(msg+": ", e);
559                     if (continueOnErr) {
560                         logger.warn("Skipping tag <"+curTag+"> because of error...");
561                         skipUntilTagName = curTag;
562                         return;
563                     } else {
564                         throw new SAXException(msg, e);
565                     }
566                 }
567
568                 //push the object onto the stack
569
objStack.push(obj);
570
571                 //finally, if there was a name register the object accordingly
572
if (objname!=null) {
573                     objMap.put(objname, obj);
574                 }
575
576             //method - invoke a method
577
} else if (curTag.equals(METHOD)) {
578                 argList = new ArrayList(); //csc_111203_1 - any time we start a method, make sure we clean up the arglist
579
methodName = attrs.getValue(NAME);
580                 returnName = attrs.getValue(RETURN);
581                 Object JavaDoc arg = resolve(attrs.getValue(ARG));
582                 if (arg!=null) argList.add(arg);
583                 for (int i=0; i<10; i++) {
584                     arg = resolve(attrs.getValue(ARG+i));
585                     if (arg!=null) argList.add(arg);
586                 }
587                 propVal = null;
588                 needPropVal = true;
589                 paramCntr = -1;
590
591             //csc_052902.1 - added
592
//prop - set a property
593
} else if (curTag.equals(PROP)) {
594                 propName = attrs.getValue(NAME);
595                 propVal = null;
596                 needPropVal = true;
597                 paramCntr = -1;
598
599             //param - parameter (add to args list)
600
} else if (curTag.equals(PARAM)) {
601                 //the first time we hit a param tag after a method tag,
602
//reset the argList (because it may contain a blank parameter)
603
if (++paramCntr==0) argList = new ArrayList();
604                 propVal = null;
605                 needPropVal = true;
606
607             //register - register an object in the repository
608
} else if (curTag.equals(REGISTER)) {
609                 String JavaDoc key = attrs.getValue(KEY);
610                 Object JavaDoc val = resolve(attrs.getValue(VAL));
611                 String JavaDoc qt = (val instanceof String JavaDoc || val instanceof StringBuffer JavaDoc ? "'" : "");
612                 logger.info("Registering "+key+" = "+qt+val+qt+" in the object repository");
613                 or.putState(key, val);
614             }
615         }
616
617         public void endElement(String JavaDoc uri, String JavaDoc local, String JavaDoc raw) throws SAXException {
618             String JavaDoc curTag = local;
619
620             //csc_041603.2_start
621
if (skipUntilTagName!=null) {
622                 if (skipUntilTagName.equals(curTag)) {
623                     logger.warn("Found end of error tag <"+skipUntilTagName+">");
624                     skipUntilTagName = null;
625                 } else {
626                     logger.warn("Skipping end tag <"+curTag+"> because of error handling <"+skipUntilTagName+">");
627                 }
628                 return;
629             }
630             boolean continueOnErr = (globalContinueOnErr || localContinueOnErr);
631             //csc_041603.2_end
632

633             //object
634
if (curTag.equals(OBJECT)) {
635                 //pop the object back off the stack
636
objStack.pop();
637                 argList = new ArrayList();
638                 depth--;
639
640             //param
641
} else if (curTag.equals(PARAM)) {
642
643             //method - here's where we actually invoke the method
644
} else if (curTag.equals(METHOD)) {
645                 StringBuffer JavaDoc mthsb = new StringBuffer JavaDoc(methodName+"(");
646                 if (argList.size()>0) {
647                     String JavaDoc s = " args:";
648                     String JavaDoc sep = "";
649                     for (int i=0; i<argList.size(); i++) {
650                         mthsb.append(sep+argList.get(i));
651                         sep = ", ";
652                     }
653                     mthsb.append(")");
654                 }
655                 logger.debug("Invoking method--> "+mthsb.toString());
656
657                 //get the target object
658
Object JavaDoc targetObj = objStack.peek();
659                 List clList = new ArrayList();
660                 List mthList = new ArrayList();
661                 Class JavaDoc ocl = (targetObj instanceof Class JavaDoc ? (Class JavaDoc) targetObj : targetObj.getClass());
662                 while (true) {
663                     Method allMethods[] = ocl.getDeclaredMethods();
664                     for (int i=0; i<allMethods.length; i++) {
665                         Method m = allMethods[i];
666                         if (!m.getName().equals(methodName)) continue;
667                         int mod = m.getModifiers();
668                         if (!Modifier.isPublic(mod)) continue;
669                         Class JavaDoc paramCl[] = m.getParameterTypes();
670                         if (paramCl.length!=argList.size()) continue;
671                         logger.debug("found possible method:"+m+" paramCl:"+paramCl+" paramCl.length:"+paramCl.length);
672                         if (paramCl!=null && paramCl.length>0 && paramCl[0]==String JavaDoc.class) mthList.add(0, m); //methods which take String params should be given preference (since we're already dealing with String data)
673
else mthList.add(m);
674                         clList.add(ocl);
675                     }
676                     if (ocl==Object JavaDoc.class) break;
677                     ocl = ocl.getSuperclass();
678                 }
679                 if (mthList.size()<1) {
680                     String JavaDoc msg = "Unable to find matching method: "+mthsb.toString();
681                     logger.warn(msg);
682                     if (continueOnErr) {
683                         logger.warn("Skipping tag <"+curTag+"> because of error...");
684                         skipUntilTagName = curTag;
685                         return;
686                     } else {
687                         throw new SAXException(msg);
688                     }
689                 }
690
691                 //now we need to iterate through the methods we found and see if we
692
//can invoke them
693
boolean success = false;
694                 methodsIterate: for (int i=0; i<mthList.size(); i++) {
695                     //start by trying to convert the params into the target types
696
Method m = (Method) mthList.get(i);
697                     logger.debug("trying so see if we can invoke method "+m);
698                     Class JavaDoc paramTypes[] = m.getParameterTypes();
699                     Object JavaDoc args[] = new Object JavaDoc[paramTypes.length];
700                     for (int j=0; j<argList.size(); j++) {
701                         Object JavaDoc arg = argList.get(j);
702                         if (arg instanceof String JavaDoc) {
703                             String JavaDoc sarg = (String JavaDoc) arg;
704                             Class JavaDoc targetParamCl = null;
705                             try {
706                                 //..Integer
707
if (paramTypes[j]==int.class) {
708                                     targetParamCl = Integer JavaDoc.class;
709                                     args[j] = new Integer JavaDoc(sarg);
710
711                                 //..Short
712
} else if (paramTypes[j]==short.class) {
713                                     targetParamCl = Short JavaDoc.class;
714                                     args[j] = new Short JavaDoc(sarg);
715
716                                 //..Long
717
} else if (paramTypes[j]==long.class) {
718                                     targetParamCl = Long JavaDoc.class;
719                                     args[j] = new Long JavaDoc(sarg);
720
721                                 //..Double
722
} else if (paramTypes[j]==double.class) {
723                                     targetParamCl = Double JavaDoc.class;
724                                     args[j] = new Double JavaDoc(sarg);
725
726                                 //..Float
727
} else if (paramTypes[j]==float.class) {
728                                     targetParamCl = Float JavaDoc.class;
729                                     args[j] = new Float JavaDoc(sarg);
730
731                                 //..Class - //csc_010404_1 - added
732
} else if (paramTypes[j]==Class JavaDoc.class) {
733                                     targetParamCl = Class JavaDoc.class;
734                                     args[j] = Classes.getClass(sarg);
735
736                                 //..String
737
} else {
738                                     args[j] = arg;
739                                 }
740                             } catch (Exception JavaDoc e) {
741                                 logger.debug("error trying to cast arg"+j+" to "+paramTypes[j]+"...trying next method");
742                             }
743                         } else {
744                             args[j] = arg;
745                         }
746                     }
747                     
748                     //now try and invoke the method
749
try {
750                         logger.info("...Invoking "+targetObj.getClass().getName()+"@"+Integer.toHexString(targetObj.hashCode())+"."+mthsb.toString());
751                         Object JavaDoc o = m.invoke(targetObj, args);
752                         if (returnName!=null) {
753                             logger.debug("...Saving reference "+returnName+" to "+(o!=null ? o.getClass().getName()+"@"+Integer.toHexString(o.hashCode()) : "null"));
754                             objMap.put(returnName, o);
755                         }
756                         success = true;
757                         logger.debug("successfully invoked: "+m);
758                         break;
759                     } catch (Exception JavaDoc e) {
760                         logger.debug("error invoking method m:"+e);
761                         continue;
762                     }
763                 }
764                 if (!success) {
765                     String JavaDoc msg = "Unable to invoke method: "+mthsb.toString();
766                     logger.warn(msg);
767                     if (continueOnErr) {
768                         logger.warn("Skipping tag <"+curTag+"> because of error...");
769                         skipUntilTagName = curTag;
770                         return;
771                     } else {
772                         throw new SAXException(msg);
773                     }
774                 }
775
776                 //make sure we clean up the argList
777
argList = new ArrayList();
778
779             //csc_052902.1 - added
780
//prop - here's where we actually set the property
781
} else if (curTag.equals(PROP)) {
782                 logger.debug("Setting prop--> "+propName+"="+propVal);
783
784                 //get the target object
785
Object JavaDoc targetObj = objStack.peek();
786                 Field fld = null;
787                 Class JavaDoc ocl = targetObj.getClass();
788                 while (true) {
789                     Field allFields[] = ocl.getDeclaredFields();
790                     for (int i=0; i<allFields.length; i++) {
791                         Field f = allFields[i];
792                         if (f.getName().equals(propName) && Modifier.isPublic(f.getModifiers())) {
793                             logger.debug("found property:"+f);
794                             fld = f;
795                             break;
796                         }
797                     }
798                     if (ocl==Object JavaDoc.class) break;
799                     ocl = ocl.getSuperclass();
800                 }
801                 if (fld==null) {
802                     String JavaDoc msg = "Unable to find matching property: "+propName;
803                     logger.warn(msg);
804                     if (continueOnErr) {
805                         logger.warn("Skipping tag <"+curTag+"> because of error...");
806                         skipUntilTagName = curTag;
807                         return;
808                     } else {
809                         throw new SAXException(msg);
810                     }
811                 }
812
813                 //now we need to set the property
814
try {
815                     Object JavaDoc iprop = fld.get(targetObj);
816 //csc_010404_1_start
817
// Class targetClass = (iprop!=null ? iprop.getClass() : String.class);
818
Class JavaDoc targetClass = String JavaDoc.class;
819                     if (iprop!=null) {
820                         if (iprop instanceof Class JavaDoc) targetClass = Class JavaDoc.class;
821                         else targetClass = iprop.getClass();
822                     }
823 //csc_010404_1_start
824
logger.debug("targetObj:"+targetObj+" iprop:"+iprop+" targetClass:"+targetClass);
825                     Object JavaDoc targetProp = null;
826                     if (propVal!=null) {
827
828                         //..Integer
829
if (targetClass.equals(Integer JavaDoc.class)) {
830                             targetProp = new Integer JavaDoc(propVal);
831
832                         //..Short
833
} else if (targetClass.equals(Short JavaDoc.class)) {
834                             targetProp = new Short JavaDoc(propVal);
835
836                         //..Long
837
} else if (targetClass.equals(Long JavaDoc.class)) {
838                             targetProp = new Long JavaDoc(propVal);
839
840                         //..Double
841
} else if (targetClass.equals(Double JavaDoc.class)) {
842                             targetProp = new Double JavaDoc(propVal);
843
844                         //..Float
845
} else if (targetClass.equals(Float JavaDoc.class)) {
846                             targetProp = new Float JavaDoc(propVal);
847
848                         //..Class - //csc_010404_1 - added
849
} else if (targetClass.equals(Class JavaDoc.class)) {
850                             targetProp = Classes.getClass(propVal);
851
852                         //..Boolean
853
} else if (targetClass.equals(Boolean JavaDoc.class)) {
854                             String JavaDoc tpropVal = propVal.toLowerCase().trim();
855                             targetProp = new Boolean JavaDoc(tpropVal.equals("true") || tpropVal.equals("yes") || tpropVal.equals("on") || tpropVal.equals("1"));
856
857                         //..String
858
} else {
859                             targetProp = new String JavaDoc(propVal);
860                         }
861                     }
862                     String JavaDoc bracket = (propVal instanceof String JavaDoc ? "\"" : "");
863                     logger.info("...Setting "+fld.getDeclaringClass().getName()+"."+propName+" = "+bracket+targetProp+bracket+" ("+targetClass.getName()+")");
864                     fld.set(targetObj, targetProp);
865
866                 } catch (IllegalAccessException JavaDoc e) {
867                     String JavaDoc msg = "Unexpected IllegalAccessException:"+e;
868                     logger.warn(msg);
869                     if (continueOnErr) {
870                         logger.warn("Skipping tag <"+curTag+"> because of error...");
871                         skipUntilTagName = curTag;
872                         return;
873                     } else {
874                         throw new SAXException(msg);
875                     }
876                 }
877
878                 //make sure we clean up the argList
879
argList = new ArrayList(); //csc_111203_1 - added; we need to clean up the argList after PROPs as well as after METHODS (which we were doing already)
880
}
881
882             logger.debug("Finished w/: " + curTag);
883         }
884
885         public void characters(char ch[], int start, int length) {
886             //csc_041603.2 - added
887
if (skipUntilTagName!=null) return;
888
889             if (needPropVal) {
890 //System.out.println("ch:"+ch+" start:"+start+" length:"+length+" ch.length:"+ch.length);
891
//System.out.println("str:'"+new String(ch, start, length)+"'");
892
//System.out.println("xml:'"+XMLUtil.fromXMLUnicodeString(new String(ch, start, length))+"'");
893
propVal = XMLUtil.fromXMLUnicodeString(new String JavaDoc(ch, start, length)).trim();
894                 if (propVal!=null) argList.add(propVal);
895                 logger.debug("got propVal:"+propVal);
896                 needPropVal = false;
897             } else {
898 // logger.debug("[characters] " + new String(ch, start, length));
899
}
900         }
901
902         public void ignorableWhitespace(char ch[], int start, int length) {
903 // logger.debug("[whitespace] " + new String(ch, start, length));
904
}
905
906         public void warning(SAXParseException ex) {
907             System.err.println("[Warning] " + getLocationString(ex) + ": " + ex.getMessage());
908         }
909
910         public void error(SAXParseException ex) {
911             System.err.println("[Error] " + getLocationString(ex) + ": " + ex.getMessage());
912         }
913
914         public void fatalError(SAXParseException ex) throws SAXException {
915             System.err.println("[Fatal Error] " + getLocationString(ex) + ": " + ex.getMessage());
916         }
917
918         private String JavaDoc getLocationString(SAXParseException ex) {
919             StringBuffer JavaDoc str = new StringBuffer JavaDoc();
920             String JavaDoc systemId = ex.getSystemId();
921             if (systemId!=null) {
922                 int index = systemId.lastIndexOf(47);
923                 if (index!=-1) systemId = systemId.substring(index + 1);
924                 str.append(systemId);
925             }
926             str.append(':');
927             str.append(ex.getLineNumber());
928             str.append(':');
929             str.append(ex.getColumnNumber());
930             return str.toString();
931         }
932
933         protected Object JavaDoc resolve(Object JavaDoc id) {
934             if (id==null) return null;
935             if (id.equals("null")) return null;
936             if (objMap.containsKey(id)) {
937                 return objMap.get(id);
938             } else {
939                 return id.toString();
940             }
941         }
942     }
943
944
945     //--------------- HttpServlet --------------------------------
946
/**
947      * This class extends HttpServlet primarily for convenience, so that you easily
948      * use it to set up a servlet environment. The servlet methods that handle requests
949      * do not do anything; it all happens in the config.
950      */

951     public void init() throws ServletException {
952         logger.info("Attempting to setup default ObjectRepository (HTTP interface)");
953         String JavaDoc descriptor = getInitParameter(ASSEMBLY_DESCRIPTOR);
954         String JavaDoc parser = getInitParameter(SAX_PARSER);
955         String JavaDoc hbparm = getInitParameter(LOG_HEARTBEAT_STR);
956         if (hbparm!=null) {
957             hbparm = hbparm.toLowerCase();
958             logHeartbeat = (hbparm.equals("true") || hbparm.equals("yes") ||
959                             hbparm.equals("on") || hbparm.equals("1"));
960         }
961         //csc_041603.2_start
962
String JavaDoc continue_on_err = getInitParameter(GLOBAL_CONTINUE_ON_ERR);
963         globalContinueOnErr = (continue_on_err!=null &&
964                                (continue_on_err.toLowerCase().equals("true") ||
965                                 continue_on_err.toLowerCase().equals("yes") ||
966                                 continue_on_err.toLowerCase().equals("1")));
967         //csc_041603.2_end
968
this.assemble(null, this, descriptor, parser);
969     }
970
971
972     public static void main(String JavaDoc[] args) {
973         //manually configure the log4j stuff
974
DOMConfigurator.configure("../WEB-INF/log4j.xml");
975
976         //assemble into the default ObjectRepository (you may need to put the
977
//xml file in the classes directory in order to find it if you are
978
//running this standalone)
979

980         logger.info("Attempting to setup default ObjectRepository (Application interface)");
981         new ObjectRepositoryAssembler().assemble("../WEB-INF/object-repository.xml");
982         logger.info("Assembly complete!");
983
984         //check the prop value
985
System.out.println("TEST_STRING:"+TEST_STRING);
986         System.out.println("TEST_INT:"+TEST_INT);
987         System.out.println("TEST_SHORT:"+TEST_SHORT);
988         System.out.println("TEST_LONG:"+TEST_LONG);
989         System.out.println("TEST_DOUBLE:"+TEST_DOUBLE);
990         System.out.println("TEST_FLOAT:"+TEST_FLOAT);
991         System.out.println("TEST_BOOLEAN:"+TEST_BOOLEAN);
992         System.out.println("TEST_INT2:"+TEST_INT2);
993         System.out.println("TEST_SHORT2:"+TEST_SHORT2);
994         System.out.println("TEST_LONG2:"+TEST_LONG2);
995         System.out.println("TEST_DOUBLE2:"+TEST_DOUBLE2);
996         System.out.println("TEST_FLOAT2:"+TEST_FLOAT2);
997         System.out.println("TEST_BOOLEAN2:"+TEST_BOOLEAN2);
998
999         //check and make sure it's there
1000
ObjectRepository or = ObjectRepository.getGlobalRepository();
1001        List keys = or.getStateKeys();
1002        if (keys!=null) {
1003            Iterator it = keys.iterator();
1004            while (it.hasNext()) {
1005                Object JavaDoc key = it.next();
1006                Object JavaDoc val = or.getState(key);
1007                System.out.println("Key:"+key+" Val:"+val);
1008            }
1009        }
1010    }
1011
1012}
1013
Popular Tags