KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcorporate > expresso > core > misc > ConfigManager


1 /* ====================================================================
2 * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
3 *
4 * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * 3. The end-user documentation included with the redistribution,
19 * if any, must include the following acknowledgment:
20 * "This product includes software developed by Jcorporate Ltd.
21 * (http://www.jcorporate.com/)."
22 * Alternately, this acknowledgment may appear in the software itself,
23 * if and wherever such third-party acknowledgments normally appear.
24 *
25 * 4. "Jcorporate" and product names such as "Expresso" must
26 * not be used to endorse or promote products derived from this
27 * software without prior written permission. For written permission,
28 * please contact info@jcorporate.com.
29 *
30 * 5. Products derived from this software may not be called "Expresso",
31 * or other Jcorporate product names; nor may "Expresso" or other
32 * Jcorporate product names appear in their name, without prior
33 * written permission of Jcorporate Ltd.
34 *
35 * 6. No product derived from this software may compete in the same
36 * market space, i.e. framework, without prior written permission
37 * of Jcorporate Ltd. For written permission, please contact
38 * partners@jcorporate.com.
39 *
40 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
41 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43 * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
44 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
46 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
47 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 * ====================================================================
53 *
54 * This software consists of voluntary contributions made by many
55 * individuals on behalf of the Jcorporate Ltd. Contributions back
56 * to the project(s) are encouraged when you make modifications.
57 * Please send them to support@jcorporate.com. For more information
58 * on Jcorporate Ltd. and its products, please see
59 * <http://www.jcorporate.com/>.
60 *
61 * Portions of this software are based upon other open source
62 * products and are subject to their respective licenses.
63  */

64
65 package com.jcorporate.expresso.core.misc;
66
67 import com.jcorporate.expresso.core.cache.CacheManager;
68 import com.jcorporate.expresso.core.controller.ControllerException;
69 import com.jcorporate.expresso.core.controller.ControllerFactory;
70 import com.jcorporate.expresso.core.db.DBConnectionPool;
71 import com.jcorporate.expresso.core.db.DBException;
72 import com.jcorporate.expresso.core.dbobj.DBObject;
73 import com.jcorporate.expresso.core.dbobj.Schema;
74 import com.jcorporate.expresso.core.dbobj.SchemaFactory;
75 import com.jcorporate.expresso.core.dbobj.SecuredDBObject;
76 import com.jcorporate.expresso.core.job.ServerException;
77 import com.jcorporate.expresso.core.jsdkapi.GenericDispatcher;
78 import com.jcorporate.expresso.core.registry.MutableRequestRegistry;
79 import com.jcorporate.expresso.core.registry.RequestRegistry;
80 import com.jcorporate.expresso.core.security.SuperUser;
81 import com.jcorporate.expresso.core.security.User;
82 import com.jcorporate.expresso.core.utility.JobHandler;
83 import com.jcorporate.expresso.kernel.LogManager;
84 import com.jcorporate.expresso.kernel.digester.SaxParserConfigurer;
85 import com.jcorporate.expresso.kernel.util.FastStringBuffer;
86 import com.jcorporate.expresso.services.dbobj.DBOtherMap;
87 import com.jcorporate.expresso.services.dbobj.SchemaList;
88 import com.jcorporate.expresso.services.dbobj.Setup;
89 import com.jcorporate.expresso.services.test.TestSystemInitializer;
90 import org.apache.commons.beanutils.BeanUtils;
91 import org.apache.commons.digester.Digester;
92 import org.apache.log4j.Logger;
93 import org.apache.struts.action.ActionMapping;
94 import org.apache.struts.config.ActionConfig;
95 import org.apache.struts.config.ForwardConfig;
96 import org.apache.struts.config.ModuleConfig;
97 import org.xml.sax.InputSource JavaDoc;
98 import org.xml.sax.SAXException JavaDoc;
99
100 import javax.servlet.ServletConfig JavaDoc;
101 import javax.servlet.ServletContext JavaDoc;
102 import javax.servlet.ServletException JavaDoc;
103 import javax.servlet.http.HttpServletRequest JavaDoc;
104 import java.io.File JavaDoc;
105 import java.io.FileInputStream JavaDoc;
106 import java.io.FileNotFoundException JavaDoc;
107 import java.io.IOException JavaDoc;
108 import java.net.URL JavaDoc;
109 import java.util.ArrayList JavaDoc;
110 import java.util.Enumeration JavaDoc;
111 import java.util.HashMap JavaDoc;
112 import java.util.Hashtable JavaDoc;
113 import java.util.Iterator JavaDoc;
114 import java.util.List JavaDoc;
115 import java.util.Map JavaDoc;
116 import java.util.Vector JavaDoc;
117
118 /**
119  * ConfigManager is a static class that utilizes the Struts Digester
120  * utility to read an XML file of configuration parameters when
121  * Expresso starts up. These parameters are then available during the
122  * execution of the application.
123  *
124  * @author Adam Rossi
125  */

126 public final class ConfigManager {
127
128     /**
129      * constant path for DTD file; we expect DTD to be placed here, probably by a ANT copy before running servlet engine
130      * searched relative to class dir
131      */

132     public static final String JavaDoc EXPRESSO_DTD_COPY_LOCATION = "/com/jcorporate/expresso/core/expresso-config_4_0.dtd";
133
134     /**
135      * name of servlet param which controls logging directory
136      */

137     public static final String JavaDoc LOG_DIR_PARAM_NAME = "logDir";
138
139     /**
140      * Hashtable of current logins sitting in the system.
141      */

142     private static Hashtable JavaDoc currentLogins = new Hashtable JavaDoc();
143
144     /*
145     * A hashtable for quick lookup of the ConfigContext object for each
146     * context specified in the expresso-config.xml file
147      */

148     private static Hashtable JavaDoc allContexts = new Hashtable JavaDoc();
149
150     /* During startup, the InitServlet passes this information
151
152     * to ConfigManager if it's available
153
154      */

155     private static String JavaDoc configDir = "";
156 // private static String webAppDir = "";
157
// private static String contextPath = "";
158
// private static String serverPrefix = "";
159
private static String JavaDoc servletAPIVersion = "2_2";
160     // STRUTS 1.1
161
// private static Hashtable mappingsCache = null;
162
/**
163      * Map collection to associate module names with action mappings
164      * The default module has a prefix of "".
165      */

166     private static Map mapModuleMapping = new HashMap JavaDoc(); // STRUTS 1.1
167

168     private static ConfigExpresso myConfig = null;
169
170     //Stores DBOtherMap entries
171
private static Hashtable JavaDoc dbOtherMap = new Hashtable JavaDoc();
172     private static Logger log = Logger.getLogger(ConfigManager.class);
173
174     /* Set to true once the XML configuration file has been successfully read */
175     private static boolean xmlConfigOk = false;
176     private static boolean configurationFailed = false;
177
178     /**
179      * List of currently running job handlers
180      */

181     private static Hashtable JavaDoc jobHandlers = new Hashtable JavaDoc();
182
183     /**
184      * If configuration failed on initial startup, we keep the exception
185      * that caused the failure available for reference
186      */

187     private static Throwable JavaDoc configurationFailureException = null;
188     private static HttpServletRequest JavaDoc myRequest = null;
189
190     /**
191      * Singleton implementation function.
192      */

193     private static ConfigManager theInstance = null;
194     private static ControllerFactory controllerFactory = null;
195
196
197     /**
198      * Adds to the 'we have X many logins' hashtable.
199      *
200      * @param newLogin the new login
201      */

202     public static void addSession(CurrentLogin newLogin) {
203         if (currentLogins == null) {
204             currentLogins = new Hashtable JavaDoc();
205         }
206
207         if (newLogin == null) {
208             return;
209         }
210
211         String JavaDoc sessionid = newLogin.getSessionId();
212         if (sessionid == null) {
213             return;
214         }
215
216         if (currentLogins.containsKey(newLogin.getSessionId())) {
217             currentLogins.remove(newLogin.getSessionId());
218         }
219         currentLogins.put(newLogin.getSessionId(), newLogin);
220     }
221
222     public static void setConfigurationFailureException(Throwable JavaDoc ee) {
223         configurationFailureException = ee;
224     }
225
226     public static Throwable JavaDoc getConfigurationFailureException() {
227         return configurationFailureException;
228     }
229
230     /**
231      * Removes a stored session. Used for tracking the number of people
232      * currently logged in.
233      *
234      * @param sessionId the session id that we are receiving the signal for
235      */

236     public static void removeSession(String JavaDoc sessionId) {
237         if (sessionId == null) {
238             return;
239         }
240
241         if (currentLogins == null) {
242             currentLogins = new Hashtable JavaDoc();
243         }
244
245         if (currentLogins.containsKey(sessionId)) {
246             currentLogins.remove(sessionId);
247         }
248
249         //
250
//If we drop to zero logins, now is the perfect time to run the
251
//garbage collector and all pending finalizers.
252
//
253
if (currentLogins.size() == 0) {
254             System.gc();
255             System.runFinalization();
256         }
257     }
258
259     /**
260      * Returns a hashtable of the current login objects
261      *
262      * @return a Hashtable containing everybody logged in.
263      */

264     public static Hashtable JavaDoc getCurrentLogins() {
265         return (Hashtable JavaDoc) currentLogins.clone();
266     }
267
268     /**
269      * Returns a specific job handler.
270      *
271      * @param contextName The dbcontext to get the jobhandler from. ex: <code>
272      * default</code>
273      * @return the JobHandler for that specific context
274      */

275     public static JobHandler getJobHandler(String JavaDoc contextName) {
276         return (JobHandler) jobHandlers.get(contextName);
277     }
278
279     /**
280      * Gets all job handlers in the system
281      *
282      * @return a hashtable of all Job Handlers
283      */

284     public static Hashtable JavaDoc getAllJobHandlers() {
285         return jobHandlers;
286     }
287
288     /**
289      * Default Constructer
290      */

291     public ConfigManager() {
292
293         //Initialize the nextNumber stuff
294
super();
295     } /* ConfigManager() */
296
297     /**
298      * Queries the current servletAPI defined in the configuration system
299      *
300      * @return A string listing the current servletAPIVersion being used
301      */

302     public static String JavaDoc getServletAPIVersion() {
303         return servletAPIVersion;
304     } /* getServletAPIVersion() */
305
306     /**
307      * Remove our database pool(s)
308      * <p/>
309      * Closes all connections so that Hypersonic can handle multiple test
310      * suites from multiple VM's thrown at it as long as each test suite
311      * calls dbUninitialize in the teardown method.
312      */

313     public static synchronized void dbUninitialize()
314             throws DBException {
315         if (log.isInfoEnabled()) {
316             log.info("Tearing down connection pools");
317         }
318
319
320         DBConnectionPool.reInitialize();
321     }
322
323     /**
324      * Call this to destroy all items that ConfigManager uses.
325      * Initially not everythiny is implemented. Must be tested If there
326      * is an error the system prints a stack trace to System.err instead of the
327      * log since logging may have shut down by now.
328      */

329     public static synchronized void destroy() {
330         if (theInstance == null) {
331             return;
332         }
333
334         ConfigManager cm = ConfigManager.getInstance();
335
336         try {
337             cm.stopJobHandler();
338             ConfigManager.dbUninitialize();
339
340
341             com.jcorporate.expresso.core.dbobj.NextNumber.destroy();
342             CacheManager.destroy();
343             com.jcorporate.expresso.core.security.CryptoManager.getInstance().destroy();
344             com.jcorporate.expresso.core.security.DelayThread.kill();
345             LogManager.destroy();
346             /**
347              * Hack... if we're running hypersonic locally, we have to issue a shutdown
348              * request so the VM can exit.
349              */

350             for (Enumeration JavaDoc e = ConfigManager.getAllConfigKeys(); e.hasMoreElements();) {
351                 String JavaDoc oneKey = (String JavaDoc) e.nextElement();
352                 try {
353                     ConfigJdbc jdbcConfig = ConfigManager.getContext(oneKey).getJdbc();
354                     if (jdbcConfig.getDriver().equals("org.hsqldb.jdbcDriver")) {
355
356                         DBConnectionPool pool = DBConnectionPool.getInstance(oneKey);
357                         pool.executeExclusiveUpdate("SHUTDOWN");
358                     }
359                 } catch (DBException ex) {
360                     System.err.println("Error shutting down hypersonic: " + ex.getMessage());
361                 }
362
363             }
364             theInstance = null;
365         } catch (Exception JavaDoc e) {
366             e.printStackTrace();
367             System.err.println(e.getMessage());
368         }
369
370     }
371
372     /**
373      * Initialize our database pool(s)
374      *
375      * @throws ConfigurationException if there is an error getting the config
376      * values from the config beans.
377      */

378     public static synchronized void dbInitialize()
379             throws ConfigurationException {
380         if (log.isInfoEnabled()) {
381             log.info("Initializing connection pool(s)");
382         }
383
384         String JavaDoc oneConfigKey = null;
385
386         for (Enumeration JavaDoc e = getAllConfigKeys(); e.hasMoreElements();) {
387             oneConfigKey = (String JavaDoc) e.nextElement();
388             if (log.isInfoEnabled()) {
389                 log.info("Initializing pool for context '" + oneConfigKey + "'");
390             }
391
392             ConfigJdbc myConfig = getJdbc(oneConfigKey);
393
394             if (myConfig != null) {
395 // dbDriverType attribut added by Yves Henri AMAIZO to be compatible with
396
// JNDI datasource features. 14/07/2002 23h00
397

398                 /* We do an inner "try" here so that if one connection can't be */
399                 /* established the whole system doesn't fail */
400                 try {
401
402                     /* we do not actually need a pool, but we call this method
403                     * to initialize the pool
404                     */

405                     DBConnectionPool myPool = DBConnectionPool.getInstance(oneConfigKey);
406
407                     if (!StringUtil.notNull(myConfig.getDbTest()).equalsIgnoreCase("")) {
408                         myPool.setTestQuery(myConfig.getDbTest());
409                         if (log.isInfoEnabled()) {
410                             log.info("DB connection testing enabled");
411                         }
412                     } else {
413                         if (log.isInfoEnabled()) {
414                             log.info("DB connection testing disabled");
415                         }
416                     }
417                 } catch (DBException de) {
418                     log.error("Initialize failed for context '" +
419                             oneConfigKey +
420                             "'. This pool will not be available.", de);
421                 }
422             } /* if there is a JDBC configuration for this context */
423
424         } /* for each config key */
425
426
427         if (log.isInfoEnabled()) {
428             log.info("All connection pools initialized");
429         }
430
431         if (log.isInfoEnabled()) {
432             log.info("Initializing all registered DBObjets");
433         }
434
435     } /* dbInitialize() */
436
437     /**
438      * Iterate through all schemas and instantiate a DBObject. Yes, this by
439      * and large may get thrown away later, but constructing blank objects allows
440      * various objects to set up listener relations with other classes.
441      * This is especially important for UserListener information.
442      */

443     static public synchronized void initializeAllDBObjects() {
444         boolean expressoInitialized = false;
445
446
447         for (Iterator JavaDoc i = allContexts.keySet().iterator(); i.hasNext();) {
448             try {
449                 String JavaDoc oneDBName = (String JavaDoc) i.next();
450                 ConfigContext oneContext = ConfigManager.getContext(oneDBName);
451
452                 // set up superuser ID on this thread, which is typically called from
453
// servlet initialization
454
User old = null;
455                 try {
456                     old = RequestRegistry.getUser();
457                 } catch (Exception JavaDoc e) {
458                     // no problem
459
}
460                 try {
461                     //This sets thread local variables with the local registry settings.
462
//We set it as a superuser instance for initialization purposes
463
//only. Once the first requests come through, we initialize it
464
//through the Filter.
465
new MutableRequestRegistry(oneDBName, SuperUser.SUPER_USER);
466                     if (oneContext.hasSetupTables()) {
467
468                         try {
469                             SchemaList sl = new SchemaList(SecuredDBObject.SYSTEM_ACCOUNT);
470                             sl.setDataContext(oneDBName);
471                             sl.count(); /** count in order to see if table is ok **/
472                         } catch (DBException e) {
473                             if (log.isInfoEnabled()) {
474                                 log.info("Schema is not initialized yet- run dbcreate for context: " + oneDBName);
475                             }
476                             continue;
477                         }
478
479
480                         // make sure expresso in initialized before any others
481
if (expressoInitialized == false) {
482                             initializeOneSchema(com.jcorporate.expresso.core.ExpressoSchema.class.getName());
483                             expressoInitialized = true;
484                         }
485
486                         SchemaList sl = new SchemaList(SecuredDBObject.SYSTEM_ACCOUNT);
487                         sl.setDataContext(oneDBName);
488                         ArrayList JavaDoc al = sl.searchAndRetrieveList();
489
490                         for (Iterator JavaDoc schemas = al.iterator(); schemas.hasNext();) {
491                             SchemaList oneSchema = (SchemaList) schemas.next();
492                             try {
493                                 initializeOneSchema(oneSchema.getField(SchemaList.FLD_SCHEMA_CLASS));
494                             } catch (Exception JavaDoc ex) {
495                                 log.error("Error initializing schema: "
496                                         + oneSchema.getField(SchemaList.FLD_SCHEMA_CLASS), ex);
497                             }
498
499                         }
500                     }
501                 } finally {
502                     new MutableRequestRegistry(oneDBName, old);
503                 }
504             } catch (DBException dbe) {
505                 log.warn("Unable to initialize dbobjects... SchemaList may not be initialized yet", dbe);
506             } catch (Exception JavaDoc e) {
507                 log.error("Error in initializeAllDBObjects", e);
508             }
509         }
510     }
511
512     static protected synchronized void initializeOneSchema(String JavaDoc className) {
513         if (className == null) {
514             log.warn("initializeOneSchema: Received null className");
515             return;
516         }
517
518         Schema schema = SchemaFactory.getInstance().getSchema(className);
519         if (schema == null) {
520             log.error("initializeOneSchema: cannot find schema: " + className);
521             return;
522         }
523
524         // associate all objects w/i schema with this schema
525
Enumeration JavaDoc anEnum = schema.getMembers();
526         while (anEnum.hasMoreElements()) {
527             DBObject obj = (DBObject) anEnum.nextElement();
528             try {
529                 obj.setSchema(schema);
530             } catch (Exception JavaDoc e) {
531                 log.warn("cannot set schema for: " + obj.getClass().getName() + " because of: " + e.getMessage());
532             }
533         }
534
535     }
536
537
538     /**
539      * Return an enumeration of all of the valid configuration keys.
540      * There is one key for each property file read.
541      *
542      * @return java.util.Enumeration
543      */

544     public static Enumeration JavaDoc getAllConfigKeys() {
545         return allContexts.keys();
546     } /* getAllConfigKeys() */
547
548
549     /**
550      * Return the reference instance of the config manager Use this in preference
551      * to the singleton APIs. So now you have:
552      * <code>ConfigManager.getInstace().getLogDirectory()</code>
553      * for instance. instead of <code>ConfigManager.getLogDirectory();
554      *
555      * @return an instance of ConfigManager
556      */

557     public static synchronized ConfigManager getInstance() {
558         if (theInstance == null) {
559             theInstance = new ConfigManager();
560         }
561
562         return theInstance;
563     } /* getInstance() */
564
565     /**
566      * Is the ConfigManager initialized yet?
567      *
568      * @return true if the xml configuration parsed correctly
569      */

570     public static boolean isInitialized() {
571         return xmlConfigOk;
572     } /* isInitialized() */
573
574     /**
575      * Return the top-level configuration object, an instance of the ConfigExpresso
576      * class. This class contains all the setup options common to all contexts
577      *
578      * @return a ConfigExpresso bean
579      */

580     public static ConfigExpresso getConfig() {
581         return myConfig;
582     } /* getConfig() */
583
584
585     /**
586      * Returns a hashmap keyed by filename, and data ='s a series of input
587      * streams corresponding to xml files of the desired doctype. All files are
588      * located in the Expresso configuration directory
589      *
590      * @param filterDocType - The doctype that you need for configuration files
591      * @return HashMap of InputSources of xml files of the appropriate types.
592      * @throws ConfigurationException if an error occurs while checking xml file
593      * types
594      */

595     public static HashMap JavaDoc getConfigInputSources(String JavaDoc filterDocType)
596             throws ConfigurationException {
597         final String JavaDoc myName = "ConfigManager.getConfigInputSources(String)";
598         HashMap JavaDoc returnSources = new HashMap JavaDoc();
599         String JavaDoc configDir = ConfigManager.getConfigDir();
600
601         if (configDir == null) {
602             throw new ConfigurationException(myName +
603                     ": There is no config Directory Set");
604         }
605
606         InputSource JavaDoc inputSource = null;
607         XmlDocTypeFilter xmldtf = new XmlDocTypeFilter();
608
609         if ('/' == configDir.charAt(0) == false) {
610             configDir = "/" + configDir;
611         }
612
613         if (log.isDebugEnabled()) {
614             log.debug("Getting Input Sources in directory: " + configDir);
615         }
616
617         File JavaDoc propDir = new File JavaDoc(configDir);
618
619         if (!propDir.isDirectory()) {
620             throw new ConfigurationException(myName + ": " + configDir +
621                     " is not a directory");
622         }
623
624         String JavaDoc[] flist = propDir.list();
625
626         for (int i = 0; i < flist.length; i++) {
627             if (log.isDebugEnabled()) {
628                 log.debug("Checking file: " + flist[i]);
629             }
630             if (flist[i].endsWith(".xml")) {
631                 if (log.isDebugEnabled()) {
632                     log.debug("File ends with xml");
633                 }
634
635                 try {
636                     String JavaDoc propFileName = configDir + "/" + flist[i];
637                     FileInputStream JavaDoc fis = new FileInputStream JavaDoc(propFileName);
638
639                     try {
640                         inputSource = new InputSource JavaDoc(fis);
641                         inputSource.setSystemId(configDir + "/");
642
643                         if (xmldtf.isProperDocType(filterDocType, inputSource) == true) {
644                             if (log.isDebugEnabled()) {
645                                 log.debug(propFileName + " is doctype " +
646                                         filterDocType +
647                                         " adding as inputsource");
648                             }
649                             fis.close();
650                             inputSource = new InputSource JavaDoc(new FileInputStream JavaDoc(propFileName));
651                             inputSource.setSystemId(configDir + "/");
652                             returnSources.put(flist[i], inputSource);
653                         } else {
654                             if (log.isDebugEnabled()) {
655                                 log.debug(propFileName + " is not of doctype " +
656                                         filterDocType);
657                             }
658                         }
659                     } finally {
660                         fis.close();
661                     }
662                 } catch (java.io.FileNotFoundException JavaDoc fnfe) {
663                     throw new ConfigurationException(fnfe);
664                 } catch (java.io.IOException JavaDoc ioe) {
665                     throw new ConfigurationException(ioe);
666                 }
667             }
668         }
669
670         return returnSources;
671     }
672
673     /**
674      * Return the context configuration object for the named context. This object
675      * contains all of the configuration info for a specific context/database
676      *
677      * @param contextName the data context to retrieve the configuration information
678      * for
679      * @return the ConfigContextBean for the data context specified
680      * @throws ConfigurationException if there's an error retrieving the ConfigContext
681      * bean for the specified context
682      */

683     public static ConfigContext getContext(String JavaDoc contextName)
684             throws ConfigurationException {
685         StringUtil.assertNotBlank(contextName,
686                 "You must specify a context name");
687
688         if (allContexts == null) {
689             throw new ConfigurationException("No contexts available");
690         }
691
692         ConfigContext oneContext = (ConfigContext) allContexts.get(contextName);
693
694         if (oneContext == null) {
695             throw new ConfigurationException("No such configuration context as '" + contextName + "'");
696         }
697
698         return oneContext;
699     }
700
701     /**
702      * Return the Class dealing with the named ClassHandler
703      *
704      * @param handlerName the 'service name' of the classhandler to retrieve
705      * @return the name of the class to use for this 'category'
706      */

707     public static String JavaDoc getClassHandler(String JavaDoc handlerName) {
708         ConfigClassHandler cch = (ConfigClassHandler) myConfig.getClassHandlers().get(handlerName);
709
710         if (cch == null) {
711             return null;
712         }
713
714         return cch.getClassHandler();
715     }
716
717     /**
718      * Returns the given parameter for a class handler.
719      *
720      * @param handlerName the 'service name' of the classhandler to retrieve
721      * @param parameter The name of the parameter to get
722      * @return the value of the parameter for this class handler
723      */

724     public static String JavaDoc getClassHandlerParameter(String JavaDoc handlerName,
725                                                   String JavaDoc parameter) {
726         return ((ConfigClassHandler) myConfig.getClassHandlers().get(handlerName)).getParameter(parameter);
727     }
728
729     /**
730      * Get the Jdbc configuration (if any) for the named context
731      *
732      * @param contextName the data context to get the JDBC configuration bean for
733      * @return a ConfigJdbc Configuration Bean
734      * @throws ConfigurationException if there is an error retrieving the context
735      */

736     public static ConfigJdbc getJdbc(String JavaDoc contextName)
737             throws ConfigurationException {
738         ConfigContext oneContext = getContext(contextName);
739
740         if (oneContext != null) {
741             return oneContext.getJdbc();
742         }
743
744         return null;
745     }
746
747     /**
748      * Get a Jdbc configuration object, throwing an exception if there is not one
749      * for the specified context
750      *
751      * @param contextName the data context to get the JDBC configuration bean for
752      * @return a ConfigJdbc Configuration Bean
753      * @throws ConfigurationException if there is an error retrieving the context
754      */

755     public static ConfigJdbc getJdbcRequired(String JavaDoc contextName)
756             throws ConfigurationException {
757         ConfigJdbc myJdbc = getJdbc(contextName);
758
759         if (myJdbc == null) {
760             throw new ConfigurationException("Context '" + contextName +
761                     "' is not configured for JDBC access");
762         }
763
764         return myJdbc;
765     }
766
767     /**
768      * Get the actual filesystem directory that is the root of this web-app
769      *
770      * @return The filesystem directory that is the root of this webapp.
771      */

772     public static String JavaDoc getWebAppDir() {
773         String JavaDoc webAppDir = SystemMacros.getInstance().getWebAppDir();
774
775         if (webAppDir == null) {
776             try {
777                 throw new Exception JavaDoc("Getting requests for web application directory, but system is deployed in a " +
778                         "compressed war file. There is no such thing");
779             } catch (Exception JavaDoc ex) {
780                 log.warn("getWebAppDir path error", ex);
781             }
782         }
783         return webAppDir;
784     } /* getWebAppDir() */
785
786     /**
787      * Checks to see if any given field or tablename fed to this qualifies
788      * as a known reserved word for various databases.
789      *
790      * @param testWord The word to check against the list of known reserved
791      * words.
792      * @return true if the test word is a reserved word.
793      * @todo Convert this to isReservedWord() and get all dbobjects converted
794      * over.
795      */

796     public static boolean isReservedWord(String JavaDoc testWord) {
797
798         // return ReservedWords.getInstance().isReservedWord(testWord);
799
return ReservedWords.getInstance().isExpressoReservedWord(testWord);
800     }
801
802     /**
803      * Checks to see if a controller parameter may be a reserved word. This
804      * helps prevent any weird behavior when posting objects.
805      *
806      * @param testWord The word to check against the list of known reserved
807      * words.
808      * @return true if the test word is a reserved word.
809      */

810     public static boolean isParameterReservedWord(String JavaDoc testWord) {
811         return ReservedWords.getInstance().isExpressoReservedWord(testWord);
812     }
813
814     /**
815      * Start job handlers
816      * The job handler for each DB context is started if the appropriate
817      * configuration entry is found for that context
818      *
819      * @throws ConfigurationException if there's a config error reading job values or
820      * getting job values for a particular context.
821      */

822     public static synchronized void startJobHandler()
823             throws ConfigurationException {
824         if (log.isInfoEnabled()) {
825             log.info("Starting job handler(s)");
826         }
827
828         String JavaDoc oneConfigKey = null;
829
830         // Iterate through each DB config
831
for (Enumeration JavaDoc e = getAllConfigKeys(); e.hasMoreElements();) {
832             oneConfigKey = (String JavaDoc) e.nextElement();
833
834             // Retrieve the property setting for the DB config
835
if (!getContext(oneConfigKey).startJobHandler()) {
836                 log.warn("Job handler for configuration '" + oneConfigKey +
837                         "' not enabled (because of the setting in expresso-config.xml).");
838             } else {
839                 if (log.isInfoEnabled()) {
840                     log.info("Job handler for configuration '" + oneConfigKey +
841                             "' starting...");
842                 }
843
844                 /* We do an inner "try" here so that if one job handler */
845                 /* can't start the whole system doesn't fail */
846                 try {
847                     JobHandler ts = new JobHandler(oneConfigKey);
848                     ts.setDaemon(true);
849
850                     // Start a thread for the JobHandler Job
851
ts.start();
852                     jobHandlers.put(oneConfigKey, ts);
853                     if (log.isInfoEnabled()) {
854                         log.info("Job handler for '" + oneConfigKey +
855                                 "' running.");
856                     }
857                 } catch (DBException de) {
858                     log.error("Job handler start failed for config key '" +
859                             oneConfigKey + "'. Jobs for this config will " +
860                             "will not be run.", de);
861                 } catch (ServerException se) {
862                     log.error("Job handler start failed for config key ' " +
863                             oneConfigKey +
864                             "'. Jobs for this config will will " +
865                             "not be run.", se);
866                 }
867             }
868         } /* for each config key */
869
870
871         if (log.isInfoEnabled()) {
872             log.info("All job handlers started");
873         }
874     } /* startJobHandler() */
875
876
877     /**
878      * Stops all job handlers
879      *
880      * @throws ConfigurationException if there's an error getting the config
881      * information beans.
882      */

883     protected void stopJobHandler()
884             throws ConfigurationException {
885         if (log.isInfoEnabled()) {
886             log.info("Stops job handler(s)");
887         }
888
889         String JavaDoc oneConfigKey = null;
890
891         // Iterate through each DB config
892
for (Enumeration JavaDoc e = getAllConfigKeys(); e.hasMoreElements();) {
893             oneConfigKey = (String JavaDoc) e.nextElement();
894
895             // Retrieve the property setting for the DB config
896
if (getContext(oneConfigKey).startJobHandler()) {
897                 if (log.isInfoEnabled()) {
898                     log.info("Job handler for configuration '" + oneConfigKey +
899                             "' interrupting...");
900                 }
901
902                 /* We do an inner "try" here so that if one job handler */
903
904                 /* can't start the whole system doesn't fail */
905                 JobHandler ts = (JobHandler) jobHandlers.get(oneConfigKey);
906
907                 if (ts != null) {
908                     ts.shutDown();
909                 }
910
911                 // Start a thread for the JobHandler Job
912
}
913         } /* for each config key */
914
915
916         if (log.isInfoEnabled()) {
917             log.info("All job handlers interrupted");
918         }
919     }
920
921     /**
922      * Set the "Web application directory" - this is used for translating
923      * the %web-app% 'macro' that can be used in property and setup
924      * values
925      *
926      * @param newDir the new directory for the webAppDirectory 'environment
927      * variable'
928      */

929     public static void setWebAppDir(String JavaDoc newDir) {
930         SystemMacros.getInstance().setWebAppDir(newDir);
931     } /* setWebAppDir(String) */
932
933     /**
934      * Set the "context path" - this is used for translating
935      * the %context% 'macro' that can be used in property and setup
936      * values
937      *
938      * @param newContextPath the new contextPath value to use
939      */

940     public static void setContextPath(String JavaDoc newContextPath) {
941         SystemMacros.getInstance().setContextPath(newContextPath);
942     } /* setContextPath(String) */
943
944     /**
945      * set the controller factory to use.
946      *
947      * @param cf the new Controller Factory to use for the running system.
948      * @see com.jcorporate.expresso.core.controller.ExpressoActionServlet for
949      * an example use of this.
950      */

951     public synchronized static void setControllerFactory(ControllerFactory cf) {
952         controllerFactory = cf;
953     }
954
955     /**
956      * Get the web-app context path for this web application
957      *
958      * @return the context path string.
959      */

960     public static String JavaDoc getContextPath() {
961         if (!isInitialized()) {
962             throw new IllegalArgumentException JavaDoc("ConfigManager not initialized");
963         }
964
965         return SystemMacros.getInstance().getContextPath();
966     } /* getContextPath() */
967
968     /**
969      * Called by the initial load servlet to initialize the entire system
970      *
971      * @param c The servlet engine configuration
972      * @throws ServletException Servlet exception if an error occurs initializing
973      * the configuration system.
974      */

975     public static synchronized void config(ServletConfig JavaDoc c)
976             throws ServletException JavaDoc {
977
978         /* If we've already failed to configure, don't try again */
979         if (configurationFailed) {
980             throw new ServletException JavaDoc(
981                     "ConfigManager: Configuration has already been attempted and has failed - cannot re-run");
982         }
983
984
985         if (c == null) {
986             ServletException JavaDoc se = new ServletException JavaDoc("ConfigManager: ServletConfig may not be null");
987             setConfigurationFailureException(se);
988             throw se;
989         }
990         /* We initialize the default schema object here specifically in order */
991         /* for it to do it's "version checking" against dependant packages */
992
993         try {
994             ServletContext JavaDoc sc = c.getServletContext();
995             servletAPIVersion = Integer.toString(sc.getMajorVersion()) +
996                     "_" +
997                     Integer.toString(sc.getMinorVersion());
998 // setupLog.info("ConfigManager: System running servlet API " +
999
// servletAPIVersion);
1000
configDir = StringUtil.notNull(c.getInitParameter("configDir"));
1001
1002            if (configDir.equals("")) {
1003                configDir = StringUtil.notNull(sc.getInitParameter("configDir"));
1004            }
1005            if (configDir.equals("")) {
1006                ServletException JavaDoc se = new ServletException JavaDoc("ConfigManager: No 'configDir' initial " +
1007                        "parameter was read - unable to initialize. " +
1008                        "Check web.xml to ensure the configDir parameter is set " +
1009                        "to a non-blank value");
1010                setConfigurationFailureException(se);
1011                throw se;
1012            }
1013
1014            String JavaDoc rootDir = StringUtil.notNull(sc.getRealPath("/"));
1015
1016// if (setupLog.isInfoEnabled()) {
1017
// setupLog.info("ConfigManager: Context root (webAppDir) is '" +
1018
// rootDir + "'");
1019
// }
1020

1021            if (rootDir.equals("")) {
1022// setupLog.info("Deploying inside a packed war file. Relative File URLs will throw Exceptions");
1023
rootDir = System.getProperty("expresso.home", "");
1024                if (rootDir.length() == 0) {
1025                    log.warn("Deployed inside WAR file and no expresso.home " +
1026                            "directory set. %WEB-APP% will expand to null");
1027                } else {
1028                    configDir = FileUtil.makeAbsolutePath(rootDir, configDir);
1029
1030                    if (!('/' == configDir.charAt(0))) {
1031                        configDir = "/" + configDir;
1032                    }
1033
1034// setupLog.info("ConfigManager: Config dir is now '" +
1035
// configDir + "'");
1036
setWebAppDir(rootDir);
1037                }
1038            } else {
1039                configDir = FileUtil.makeAbsolutePath(rootDir, configDir);
1040
1041                if (!('/' == configDir.charAt(0))) {
1042                    configDir = "/" + configDir;
1043                }
1044
1045// setupLog.info("ConfigManager: Config dir is now '" +
1046
// configDir + "'");
1047

1048                // protect against installation in "Program Files" directory
1049
if (configDir.indexOf(' ') != -1) {
1050// setupLog.warn("Bad name for installation path: Reinstall in directory without a space in name.");
1051
System.err.println(
1052                            "Bad name for installation path: Reinstall in directory without a space in name.");
1053                }
1054                setWebAppDir(rootDir);
1055            }
1056
1057            initLogManager(c);
1058
1059            load(configDir);
1060        } catch (Throwable JavaDoc thrown) {
1061            if (log != null) {
1062                log.error(thrown);
1063            }
1064            setConfigurationFailureException(thrown);
1065            System.err.println("ConfigManager: Expresso configuration encountered an exception:");
1066            thrown.printStackTrace(System.err);
1067            configurationFailed = true;
1068            throw new ServletException JavaDoc(thrown);
1069        }
1070    }
1071
1072    /**
1073     * Initialize Log Manager based upon the LogDirectory.
1074     *
1075     * @param sc the servlet configuration.
1076     */

1077    private static void initLogManager(ServletConfig JavaDoc sc) {
1078        String JavaDoc configDir = sc.getServletContext().getInitParameter("configDir");
1079        String JavaDoc logDir = sc.getServletContext().getInitParameter(LOG_DIR_PARAM_NAME);
1080        String JavaDoc logConfig = null;
1081
1082        if (!('/' == configDir.charAt(0))) {
1083            configDir = getWebAppDir() + configDir;
1084        }
1085
1086        if (logDir != null && logDir.length() > 0 && !('/' == logDir.charAt(0))) {
1087            logDir = getWebAppDir() + logDir;
1088        }
1089        //
1090
//expressoLogging can be initialized with or without a log directory
1091
//or a config dir directory. If log4j.xml exists in the classpath, the
1092
//system will initialize with that.
1093
//
1094
if (configDir != null && configDir.length() > 0) {
1095            logConfig = configDir + "/expressoLogging.xml";
1096            java.io.File JavaDoc f = new java.io.File JavaDoc(logConfig);
1097            if (f == null || !f.exists()) {
1098                logConfig = null;
1099            }
1100        }
1101
1102        new LogManager(logConfig, logDir);
1103    }
1104
1105    /**
1106     * "Second stage" configuration. Programs not running in the servlet
1107     * environment can call this method with a configuration directory
1108     * directly in order to set up Expresso. In a servlet environment, load
1109     * gets called from "config" above.
1110     *
1111     * @param theConfigDir The directory to load all config files from.
1112     */

1113    public static synchronized void load(String JavaDoc theConfigDir)
1114            throws DBException, ConfigurationException {
1115
1116
1117        StringUtil.assertNotBlank(theConfigDir,
1118                "No configuration directory specified");
1119        Logger.getLogger(ConfigManager.class); // todo remove this?
1120
ConfigManager.configDir = theConfigDir;
1121
1122        ConfigManager instance = ConfigManager.getInstance();
1123        instance.readXMLConfig(configDir);
1124
1125        // note: logging manager & directory handled elsewhere (servlet params) now
1126

1127        //initialize the db pool
1128
if (log.isInfoEnabled()) {
1129            log.info("Initializing connection pool(s)");
1130        }
1131        ConfigManager.dbInitialize();
1132
1133        //Read the DBOtherMap entries into memory
1134
ConfigManager.mapOtherDBs();
1135
1136        /* read - or re-read - the setup values */
1137        if (log.isInfoEnabled()) {
1138            log.info("Reading setup values");
1139        }
1140        Setup.readSetups();
1141
1142        if (log.isInfoEnabled()) {
1143            log.info("Initializing Schema Objects");
1144        }
1145
1146        initializeAllDBObjects();
1147
1148        com.jcorporate.expresso.core.dbobj.NextNumber.getInstance();
1149        CacheManager.getInstance();
1150
1151        //Job Handler starting is the very last thing we want to do since dead
1152
//jobs CAN come to life while we're still trying to get everything up
1153
//and running.
1154
//
1155
// Start JobHandler thread(s)
1156
if (log.isInfoEnabled()) {
1157            log.info("Starting job handler(s)");
1158        }
1159        ConfigManager.startJobHandler();
1160        if (log.isInfoEnabled()) {
1161            log.info("Expresso initialization complete");
1162        }
1163    } /* load */
1164
1165
1166    /**
1167     * Method to "expand" some simple "macro" codes allowed in
1168     * property file and Setup values.
1169     *
1170     * @param propValue The 'property value' to expand.
1171     * @return The 'expanded' value of the property value
1172     */

1173    public static String JavaDoc expandValue(String JavaDoc propValue) {
1174        return SystemMacros.getInstance().expandValue(propValue);
1175    } /* expandValue(String) */
1176
1177    /**
1178     * Return the pathname of the configuration directory (specified
1179     * as "configDir"
1180     *
1181     * @return The configuration directory that is used by expresso
1182     */

1183    public static String JavaDoc getConfigDir() {
1184        return configDir;
1185    } /* getConfigDir() */
1186
1187    /**
1188     * Returns the controller factory object. Instantiates the default
1189     * controller factory if one doesn't exist.
1190     *
1191     * @return a ControllerFactory object to use for instantiating controllers
1192     */

1193    public static synchronized ControllerFactory getControllerFactory() {
1194        if (controllerFactory == null) {
1195            controllerFactory = new com.jcorporate.expresso.core.controller.DefaultControllerFactory();
1196        }
1197
1198        return controllerFactory;
1199    }
1200
1201    /**
1202     * Get the cached "other db" location for a specific object
1203     * Creation date: (1/5/01 6:57:06 PM)
1204     * author: Adam Rossi, PlatinumSolutions
1205     *
1206     * @param dbName java.lang.String
1207     * @param objectName the name to located
1208     * @return A String giving the data context for the other location
1209     */

1210    public static String JavaDoc getOtherDbLocation(String JavaDoc dbName, String JavaDoc objectName) {
1211        FastStringBuffer fsb = FastStringBuffer.getInstance();
1212        try {
1213            fsb.append(dbName);
1214            fsb.append("|");
1215            fsb.append(objectName);
1216            return (String JavaDoc) dbOtherMap.get(fsb.toString());
1217        } finally {
1218            fsb.release();
1219        }
1220    } /* getOtherDbLocation(String) */
1221
1222    /**
1223     * Return a cloned Hashtable containing all of the DBOtherMap entries
1224     * author Adam Rossi, PlatinumSolutions
1225     *
1226     * @return java.util.Hashtable
1227     */

1228    public static Hashtable JavaDoc getOtherDBLocations() {
1229        return (Hashtable JavaDoc) dbOtherMap.clone();
1230    }
1231
1232    /**
1233     * Map otherdb locations into a hashtable stored in memory.
1234     * <p/>
1235     * Creation date: (1/5/01 6:48:11 PM)
1236     * author: Adam Rossi, PlatinumSolutions
1237     *
1238     * @throws ConfigurationException if there is an error mapping these other
1239     * databases.
1240     */

1241    public static synchronized void mapOtherDBs()
1242            throws ConfigurationException {
1243        String JavaDoc oneKey = "";
1244        dbOtherMap.clear(); //Clear it since we may need to read.
1245

1246        for (Enumeration JavaDoc ek = getAllConfigKeys(); ek.hasMoreElements();) {
1247            oneKey = (String JavaDoc) ek.nextElement();
1248
1249            ConfigContext oneContext = getContext(oneKey);
1250
1251            if (oneContext.hasSetupTables() && oneContext.isActive()) {
1252                if (log.isInfoEnabled()) {
1253                    log.info("Reading DBObject mappings to other databases, context '" +
1254                            oneKey + "'...");
1255                }
1256                //This sets thread local variables with the local registry settings.
1257
//We set it as a superuser instance for initialization purposes
1258
//only. Once the first requests come through, we initialize it
1259
//through the Filter.
1260
new MutableRequestRegistry(oneKey, SuperUser.SUPER_USER);
1261
1262                try {
1263                    SchemaList sl = new SchemaList(SecuredDBObject.SYSTEM_ACCOUNT);
1264                    sl.setDataContext(oneKey);
1265                    sl.count();
1266                } catch (DBException e) {
1267                    if (log.isInfoEnabled()) {
1268                        log.info("Context: " + oneKey + " does not have a SchemaList yet. Skipping for now");
1269                        continue;
1270                    }
1271                }
1272
1273                int i = 0;
1274
1275                try {
1276                    DBOtherMap otherDB = new DBOtherMap();
1277                    otherDB.setDataContext(oneKey);
1278
1279                    DBOtherMap oneOtherDB = null;
1280                    FastStringBuffer fsb = FastStringBuffer.getInstance();
1281                    try {
1282                        for (Iterator JavaDoc allOtherDB = otherDB.searchAndRetrieveList().iterator();
1283                             allOtherDB.hasNext();) {
1284                            oneOtherDB = (DBOtherMap) allOtherDB.next();
1285                            fsb.append(oneKey);
1286                            fsb.append("|");
1287                            fsb.append(oneOtherDB.getField("DBObjName"));
1288                            dbOtherMap.put(fsb.toString(),
1289                                    oneOtherDB.getField("DBConnName"));
1290                            fsb.clear();
1291                            i++;
1292                        } /* for each mapping entry found in this context */
1293                    } finally {
1294                        fsb.release();
1295                    }
1296
1297                    if (log.isInfoEnabled()) {
1298                        log.info("Added " + i +
1299                                " entries to the DBObject Other Database Map.");
1300                    }
1301                } catch (DBException de) {
1302                    if (oneKey.equalsIgnoreCase(TestSystemInitializer.getTestContext())) {
1303                        log.warn("Didn't read test database mapping context: " +
1304                                de.getMessage());
1305                    } else {
1306                        log.error("Unable to read database mapping entries for context '" +
1307                                oneKey + "'", de);
1308                    }
1309                }
1310            } else { /* if this context has the standard tables */
1311                if (log.isInfoEnabled()) {
1312                    log.info(
1313                            "DB/Context '" + oneKey +
1314                            "' is not an Expresso database, or is not active - not reading mapping entries from this context");
1315                }
1316            }
1317        } /* for each context */
1318
1319    } /* mapOtherDBs() */
1320
1321
1322    /**
1323     * Re-read all properties and other values, re-initialize everything
1324     *
1325     * @param req The servlet request to use
1326     * @param c The servlet config handed to us in the init() method.
1327     */

1328    public static void reInitialize(HttpServletRequest JavaDoc req, ServletConfig JavaDoc c)
1329            throws ServletException JavaDoc {
1330        try {
1331            DBConnectionPool.reInitialize();
1332            checkInitialized(req, c);
1333        } catch (DBException de) {
1334            System.err.println("ConfigManager: Error re-initializing:");
1335            de.printStackTrace(System.err);
1336        }
1337
1338    } /* reInitialize(HttpServletRequest, ServletConfig) */
1339
1340    /**
1341     * Check if the configuration info needs to be read, and read
1342     * it if so.<br>
1343     * Immediately returns if the config manager has already been
1344     * initialized successfully.<br>
1345     * Any servlet can check this to make sure Expresso has been
1346     * started up successfully - if not, it calls load as needed
1347     * to perform/re-perform the startup.
1348     *
1349     * @param req The servlet request given by the servlet container
1350     * @param c The servlet configuration
1351     */

1352    public static void checkInitialized(HttpServletRequest JavaDoc req,
1353                                        ServletConfig JavaDoc c)
1354            throws ServletException JavaDoc {
1355
1356        // If properties have been defined, Expresso must have been initialized once
1357
// Otherwise, call the config method of ConfigManager to do the actuall init.
1358
// of Expresso.
1359
if (!isInitialized()) {
1360            System.err.println("ConfigManager: Expresso was not initialized - initializing now");
1361            config(c);
1362        }
1363
1364        setRequest(req);
1365    } /* checkInitialized(HttpServletRequest, ServletConfig) */
1366
1367
1368    /**
1369     * This function is used by webservers to set global variables such as
1370     * server prefix, or context path. This is usually set by checkLogin(),
1371     * or any other first pages that are reached.
1372     *
1373     * @param req a HttpServletRequest
1374     */

1375    public static synchronized void setRequest(HttpServletRequest JavaDoc req) {
1376        if (myRequest == null) {
1377            myRequest = req;
1378            SystemMacros sm = SystemMacros.getInstance();
1379            sm.setContextPath(GenericDispatcher.getContextPath(req));
1380            sm.setServerPrefix(req.getServerName() + ":" + req.getServerPort());
1381        }
1382    }
1383
1384    //////////////////////////////////////////////////////////////////////
1385
// START OF STRUTS 1.1 INTEGRATION
1386
//////////////////////////////////////////////////////////////////////
1387

1388    /**
1389     * Store the action mappings per module to allow fast reverse based
1390     * lookup based on the controller name.
1391     * <p/>
1392     * <p/>
1393     * It is possible that the same controller is used across
1394     * action mappings and also across module (sub applications). So
1395     * this data structure takes account of the multiple mappings to
1396     * module names and save a list of possible action mappings
1397     * related to a controller class name.
1398     * </p>
1399     * <p/>
1400     * <p/>
1401     * <b>PLEASE NOTE</b> from Struts 1.1 the old
1402     * <code>org.apache.struts.action.ActionMapping</code> is deprecated
1403     * and has been replaced with <code>org.apache.struts.config.ActionConfig</code>
1404     * which is part of <code>org.apache.struts.config.ModuleConfig</code>
1405     * <p/>
1406     * </p>
1407     */

1408    public static void storeModuleActionConfig(ModuleConfig moduleConfig) {
1409        String JavaDoc prefixName = moduleConfig.getPrefix();
1410        ActionConfig actionConfig[] = moduleConfig.findActionConfigs();
1411        if (log.isDebugEnabled()) {
1412            log.debug("ConfigManager.saveModuleActionConfig() prefix=`" + prefixName + "'");
1413        }
1414
1415        synchronized (mapModuleMapping) {
1416            Map mapMappings = new HashMap JavaDoc();
1417            for (int j = 0; j < actionConfig.length; ++j) {
1418                String JavaDoc controllerName = actionConfig[j].getType();
1419                List list = (List) mapMappings.get(controllerName);
1420                if (list == null) {
1421                    list = new ArrayList JavaDoc();
1422                }
1423                list.add(actionConfig[j]);
1424                mapMappings.put(controllerName, list);
1425                if (log.isDebugEnabled()) {
1426                    log.debug(" " + controllerName + " => { `" + actionConfig[j].getPath() + "' " +
1427                            "name:`" + actionConfig[j].getName() + "' " +
1428                            "scope:`" + actionConfig[j].getScope() + "' " +
1429                            "input:`" + actionConfig[j].getInput() + "' " +
1430                            "attribute:`" + actionConfig[j].getAttribute() + "' " +
1431                            "parameter:`" + actionConfig[j].getParameter() + "' " +
1432                            "validate:`" + actionConfig[j].getValidate() + "' " +
1433                            "}");
1434                }
1435            }
1436
1437            mapModuleMapping.put(prefixName, mapMappings);
1438        }
1439    }
1440
1441    /**
1442     * Gets the action mapping associated with the controller and default root module.
1443     * Perform a 'reverse-mapping', that is, locate a Struts action mapping
1444     * by looking for the given controller name (and optional state name)
1445     *
1446     * @param controllerName the classname of the controller to look up.
1447     * @param stateName the name of the state to lookup within that controller
1448     * @return the ActionConfig associated with the parameters specified
1449     * @see #getActionConfig( String,String,String )
1450     */

1451    public static ActionConfig getActionConfig(String JavaDoc controllerName, String JavaDoc stateName) {
1452        return getActionConfig("", controllerName, stateName);
1453    }
1454
1455    /**
1456     * Gets the action mapping associated with the controller and the module name.
1457     * Perform a 'reverse-mapping', that is, locate a Struts action mapping
1458     * by looking for the given controller name (and optional state name).
1459     * If the stateName is <code>null</code> this method will attempt to
1460     * dynamically load the controller class, instantiate an object instance
1461     * and retrieve the controller class's initial state.
1462     * <p/>
1463     * <p/>
1464     * <p/>
1465     * The action mapping is determined by looking at
1466     * <code>ActionConfig</code> records in Struts configuration,
1467     * retrieving all the <em>local</em> action forward and comparing
1468     * its name to the state forward. This means that in your Struts
1469     * XML configuration you must define a local action forward with
1470     * the same name as the state Method.
1471     * <p/>
1472     * </p>
1473     * <p/>
1474     * <p/>
1475     * <p/>
1476     * If no action mapping can be determined by�looking for a
1477     * particular matching local action forward, then the first action
1478     * mapping is returned if exists. Please note the first action
1479     * mapping is not necessarily the first action mapping declared in
1480     * the XML configuration. This cannot be guaranteed, because the
1481     * implementation may changed in the future.
1482     * <p/>
1483     * </p>
1484     * <p/>
1485     * <pre>
1486     * &lt;action path="/Register"
1487     * type="com.jcorporate.expresso.services.controller.SimpleRegistration"
1488     * name="default" scope="request" validate="false" &gt;
1489     * &lt;forward name="showDBMenu"
1490     * path="/expresso/jsp/register/dbmenu.jsp" /&gt;
1491     * &lt;forward name="promptAddRecord"
1492     * path="/expresso/jsp/register/regAdd.jsp" /&gt;
1493     * &lt;forward name="promptUpdateRecord"
1494     * path="/expresso/jsp/register/regAdd.jsp" /&gt;
1495     * ...
1496     * &lt;/action&gt;
1497     * <pre>
1498     * <p/>
1499     * <p/>
1500     * In order for the above action mapping "/Register" to be returned then
1501     * you need to declare a <em>unique</em> local action forward name, if you
1502     * use the same controller class for multiple actions. For example "showDBMenu"
1503     * could be the unique local forward.
1504     * </p>
1505     *
1506     * @param moduleName the Struts module name
1507     * @param controllerName the classname of the controller to look up.
1508     * @param stateName the name of the state to lookup within that controller
1509     * @return the ActionConfig associated with the parameters specified
1510     * @see #storeModuleActionConfig( ModuleConfig moduleConfig)
1511     */

1512    public static ActionConfig getActionConfig(String JavaDoc moduleName, String JavaDoc controllerName, String JavaDoc stateName) {
1513        if (log.isDebugEnabled()) {
1514            log.debug("CF.getActionConfig() moduleName=`" + moduleName +
1515                    "', controllerName=`" + controllerName + "', stateName=`" + stateName + "'");
1516        }
1517
1518        if (moduleName == null) {
1519            throw new IllegalArgumentException JavaDoc("ConfigManager.getActionMapping(): " +
1520                    "parameter moduleName cannot be null");
1521        }
1522        if (controllerName == null) {
1523            throw new IllegalArgumentException JavaDoc("ConfigManager.getActionMapping(): " +
1524                    "parameter controllerName cannot be null");
1525        }
1526
1527        if (stateName == null || stateName.length() == 0) {
1528            try {
1529                com.jcorporate.expresso.core.controller.Controller c =
1530                        ConfigManager.getControllerFactory().getController(moduleName, controllerName);
1531
1532                stateName = c.getInitialState();
1533                if (stateName == null || stateName.length() == 0) {
1534                    throw new IllegalArgumentException JavaDoc("ConfigManager.getMapping(): " +
1535                            "stateName was null and there is no defined initial state for: "
1536                            + controllerName);
1537                }
1538                if (log.isDebugEnabled()) {
1539                    log.debug("using initial state =`" + stateName + "'");
1540                }
1541            } catch (ControllerException ex) {
1542                throw new RuntimeException JavaDoc("ConfigManager.getMapping(): "
1543                        + "stateName was null and can't construct controller of name: "
1544                        + controllerName, ex);
1545            } catch (ClassCastException JavaDoc ex) {
1546                log.error("Error getting controller", ex);
1547                throw new IllegalArgumentException JavaDoc("ClassCastException getting"
1548                        + " controller: " + ex.toString());
1549            }
1550        }
1551
1552        synchronized (mapModuleMapping) {
1553            Map mapMappings = (Map) mapModuleMapping.get(moduleName);
1554            if (mapMappings != null) {
1555                List list = (List) mapMappings.get(controllerName);
1556                if (list != null) {
1557                    for (int j = 0; j < list.size(); ++j) {
1558                        ActionConfig oneConfig = (ActionConfig) list.get(j);
1559                        if (StringUtil.notNull(oneConfig.getParameter()).equals(stateName)) {
1560                            if (log.isDebugEnabled()) {
1561                                log.debug("CM.getActionConfig() *FOUND* parameter=`" + oneConfig.getParameter() + "' actionConfig:"
1562                                        + oneConfig.getName() + "," + oneConfig.getPath());
1563                            }
1564                            return oneConfig;
1565                        }
1566
1567                        ForwardConfig aForward = findForwardConfig(oneConfig, stateName);
1568                        if (aForward != null) {
1569                            if (log.isDebugEnabled()) {
1570                                log.debug("CM.getActionConfig() *FOUND* forwards=`"
1571                                        + aForward.getName() + "',`" + aForward.getPath() +
1572                                        "' actionConfig:" + oneConfig.getName() + "," + oneConfig.getPath());
1573                            }
1574                            return oneConfig;
1575                        }
1576                    }
1577
1578
1579                    // If we still have not found an action mapping
1580
// then we return the first one on the list and
1581
// assume this will be correct most of the time.
1582
if (list.size() > 0) {
1583                        ActionConfig oneConfig = (ActionConfig) list.get(0);
1584                        if (log.isDebugEnabled()) {
1585                            log.debug("CM.getActionConfig() *FOUND* using the FIRST actionConfig:"
1586                                    + oneConfig.getName() + "," + oneConfig.getPath());
1587                        }
1588                        return oneConfig;
1589                    }
1590                }
1591            }
1592        }
1593
1594        return (null);
1595    }
1596
1597    /**
1598     * Find a forward config given an action config and a state name Does not
1599     * return higher level forwards, just the one for the given state IF it exists
1600     *
1601     * @param oneConfig the ActionConfig for the controller
1602     * @param stateName the state name for the controller
1603     * @return ForwardConfig instance for that parameter combination
1604     */

1605    public static final ForwardConfig findForwardConfig(ActionConfig oneConfig,
1606                                                        String JavaDoc stateName) {
1607
1608        ForwardConfig forwards[] = oneConfig.findForwardConfigs();
1609        for (int k = 0; k < forwards.length; ++k) {
1610            if (forwards[k].getName().equals(stateName)) {
1611                return forwards[k];
1612            }
1613        }
1614
1615        return null;
1616    }
1617
1618    /**
1619     * Gets <em>all</em> the action mappings associated with the
1620     * controller and the default module. Perform a
1621     * 'reverse-mapping', that is, locate a Struts action mappings by
1622     * looking for the given controller name.
1623     *
1624     * @param controllerName the classname of the controller to look up.
1625     * @return the ActionConfig associated with the parameters specified
1626     * @see #getActionConfigList( String,String )
1627     */

1628    public static List getActionConfigList(String JavaDoc controllerName) {
1629        return getActionConfigList("", controllerName);
1630    }
1631
1632    /**
1633     * Gets <em>all</em> the action mappings associated with the controller
1634     * and the module name.
1635     * Perform a 'reverse-mapping', that is, locate a Struts action mapping
1636     * by looking for the given controller name.
1637     *
1638     * @param moduleName the Struts module name
1639     * @param controllerName the classname of the controller to look up.
1640     * @return the ActionConfig list associated with the parameters specified
1641     * @see #storeModuleActionConfig( ModuleConfig moduleConfig)
1642     */

1643    public static List getActionConfigList(String JavaDoc moduleName, String JavaDoc controllerName) {
1644        if (moduleName == null) {
1645            throw new IllegalArgumentException JavaDoc("ConfigManager.getActionConfigList(): " +
1646                    "parameter moduleName cannot be null");
1647        }
1648        if (controllerName == null) {
1649            throw new IllegalArgumentException JavaDoc("ConfigManager.getActionConfigList(): " +
1650                    "parameter controllerName cannot be null");
1651        }
1652
1653        List result = new ArrayList JavaDoc();
1654
1655        synchronized (mapModuleMapping) {
1656            Map mapMappings = (Map) mapModuleMapping.get(moduleName);
1657            if (mapMappings != null) {
1658                List mappings = (List) mapMappings.get(controllerName);
1659                if (mappings != null) {
1660                    // Protect the internal data structure: always
1661
// return a copy of the list.
1662
result.addAll(mappings);
1663                }
1664            }
1665        }
1666
1667        return result;
1668    }
1669
1670    /**
1671     * Perform a 'reverse-mapping', that is, locate a Struts action mapping
1672     * by looking for the given controller name (and optional state name)
1673     *
1674     * @param controllerName the classname of the controller to look up.
1675     * @param stateName the name of the state to lookup within that controller
1676     * @return the ActionMapping associated with the parameters specified
1677     * @deprecated this method is now deprecated and does no anything since Struts 1.1
1678     * {@link #getActionConfig(String moduleName, String controllerName, String stateName )}
1679     */

1680    public static ActionMapping getMapping(String JavaDoc controllerName, String JavaDoc stateName) {
1681        ActionMapping mapping = null;
1682        ActionConfig config = getActionConfig("", controllerName, stateName);
1683        if (config != null) {
1684            // Because `org.apache.struts.action.ActionMapping' is a
1685
// direct subclass of
1686
// `org.apache.struts.action.util.ActionConfig' we can use
1687
// the common beans utils to copy the properties from one
1688
// to the other easily.
1689
mapping = new ActionMapping();
1690            try {
1691                BeanUtils.copyProperties(mapping, config);
1692            } catch (Exception JavaDoc e) {
1693                log.error("BeanUtils failed to copy properties", e);
1694                e.printStackTrace();
1695            }
1696        }
1697
1698        return mapping;
1699    } /* getMapping(String controllerName, String stateName) */
1700
1701
1702    //////////////////////////////////////////////////////////////////////
1703
// END OF STRUTS 1.1 INTEGRATION
1704
//////////////////////////////////////////////////////////////////////
1705

1706
1707    /**
1708     * Read the Expresso-config.xml file, populating the configuration tree as we go
1709     * <p/>
1710     * This method utilizes the Strut's XML digester to perform it's configuration
1711     * readings. When Struts 1.1 is eventually integrated, the package will move
1712     * to apache.commons package.
1713     *
1714     * @param configDir The directory that the expresso-config.xml resides in.
1715     * @throws ConfigurationException if something goes wrong in reading the XML
1716     * file.
1717     */

1718    private void readXMLConfig(String JavaDoc configDir)
1719            throws ConfigurationException {
1720        Logger setupLog = Logger.getLogger(ConfigManager.class);
1721        setupLog.info("ConfigManager: Reading XML config");
1722
1723        setSAXParser();
1724
1725        Digester digester = new Digester();
1726        URL JavaDoc url = ConfigManager.class.getResource(EXPRESSO_DTD_COPY_LOCATION);
1727
1728        if (url != null) {
1729            digester.register("-//Jcorporate Ltd//DTD Expresso Configuration 4.0//EN",
1730                    url.toString());
1731        } else {
1732            ConfigurationException ce = new ConfigurationException(
1733                    "ConfigManager: Unable to get URL to the expresso-config dtd from: " + EXPRESSO_DTD_COPY_LOCATION + " relative to classes directory (DTD should be copied there).");
1734            setConfigurationFailureException(ce);
1735            throw ce;
1736        }
1737
1738        myConfig = new ConfigExpresso();
1739
1740        ConfigErrorHandler myHandler = new ConfigErrorHandler();
1741        digester.setErrorHandler(myHandler);
1742        digester.setUseContextClassLoader(true);
1743// ClassLoader cl = ConfigManager.class.getClassLoader();
1744
// if (cl != null) {
1745
// digester.setClassLoader(ConfigManager.class.getClassLoader());
1746
// } else {
1747
// digester.setClassLoader(Thread.currentThread().getContextClassLoader());
1748
// }
1749
// digester.setDebug(9); // is a no-op in digester v.1.3
1750

1751        this.setDigesterRules(myConfig, digester);
1752
1753
1754        FileInputStream JavaDoc fin = null;
1755
1756        try {
1757            fin = new FileInputStream JavaDoc(configDir + "/expresso-config.xml");
1758        } catch (FileNotFoundException JavaDoc fe) {
1759            ConfigurationException ce = new ConfigurationException("No such file as '" +
1760                    configDir +
1761                    "/expresso-config.xml");
1762            setConfigurationFailureException(ce);
1763            throw ce;
1764        }
1765        try {
1766            digester.parse(fin);
1767        } catch (IOException JavaDoc ie) {
1768            System.err.println("ConfigManager: IOException reading expresso-config.xml:");
1769            ie.printStackTrace(System.err);
1770            configurationFailed = true;
1771            setConfigurationFailureException(ie);
1772            throw new ConfigurationException("IO Exception reading expresso-config.xml");
1773        } catch (SAXException JavaDoc se) {
1774            System.err.println("ConfigManager: SAXException reading expresso-config.xml:");
1775            se.printStackTrace(System.err);
1776            setConfigurationFailureException(se);
1777
1778            if (se.getException() != null) {
1779                System.err.println("ConfigManager: Nested SAX Exception:");
1780                se.getException().printStackTrace(System.err);
1781            }
1782
1783            configurationFailed = true;
1784            throw new ConfigurationException("SAX Exception reading expresso-config.xml");
1785        } catch (IllegalArgumentException JavaDoc ia) {
1786            configurationFailed = true;
1787            setConfigurationFailureException(ia);
1788            throw new ConfigurationException("Illegal Setup Value Specified",
1789                    ia);
1790        } finally {
1791            if (fin != null) {
1792                try {
1793                    fin.close();
1794                } catch (IOException JavaDoc ex) {
1795                    setupLog.error("Error closing file input stream", ex);
1796                }
1797            }
1798        }
1799
1800        digester = null;
1801        System.gc(); //Digester is an expensive memory allocation, clean up now.
1802

1803        //Output any errors or warnings.
1804
if (myHandler.anyErrorsOrWarnings()) {
1805            Exception JavaDoc oneException = null;
1806            Vector JavaDoc warnings = myHandler.getWarnings();
1807
1808            if (warnings.size() > 0) {
1809                System.err.println("ConfigManager: XML warnings:");
1810
1811                for (Enumeration JavaDoc ee2 = warnings.elements();
1812                     ee2.hasMoreElements();) {
1813                    oneException = (Exception JavaDoc) ee2.nextElement();
1814                    oneException.printStackTrace(System.err);
1815                    setConfigurationFailureException(oneException);
1816                }
1817            } /* if any warnings */
1818
1819
1820            Vector JavaDoc errors = myHandler.getErrors();
1821
1822            if (errors.size() > 0) {
1823                System.err.println("ConfigManager: XML errors:");
1824
1825                for (Enumeration JavaDoc ee = errors.elements(); ee.hasMoreElements();) {
1826                    oneException = (Exception JavaDoc) ee.nextElement();
1827                    oneException.printStackTrace(System.err);
1828                    setConfigurationFailureException(oneException);
1829                }
1830            } /* if any errors */
1831
1832
1833            Exception JavaDoc fatal = myHandler.getFatalException();
1834
1835            if (fatal != null) {
1836                System.err.println("ConfigManager: Fatal XML exception:");
1837                setConfigurationFailureException(oneException);
1838                fatal.printStackTrace(System.err);
1839            }
1840
1841            configurationFailed = true;
1842            throw new ConfigurationException("Unable to parse expresso-config.xml successfully. " +
1843                    "Please see your 'system.err' log file for details of the problem");
1844        }
1845
1846        System.err.println("ConfigManager: Done reading XML config - no errors or warnings");
1847
1848        //myConfig.display();
1849

1850        /* Load the contexts into a hashtable for easy access */
1851        ConfigContext oneContext = null;
1852
1853        Vector JavaDoc contexts = myConfig.getContexts();
1854        int contextsize = contexts.size();
1855        for (int i = 0; i < contextsize; i++) {
1856            //Remove any non-active contexts while we're at it.
1857
oneContext = (ConfigContext) contexts.elementAt(i);
1858            if (oneContext.isActive() == true) {
1859                allContexts.put(oneContext.getName(), oneContext);
1860            } else {
1861                contexts.removeElementAt(i);
1862                contextsize -= 1;
1863                i--;
1864            }
1865        }
1866
1867        xmlConfigOk = true;
1868    }
1869
1870    /**
1871     * Set up the rules for the digester
1872     *
1873     * @param myConfig The root of the bean accepting the digester input
1874     * @param digester an instantiated Digester ready to accept the rules.
1875     */

1876    protected void setDigesterRules(ConfigExpresso myConfig, Digester digester) {
1877        digester.push(myConfig);
1878
1879        /* Top-level configuration */
1880        digester.addSetProperties("expresso-config");
1881        digester.addCallMethod("expresso-config/logDirectory",
1882                "setLogDirectory", 0);
1883        digester.addCallMethod("expresso-config/strongCrypto",
1884                "setStrongCrypto", 0);
1885        digester.addCallMethod("expresso-config/cryptoKey", "setCryptoKey", 0);
1886        digester.addCallMethod("expresso-config/servletAPI", "setServletAPI",
1887                0);
1888        digester.addCallMethod("expresso-config/encryptMode", "setEncryptMode",
1889                0);
1890
1891        digester.addCallMethod("expresso-config/httpPort", "setHttpPort", 0);
1892        digester.addCallMethod("expresso-config/sslPort", "setSslPort", 0);
1893
1894        /* Cache Manager configuration */
1895        digester.addObjectCreate("expresso-config/cacheManager",
1896                "com.jcorporate.expresso.core.misc.ConfigCacheManager");
1897        digester.addSetProperties("expresso-config/context/cacheManager");
1898        digester.addSetNext("expresso-config/cacheManager", "addCacheManager",
1899                "com.jcorporate.expresso.core.misc.ConfigCacheManager");
1900
1901        /* Each class handler */
1902        digester.addObjectCreate("expresso-config/class-handlers/class-handler",
1903                "com.jcorporate.expresso.core.misc.ConfigClassHandler");
1904        digester.addSetProperties("expresso-config/class-handlers/class-handler");
1905        digester.addSetNext("expresso-config/class-handlers/class-handler",
1906                "addClassHandler",
1907                "com.jcorporate.expresso.core.misc.ConfigClassHandler");
1908        digester.addObjectCreate("expresso-config/class-handlers/class-handler/handler-parameter",
1909                "com.jcorporate.expresso.core.misc.ConfigClassHandlerParameter");
1910        digester.addSetProperties("expresso-config/class-handlers/class-handler/handler-parameter");
1911        digester.addSetNext("expresso-config/class-handlers/class-handler/handler-parameter",
1912                "addParameter",
1913                "com.jcorporate.expresso.core.misc.ConfigClassHandlerParameter");
1914
1915        /* Each context */
1916        digester.addObjectCreate("expresso-config/context",
1917                "com.jcorporate.expresso.core.misc.ConfigContext");
1918        digester.addSetProperties("expresso-config/context");
1919        digester.addCallMethod("expresso-config/context/description",
1920                "setDescription", 0);
1921        digester.addCallMethod("expresso-config/context/images", "setImages",
1922                0);
1923        digester.addCallMethod("expresso-config/context/startJobHandler",
1924                "setStartJobHandler", 0);
1925        digester.addCallMethod("expresso-config/context/showStackTrace",
1926                "setShowStackTrace", 0);
1927        digester.addCallMethod("expresso-config/context/mailDebug",
1928                "setMailDebug", 0);
1929        digester.addCallMethod("expresso-config/context/expressoDir",
1930                "setExpressoDir", 0);
1931        digester.addCallMethod("expresso-config/context/hasSetupTables",
1932                "setHasSetupTables", 0);
1933        digester.addSetNext("expresso-config/context", "addContext",
1934                "com.jcorporate.expresso.core.misc.ConfigContext");
1935
1936        /* Jdbc definition within the context */
1937        digester.addObjectCreate("expresso-config/context/jdbc",
1938                "com.jcorporate.expresso.core.misc.ConfigJdbc");
1939        digester.addCallMethod("expresso-config/context/jdbc/dbWildcard",
1940                "addWildcard", 0);
1941        digester.addSetProperties("expresso-config/context/jdbc");
1942        digester.addSetNext("expresso-config/context/jdbc", "addJdbc",
1943                "com.jcorporate.expresso.core.misc.ConfigJdbc");
1944
1945        /* Jndi definition within the context/jdbc */
1946        digester.addObjectCreate("expresso-config/context/jdbc/jndi",
1947                "com.jcorporate.expresso.core.misc.ConfigJndi");
1948        digester.addSetProperties("expresso-config/context/jdbc/jndi");
1949        digester.addSetNext("expresso-config/context/jdbc/jndi", "addJndi",
1950                "com.jcorporate.expresso.core.misc.ConfigJndi");
1951
1952        /* Path mapping configuration within the Context */
1953        digester.addObjectCreate("expresso-config/context/path-mappings/path-mapping",
1954                "com.jcorporate.expresso.core.misc.ConfigPathMapping");
1955        digester.addSetProperties("expresso-config/context/path-mappings/path-mapping");
1956        digester.addSetNext("expresso-config/context/path-mappings/path-mapping",
1957                "addPathMapping",
1958                "com.jcorporate.expresso.core.misc.ConfigPathMapping");
1959        digester.addCallMethod("expresso-config/context/path-mappings/path-mapping/url-pattern",
1960                "setUrlPattern", 0);
1961        digester.addCallMethod("expresso-config/context/path-mappings/path-mapping/path",
1962                "setPath", 0);
1963        digester.addObjectCreate("expresso-config/context/path-mappings/path-mapping/param",
1964                "com.jcorporate.expresso.core.misc.ConfigPathParam");
1965        digester.addSetNext("expresso-config/context/path-mappings/path-mapping/param",
1966                "addParam",
1967                "com.jcorporate.expresso.core.misc.ConfigPathParam");
1968        digester.addObjectCreate("expresso-config/context/path-mappings/path-mapping/fixed-param",
1969                "com.jcorporate.expresso.core.misc.ConfigPathFixedParam");
1970        digester.addSetNext("expresso-config/context/path-mappings/path-mapping/fixed-param",
1971                "addFixedParam",
1972                "com.jcorporate.expresso.core.misc.ConfigPathFixedParam");
1973
1974        //digester.addCallMethod("expresso-config/context/path-mappings/path-mapping/fixed-param",
1975
// "addFixedParam", 0);
1976
digester.addCallMethod("expresso-config/context/path-mappings/path-mapping/param/param-name",
1977                "setName", 0);
1978        digester.addCallMethod("expresso-config/context/path-mappings/path-mapping/param/param-number",
1979                "setNumber", 0);
1980        digester.addCallMethod("expresso-config/context/path-mappings/path-mapping/fixed-param/param-name",
1981                "setName", 0);
1982        digester.addCallMethod("expresso-config/context/path-mappings/path-mapping/fixed-param/param-value",
1983                "setValue", 0);
1984
1985        /* LDAP definition within the context */
1986        digester.addObjectCreate("expresso-config/context/ldap",
1987                "com.jcorporate.expresso.core.misc.ConfigLdap");
1988        digester.addSetProperties("expresso-config/context/ldap");
1989        digester.addSetNext("expresso-config/context/ldap", "addLdap",
1990                "com.jcorporate.expresso.core.misc.ConfigLdap");
1991
1992        /* Setup values default entry */
1993        digester.addObjectCreate("expresso-config/context/setupDefault",
1994                "com.jcorporate.expresso.core.misc.ConfigSetupDefault");
1995        digester.addSetProperties("expresso-config/context/setupDefault");
1996        digester.addSetNext("expresso-config/context/setupDefault",
1997                "addSetupDefault",
1998                "com.jcorporate.expresso.core.misc.ConfigSetupDefault");
1999
2000        /* Type mappings */
2001        digester.addObjectCreate("expresso-config/context/type-mapping",
2002                "com.jcorporate.expresso.core.misc.ConfigTypeMapping");
2003        digester.addSetNext("expresso-config/context/type-mapping",
2004                "addTypeMapping",
2005                "com.jcorporate.expresso.core.misc.ConfigTypeMapping");
2006        digester.addCallMethod("expresso-config/context/type-mapping/java-type",
2007                "setJavaType", 0);
2008        digester.addCallMethod("expresso-config/context/type-mapping/db-type",
2009                "setDBType", 0);
2010        digester.addCallMethod("expresso-config/context/type-mapping/expresso-type",
2011                "setExpressoType", 0);
2012
2013        /* Custom properties */
2014        digester.addObjectCreate("expresso-config/context/customProperty",
2015                "com.jcorporate.expresso.core.misc.ConfigCustomProperty");
2016        digester.addSetNext("expresso-config/context/customProperty",
2017                "addCustomProperty",
2018                "com.jcorporate.expresso.core.misc.ConfigCustomProperty");
2019        digester.addSetProperties("expresso-config/context/customProperty");
2020        digester.addCallMethod("expresso-config/context/customProperty/name",
2021                "setName", 0);
2022        digester.addCallMethod("expresso-config/context/customProperty/value",
2023                "setValue", 0);
2024        //digester.setDebug(configDebugLevel); // is a no-op in v.1.3 anyway
2025
digester.setValidating(true);
2026
2027    }
2028
2029    /*
2030    * Goes through a pre-determined list of SAX parsers,
2031    * the first one found is used to parse XML config files.
2032     */

2033    protected void setSAXParser() {
2034
2035        //
2036
//Constructor globally sets things for us.
2037
//
2038
new SaxParserConfigurer();
2039    }
2040
2041} /* ConfigManager */
2042
Popular Tags