0001: /* ====================================================================
0002: * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
0003: *
0004: * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
0005: *
0006: * Redistribution and use in source and binary forms, with or without
0007: * modification, are permitted provided that the following conditions
0008: * are met:
0009: *
0010: * 1. Redistributions of source code must retain the above copyright
0011: * notice, this list of conditions and the following disclaimer.
0012: *
0013: * 2. Redistributions in binary form must reproduce the above copyright
0014: * notice, this list of conditions and the following disclaimer in
0015: * the documentation and/or other materials provided with the
0016: * distribution.
0017: *
0018: * 3. The end-user documentation included with the redistribution,
0019: * if any, must include the following acknowledgment:
0020: * "This product includes software developed by Jcorporate Ltd.
0021: * (http://www.jcorporate.com/)."
0022: * Alternately, this acknowledgment may appear in the software itself,
0023: * if and wherever such third-party acknowledgments normally appear.
0024: *
0025: * 4. "Jcorporate" and product names such as "Expresso" must
0026: * not be used to endorse or promote products derived from this
0027: * software without prior written permission. For written permission,
0028: * please contact info@jcorporate.com.
0029: *
0030: * 5. Products derived from this software may not be called "Expresso",
0031: * or other Jcorporate product names; nor may "Expresso" or other
0032: * Jcorporate product names appear in their name, without prior
0033: * written permission of Jcorporate Ltd.
0034: *
0035: * 6. No product derived from this software may compete in the same
0036: * market space, i.e. framework, without prior written permission
0037: * of Jcorporate Ltd. For written permission, please contact
0038: * partners@jcorporate.com.
0039: *
0040: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0041: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0042: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0043: * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
0044: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0045: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
0046: * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0047: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0048: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0049: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0050: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0051: * SUCH DAMAGE.
0052: * ====================================================================
0053: *
0054: * This software consists of voluntary contributions made by many
0055: * individuals on behalf of the Jcorporate Ltd. Contributions back
0056: * to the project(s) are encouraged when you make modifications.
0057: * Please send them to support@jcorporate.com. For more information
0058: * on Jcorporate Ltd. and its products, please see
0059: * <http://www.jcorporate.com/>.
0060: *
0061: * Portions of this software are based upon other open source
0062: * products and are subject to their respective licenses.
0063: */
0064:
0065: package com.jcorporate.expresso.core.misc;
0066:
0067: import com.jcorporate.expresso.core.cache.CacheManager;
0068: import com.jcorporate.expresso.core.controller.ControllerException;
0069: import com.jcorporate.expresso.core.controller.ControllerFactory;
0070: import com.jcorporate.expresso.core.db.DBConnectionPool;
0071: import com.jcorporate.expresso.core.db.DBException;
0072: import com.jcorporate.expresso.core.dbobj.DBObject;
0073: import com.jcorporate.expresso.core.dbobj.Schema;
0074: import com.jcorporate.expresso.core.dbobj.SchemaFactory;
0075: import com.jcorporate.expresso.core.dbobj.SecuredDBObject;
0076: import com.jcorporate.expresso.core.job.ServerException;
0077: import com.jcorporate.expresso.core.jsdkapi.GenericDispatcher;
0078: import com.jcorporate.expresso.core.registry.MutableRequestRegistry;
0079: import com.jcorporate.expresso.core.registry.RequestRegistry;
0080: import com.jcorporate.expresso.core.security.SuperUser;
0081: import com.jcorporate.expresso.core.security.User;
0082: import com.jcorporate.expresso.core.utility.JobHandler;
0083: import com.jcorporate.expresso.kernel.LogManager;
0084: import com.jcorporate.expresso.kernel.digester.SaxParserConfigurer;
0085: import com.jcorporate.expresso.kernel.util.FastStringBuffer;
0086: import com.jcorporate.expresso.services.dbobj.DBOtherMap;
0087: import com.jcorporate.expresso.services.dbobj.SchemaList;
0088: import com.jcorporate.expresso.services.dbobj.Setup;
0089: import com.jcorporate.expresso.services.test.TestSystemInitializer;
0090: import org.apache.commons.beanutils.BeanUtils;
0091: import org.apache.commons.digester.Digester;
0092: import org.apache.log4j.Logger;
0093: import org.apache.struts.action.ActionMapping;
0094: import org.apache.struts.config.ActionConfig;
0095: import org.apache.struts.config.ForwardConfig;
0096: import org.apache.struts.config.ModuleConfig;
0097: import org.xml.sax.InputSource;
0098: import org.xml.sax.SAXException;
0099:
0100: import javax.servlet.ServletConfig;
0101: import javax.servlet.ServletContext;
0102: import javax.servlet.ServletException;
0103: import javax.servlet.http.HttpServletRequest;
0104: import java.io.File;
0105: import java.io.FileInputStream;
0106: import java.io.FileNotFoundException;
0107: import java.io.IOException;
0108: import java.net.URL;
0109: import java.util.ArrayList;
0110: import java.util.Enumeration;
0111: import java.util.HashMap;
0112: import java.util.Hashtable;
0113: import java.util.Iterator;
0114: import java.util.List;
0115: import java.util.Map;
0116: import java.util.Vector;
0117:
0118: /**
0119: * ConfigManager is a static class that utilizes the Struts Digester
0120: * utility to read an XML file of configuration parameters when
0121: * Expresso starts up. These parameters are then available during the
0122: * execution of the application.
0123: *
0124: * @author Adam Rossi
0125: */
0126: public final class ConfigManager {
0127:
0128: /**
0129: * constant path for DTD file; we expect DTD to be placed here, probably by a ANT copy before running servlet engine
0130: * searched relative to class dir
0131: */
0132: public static final String EXPRESSO_DTD_COPY_LOCATION = "/com/jcorporate/expresso/core/expresso-config_4_0.dtd";
0133:
0134: /**
0135: * name of servlet param which controls logging directory
0136: */
0137: public static final String LOG_DIR_PARAM_NAME = "logDir";
0138:
0139: /**
0140: * Hashtable of current logins sitting in the system.
0141: */
0142: private static Hashtable currentLogins = new Hashtable();
0143:
0144: /*
0145: * A hashtable for quick lookup of the ConfigContext object for each
0146: * context specified in the expresso-config.xml file
0147: */
0148: private static Hashtable allContexts = new Hashtable();
0149:
0150: /* During startup, the InitServlet passes this information
0151:
0152: * to ConfigManager if it's available
0153:
0154: */
0155: private static String configDir = "";
0156: // private static String webAppDir = "";
0157: // private static String contextPath = "";
0158: // private static String serverPrefix = "";
0159: private static String servletAPIVersion = "2_2";
0160: // STRUTS 1.1
0161: // private static Hashtable mappingsCache = null;
0162: /**
0163: * Map collection to associate module names with action mappings
0164: * The default module has a prefix of "".
0165: */
0166: private static Map mapModuleMapping = new HashMap(); // STRUTS 1.1
0167:
0168: private static ConfigExpresso myConfig = null;
0169:
0170: //Stores DBOtherMap entries
0171: private static Hashtable dbOtherMap = new Hashtable();
0172: private static Logger log = Logger.getLogger(ConfigManager.class);
0173:
0174: /* Set to true once the XML configuration file has been successfully read */
0175: private static boolean xmlConfigOk = false;
0176: private static boolean configurationFailed = false;
0177:
0178: /**
0179: * List of currently running job handlers
0180: */
0181: private static Hashtable jobHandlers = new Hashtable();
0182:
0183: /**
0184: * If configuration failed on initial startup, we keep the exception
0185: * that caused the failure available for reference
0186: */
0187: private static Throwable configurationFailureException = null;
0188: private static HttpServletRequest myRequest = null;
0189:
0190: /**
0191: * Singleton implementation function.
0192: */
0193: private static ConfigManager theInstance = null;
0194: private static ControllerFactory controllerFactory = null;
0195:
0196: /**
0197: * Adds to the 'we have X many logins' hashtable.
0198: *
0199: * @param newLogin the new login
0200: */
0201: public static void addSession(CurrentLogin newLogin) {
0202: if (currentLogins == null) {
0203: currentLogins = new Hashtable();
0204: }
0205:
0206: if (newLogin == null) {
0207: return;
0208: }
0209:
0210: String sessionid = newLogin.getSessionId();
0211: if (sessionid == null) {
0212: return;
0213: }
0214:
0215: if (currentLogins.containsKey(newLogin.getSessionId())) {
0216: currentLogins.remove(newLogin.getSessionId());
0217: }
0218: currentLogins.put(newLogin.getSessionId(), newLogin);
0219: }
0220:
0221: public static void setConfigurationFailureException(Throwable ee) {
0222: configurationFailureException = ee;
0223: }
0224:
0225: public static Throwable getConfigurationFailureException() {
0226: return configurationFailureException;
0227: }
0228:
0229: /**
0230: * Removes a stored session. Used for tracking the number of people
0231: * currently logged in.
0232: *
0233: * @param sessionId the session id that we are receiving the signal for
0234: */
0235: public static void removeSession(String sessionId) {
0236: if (sessionId == null) {
0237: return;
0238: }
0239:
0240: if (currentLogins == null) {
0241: currentLogins = new Hashtable();
0242: }
0243:
0244: if (currentLogins.containsKey(sessionId)) {
0245: currentLogins.remove(sessionId);
0246: }
0247:
0248: //
0249: //If we drop to zero logins, now is the perfect time to run the
0250: //garbage collector and all pending finalizers.
0251: //
0252: if (currentLogins.size() == 0) {
0253: System.gc();
0254: System.runFinalization();
0255: }
0256: }
0257:
0258: /**
0259: * Returns a hashtable of the current login objects
0260: *
0261: * @return a Hashtable containing everybody logged in.
0262: */
0263: public static Hashtable getCurrentLogins() {
0264: return (Hashtable) currentLogins.clone();
0265: }
0266:
0267: /**
0268: * Returns a specific job handler.
0269: *
0270: * @param contextName The dbcontext to get the jobhandler from. ex: <code>
0271: * default</code>
0272: * @return the JobHandler for that specific context
0273: */
0274: public static JobHandler getJobHandler(String contextName) {
0275: return (JobHandler) jobHandlers.get(contextName);
0276: }
0277:
0278: /**
0279: * Gets all job handlers in the system
0280: *
0281: * @return a hashtable of all Job Handlers
0282: */
0283: public static Hashtable getAllJobHandlers() {
0284: return jobHandlers;
0285: }
0286:
0287: /**
0288: * Default Constructer
0289: */
0290: public ConfigManager() {
0291:
0292: //Initialize the nextNumber stuff
0293: super ();
0294: } /* ConfigManager() */
0295:
0296: /**
0297: * Queries the current servletAPI defined in the configuration system
0298: *
0299: * @return A string listing the current servletAPIVersion being used
0300: */
0301: public static String getServletAPIVersion() {
0302: return servletAPIVersion;
0303: } /* getServletAPIVersion() */
0304:
0305: /**
0306: * Remove our database pool(s)
0307: * <p/>
0308: * Closes all connections so that Hypersonic can handle multiple test
0309: * suites from multiple VM's thrown at it as long as each test suite
0310: * calls dbUninitialize in the teardown method.
0311: */
0312: public static synchronized void dbUninitialize() throws DBException {
0313: if (log.isInfoEnabled()) {
0314: log.info("Tearing down connection pools");
0315: }
0316:
0317: DBConnectionPool.reInitialize();
0318: }
0319:
0320: /**
0321: * Call this to destroy all items that ConfigManager uses.
0322: * Initially not everythiny is implemented. Must be tested If there
0323: * is an error the system prints a stack trace to System.err instead of the
0324: * log since logging may have shut down by now.
0325: */
0326: public static synchronized void destroy() {
0327: if (theInstance == null) {
0328: return;
0329: }
0330:
0331: ConfigManager cm = ConfigManager.getInstance();
0332:
0333: try {
0334: cm.stopJobHandler();
0335: ConfigManager.dbUninitialize();
0336:
0337: com.jcorporate.expresso.core.dbobj.NextNumber.destroy();
0338: CacheManager.destroy();
0339: com.jcorporate.expresso.core.security.CryptoManager
0340: .getInstance().destroy();
0341: com.jcorporate.expresso.core.security.DelayThread.kill();
0342: LogManager.destroy();
0343: /**
0344: * Hack... if we're running hypersonic locally, we have to issue a shutdown
0345: * request so the VM can exit.
0346: */
0347: for (Enumeration e = ConfigManager.getAllConfigKeys(); e
0348: .hasMoreElements();) {
0349: String oneKey = (String) e.nextElement();
0350: try {
0351: ConfigJdbc jdbcConfig = ConfigManager.getContext(
0352: oneKey).getJdbc();
0353: if (jdbcConfig.getDriver().equals(
0354: "org.hsqldb.jdbcDriver")) {
0355:
0356: DBConnectionPool pool = DBConnectionPool
0357: .getInstance(oneKey);
0358: pool.executeExclusiveUpdate("SHUTDOWN");
0359: }
0360: } catch (DBException ex) {
0361: System.err
0362: .println("Error shutting down hypersonic: "
0363: + ex.getMessage());
0364: }
0365:
0366: }
0367: theInstance = null;
0368: } catch (Exception e) {
0369: e.printStackTrace();
0370: System.err.println(e.getMessage());
0371: }
0372:
0373: }
0374:
0375: /**
0376: * Initialize our database pool(s)
0377: *
0378: * @throws ConfigurationException if there is an error getting the config
0379: * values from the config beans.
0380: */
0381: public static synchronized void dbInitialize()
0382: throws ConfigurationException {
0383: if (log.isInfoEnabled()) {
0384: log.info("Initializing connection pool(s)");
0385: }
0386:
0387: String oneConfigKey = null;
0388:
0389: for (Enumeration e = getAllConfigKeys(); e.hasMoreElements();) {
0390: oneConfigKey = (String) e.nextElement();
0391: if (log.isInfoEnabled()) {
0392: log.info("Initializing pool for context '"
0393: + oneConfigKey + "'");
0394: }
0395:
0396: ConfigJdbc myConfig = getJdbc(oneConfigKey);
0397:
0398: if (myConfig != null) {
0399: // dbDriverType attribut added by Yves Henri AMAIZO to be compatible with
0400: // JNDI datasource features. 14/07/2002 23h00
0401:
0402: /* We do an inner "try" here so that if one connection can't be */
0403: /* established the whole system doesn't fail */
0404: try {
0405:
0406: /* we do not actually need a pool, but we call this method
0407: * to initialize the pool
0408: */
0409: DBConnectionPool myPool = DBConnectionPool
0410: .getInstance(oneConfigKey);
0411:
0412: if (!StringUtil.notNull(myConfig.getDbTest())
0413: .equalsIgnoreCase("")) {
0414: myPool.setTestQuery(myConfig.getDbTest());
0415: if (log.isInfoEnabled()) {
0416: log.info("DB connection testing enabled");
0417: }
0418: } else {
0419: if (log.isInfoEnabled()) {
0420: log.info("DB connection testing disabled");
0421: }
0422: }
0423: } catch (DBException de) {
0424: log
0425: .error(
0426: "Initialize failed for context '"
0427: + oneConfigKey
0428: + "'. This pool will not be available.",
0429: de);
0430: }
0431: } /* if there is a JDBC configuration for this context */
0432:
0433: } /* for each config key */
0434:
0435: if (log.isInfoEnabled()) {
0436: log.info("All connection pools initialized");
0437: }
0438:
0439: if (log.isInfoEnabled()) {
0440: log.info("Initializing all registered DBObjets");
0441: }
0442:
0443: } /* dbInitialize() */
0444:
0445: /**
0446: * Iterate through all schemas and instantiate a DBObject. Yes, this by
0447: * and large may get thrown away later, but constructing blank objects allows
0448: * various objects to set up listener relations with other classes.
0449: * This is especially important for UserListener information.
0450: */
0451: static public synchronized void initializeAllDBObjects() {
0452: boolean expressoInitialized = false;
0453:
0454: for (Iterator i = allContexts.keySet().iterator(); i.hasNext();) {
0455: try {
0456: String oneDBName = (String) i.next();
0457: ConfigContext oneContext = ConfigManager
0458: .getContext(oneDBName);
0459:
0460: // set up superuser ID on this thread, which is typically called from
0461: // servlet initialization
0462: User old = null;
0463: try {
0464: old = RequestRegistry.getUser();
0465: } catch (Exception e) {
0466: // no problem
0467: }
0468: try {
0469: //This sets thread local variables with the local registry settings.
0470: //We set it as a superuser instance for initialization purposes
0471: //only. Once the first requests come through, we initialize it
0472: //through the Filter.
0473: new MutableRequestRegistry(oneDBName,
0474: SuperUser.SUPER_USER);
0475: if (oneContext.hasSetupTables()) {
0476:
0477: try {
0478: SchemaList sl = new SchemaList(
0479: SecuredDBObject.SYSTEM_ACCOUNT);
0480: sl.setDataContext(oneDBName);
0481: sl.count();
0482: /** count in order to see if table is ok **/
0483: } catch (DBException e) {
0484: if (log.isInfoEnabled()) {
0485: log
0486: .info("Schema is not initialized yet- run dbcreate for context: "
0487: + oneDBName);
0488: }
0489: continue;
0490: }
0491:
0492: // make sure expresso in initialized before any others
0493: if (expressoInitialized == false) {
0494: initializeOneSchema(com.jcorporate.expresso.core.ExpressoSchema.class
0495: .getName());
0496: expressoInitialized = true;
0497: }
0498:
0499: SchemaList sl = new SchemaList(
0500: SecuredDBObject.SYSTEM_ACCOUNT);
0501: sl.setDataContext(oneDBName);
0502: ArrayList al = sl.searchAndRetrieveList();
0503:
0504: for (Iterator schemas = al.iterator(); schemas
0505: .hasNext();) {
0506: SchemaList oneSchema = (SchemaList) schemas
0507: .next();
0508: try {
0509: initializeOneSchema(oneSchema
0510: .getField(SchemaList.FLD_SCHEMA_CLASS));
0511: } catch (Exception ex) {
0512: log
0513: .error(
0514: "Error initializing schema: "
0515: + oneSchema
0516: .getField(SchemaList.FLD_SCHEMA_CLASS),
0517: ex);
0518: }
0519:
0520: }
0521: }
0522: } finally {
0523: new MutableRequestRegistry(oneDBName, old);
0524: }
0525: } catch (DBException dbe) {
0526: log
0527: .warn(
0528: "Unable to initialize dbobjects... SchemaList may not be initialized yet",
0529: dbe);
0530: } catch (Exception e) {
0531: log.error("Error in initializeAllDBObjects", e);
0532: }
0533: }
0534: }
0535:
0536: static protected synchronized void initializeOneSchema(
0537: String className) {
0538: if (className == null) {
0539: log.warn("initializeOneSchema: Received null className");
0540: return;
0541: }
0542:
0543: Schema schema = SchemaFactory.getInstance()
0544: .getSchema(className);
0545: if (schema == null) {
0546: log.error("initializeOneSchema: cannot find schema: "
0547: + className);
0548: return;
0549: }
0550:
0551: // associate all objects w/i schema with this schema
0552: Enumeration anEnum = schema.getMembers();
0553: while (anEnum.hasMoreElements()) {
0554: DBObject obj = (DBObject) anEnum.nextElement();
0555: try {
0556: obj.setSchema(schema);
0557: } catch (Exception e) {
0558: log.warn("cannot set schema for: "
0559: + obj.getClass().getName() + " because of: "
0560: + e.getMessage());
0561: }
0562: }
0563:
0564: }
0565:
0566: /**
0567: * Return an enumeration of all of the valid configuration keys.
0568: * There is one key for each property file read.
0569: *
0570: * @return java.util.Enumeration
0571: */
0572: public static Enumeration getAllConfigKeys() {
0573: return allContexts.keys();
0574: } /* getAllConfigKeys() */
0575:
0576: /**
0577: * Return the reference instance of the config manager Use this in preference
0578: * to the singleton APIs. So now you have:
0579: * <code>ConfigManager.getInstace().getLogDirectory()</code>
0580: * for instance. instead of <code>ConfigManager.getLogDirectory();
0581: *
0582: * @return an instance of ConfigManager
0583: */
0584: public static synchronized ConfigManager getInstance() {
0585: if (theInstance == null) {
0586: theInstance = new ConfigManager();
0587: }
0588:
0589: return theInstance;
0590: } /* getInstance() */
0591:
0592: /**
0593: * Is the ConfigManager initialized yet?
0594: *
0595: * @return true if the xml configuration parsed correctly
0596: */
0597: public static boolean isInitialized() {
0598: return xmlConfigOk;
0599: } /* isInitialized() */
0600:
0601: /**
0602: * Return the top-level configuration object, an instance of the ConfigExpresso
0603: * class. This class contains all the setup options common to all contexts
0604: *
0605: * @return a ConfigExpresso bean
0606: */
0607: public static ConfigExpresso getConfig() {
0608: return myConfig;
0609: } /* getConfig() */
0610:
0611: /**
0612: * Returns a hashmap keyed by filename, and data ='s a series of input
0613: * streams corresponding to xml files of the desired doctype. All files are
0614: * located in the Expresso configuration directory
0615: *
0616: * @param filterDocType - The doctype that you need for configuration files
0617: * @return HashMap of InputSources of xml files of the appropriate types.
0618: * @throws ConfigurationException if an error occurs while checking xml file
0619: * types
0620: */
0621: public static HashMap getConfigInputSources(String filterDocType)
0622: throws ConfigurationException {
0623: final String myName = "ConfigManager.getConfigInputSources(String)";
0624: HashMap returnSources = new HashMap();
0625: String configDir = ConfigManager.getConfigDir();
0626:
0627: if (configDir == null) {
0628: throw new ConfigurationException(myName
0629: + ": There is no config Directory Set");
0630: }
0631:
0632: InputSource inputSource = null;
0633: XmlDocTypeFilter xmldtf = new XmlDocTypeFilter();
0634:
0635: if ('/' == configDir.charAt(0) == false) {
0636: configDir = "/" + configDir;
0637: }
0638:
0639: if (log.isDebugEnabled()) {
0640: log.debug("Getting Input Sources in directory: "
0641: + configDir);
0642: }
0643:
0644: File propDir = new File(configDir);
0645:
0646: if (!propDir.isDirectory()) {
0647: throw new ConfigurationException(myName + ": " + configDir
0648: + " is not a directory");
0649: }
0650:
0651: String[] flist = propDir.list();
0652:
0653: for (int i = 0; i < flist.length; i++) {
0654: if (log.isDebugEnabled()) {
0655: log.debug("Checking file: " + flist[i]);
0656: }
0657: if (flist[i].endsWith(".xml")) {
0658: if (log.isDebugEnabled()) {
0659: log.debug("File ends with xml");
0660: }
0661:
0662: try {
0663: String propFileName = configDir + "/" + flist[i];
0664: FileInputStream fis = new FileInputStream(
0665: propFileName);
0666:
0667: try {
0668: inputSource = new InputSource(fis);
0669: inputSource.setSystemId(configDir + "/");
0670:
0671: if (xmldtf.isProperDocType(filterDocType,
0672: inputSource) == true) {
0673: if (log.isDebugEnabled()) {
0674: log.debug(propFileName + " is doctype "
0675: + filterDocType
0676: + " adding as inputsource");
0677: }
0678: fis.close();
0679: inputSource = new InputSource(
0680: new FileInputStream(propFileName));
0681: inputSource.setSystemId(configDir + "/");
0682: returnSources.put(flist[i], inputSource);
0683: } else {
0684: if (log.isDebugEnabled()) {
0685: log.debug(propFileName
0686: + " is not of doctype "
0687: + filterDocType);
0688: }
0689: }
0690: } finally {
0691: fis.close();
0692: }
0693: } catch (java.io.FileNotFoundException fnfe) {
0694: throw new ConfigurationException(fnfe);
0695: } catch (java.io.IOException ioe) {
0696: throw new ConfigurationException(ioe);
0697: }
0698: }
0699: }
0700:
0701: return returnSources;
0702: }
0703:
0704: /**
0705: * Return the context configuration object for the named context. This object
0706: * contains all of the configuration info for a specific context/database
0707: *
0708: * @param contextName the data context to retrieve the configuration information
0709: * for
0710: * @return the ConfigContextBean for the data context specified
0711: * @throws ConfigurationException if there's an error retrieving the ConfigContext
0712: * bean for the specified context
0713: */
0714: public static ConfigContext getContext(String contextName)
0715: throws ConfigurationException {
0716: StringUtil.assertNotBlank(contextName,
0717: "You must specify a context name");
0718:
0719: if (allContexts == null) {
0720: throw new ConfigurationException("No contexts available");
0721: }
0722:
0723: ConfigContext oneContext = (ConfigContext) allContexts
0724: .get(contextName);
0725:
0726: if (oneContext == null) {
0727: throw new ConfigurationException(
0728: "No such configuration context as '" + contextName
0729: + "'");
0730: }
0731:
0732: return oneContext;
0733: }
0734:
0735: /**
0736: * Return the Class dealing with the named ClassHandler
0737: *
0738: * @param handlerName the 'service name' of the classhandler to retrieve
0739: * @return the name of the class to use for this 'category'
0740: */
0741: public static String getClassHandler(String handlerName) {
0742: ConfigClassHandler cch = (ConfigClassHandler) myConfig
0743: .getClassHandlers().get(handlerName);
0744:
0745: if (cch == null) {
0746: return null;
0747: }
0748:
0749: return cch.getClassHandler();
0750: }
0751:
0752: /**
0753: * Returns the given parameter for a class handler.
0754: *
0755: * @param handlerName the 'service name' of the classhandler to retrieve
0756: * @param parameter The name of the parameter to get
0757: * @return the value of the parameter for this class handler
0758: */
0759: public static String getClassHandlerParameter(String handlerName,
0760: String parameter) {
0761: return ((ConfigClassHandler) myConfig.getClassHandlers().get(
0762: handlerName)).getParameter(parameter);
0763: }
0764:
0765: /**
0766: * Get the Jdbc configuration (if any) for the named context
0767: *
0768: * @param contextName the data context to get the JDBC configuration bean for
0769: * @return a ConfigJdbc Configuration Bean
0770: * @throws ConfigurationException if there is an error retrieving the context
0771: */
0772: public static ConfigJdbc getJdbc(String contextName)
0773: throws ConfigurationException {
0774: ConfigContext oneContext = getContext(contextName);
0775:
0776: if (oneContext != null) {
0777: return oneContext.getJdbc();
0778: }
0779:
0780: return null;
0781: }
0782:
0783: /**
0784: * Get a Jdbc configuration object, throwing an exception if there is not one
0785: * for the specified context
0786: *
0787: * @param contextName the data context to get the JDBC configuration bean for
0788: * @return a ConfigJdbc Configuration Bean
0789: * @throws ConfigurationException if there is an error retrieving the context
0790: */
0791: public static ConfigJdbc getJdbcRequired(String contextName)
0792: throws ConfigurationException {
0793: ConfigJdbc myJdbc = getJdbc(contextName);
0794:
0795: if (myJdbc == null) {
0796: throw new ConfigurationException("Context '" + contextName
0797: + "' is not configured for JDBC access");
0798: }
0799:
0800: return myJdbc;
0801: }
0802:
0803: /**
0804: * Get the actual filesystem directory that is the root of this web-app
0805: *
0806: * @return The filesystem directory that is the root of this webapp.
0807: */
0808: public static String getWebAppDir() {
0809: String webAppDir = SystemMacros.getInstance().getWebAppDir();
0810:
0811: if (webAppDir == null) {
0812: try {
0813: throw new Exception(
0814: "Getting requests for web application directory, but system is deployed in a "
0815: + "compressed war file. There is no such thing");
0816: } catch (Exception ex) {
0817: log.warn("getWebAppDir path error", ex);
0818: }
0819: }
0820: return webAppDir;
0821: } /* getWebAppDir() */
0822:
0823: /**
0824: * Checks to see if any given field or tablename fed to this qualifies
0825: * as a known reserved word for various databases.
0826: *
0827: * @param testWord The word to check against the list of known reserved
0828: * words.
0829: * @return true if the test word is a reserved word.
0830: * @todo Convert this to isReservedWord() and get all dbobjects converted
0831: * over.
0832: */
0833: public static boolean isReservedWord(String testWord) {
0834:
0835: // return ReservedWords.getInstance().isReservedWord(testWord);
0836: return ReservedWords.getInstance().isExpressoReservedWord(
0837: testWord);
0838: }
0839:
0840: /**
0841: * Checks to see if a controller parameter may be a reserved word. This
0842: * helps prevent any weird behavior when posting objects.
0843: *
0844: * @param testWord The word to check against the list of known reserved
0845: * words.
0846: * @return true if the test word is a reserved word.
0847: */
0848: public static boolean isParameterReservedWord(String testWord) {
0849: return ReservedWords.getInstance().isExpressoReservedWord(
0850: testWord);
0851: }
0852:
0853: /**
0854: * Start job handlers
0855: * The job handler for each DB context is started if the appropriate
0856: * configuration entry is found for that context
0857: *
0858: * @throws ConfigurationException if there's a config error reading job values or
0859: * getting job values for a particular context.
0860: */
0861: public static synchronized void startJobHandler()
0862: throws ConfigurationException {
0863: if (log.isInfoEnabled()) {
0864: log.info("Starting job handler(s)");
0865: }
0866:
0867: String oneConfigKey = null;
0868:
0869: // Iterate through each DB config
0870: for (Enumeration e = getAllConfigKeys(); e.hasMoreElements();) {
0871: oneConfigKey = (String) e.nextElement();
0872:
0873: // Retrieve the property setting for the DB config
0874: if (!getContext(oneConfigKey).startJobHandler()) {
0875: log
0876: .warn("Job handler for configuration '"
0877: + oneConfigKey
0878: + "' not enabled (because of the setting in expresso-config.xml).");
0879: } else {
0880: if (log.isInfoEnabled()) {
0881: log.info("Job handler for configuration '"
0882: + oneConfigKey + "' starting...");
0883: }
0884:
0885: /* We do an inner "try" here so that if one job handler */
0886: /* can't start the whole system doesn't fail */
0887: try {
0888: JobHandler ts = new JobHandler(oneConfigKey);
0889: ts.setDaemon(true);
0890:
0891: // Start a thread for the JobHandler Job
0892: ts.start();
0893: jobHandlers.put(oneConfigKey, ts);
0894: if (log.isInfoEnabled()) {
0895: log.info("Job handler for '" + oneConfigKey
0896: + "' running.");
0897: }
0898: } catch (DBException de) {
0899: log.error(
0900: "Job handler start failed for config key '"
0901: + oneConfigKey
0902: + "'. Jobs for this config will "
0903: + "will not be run.", de);
0904: } catch (ServerException se) {
0905: log
0906: .error(
0907: "Job handler start failed for config key ' "
0908: + oneConfigKey
0909: + "'. Jobs for this config will will "
0910: + "not be run.", se);
0911: }
0912: }
0913: } /* for each config key */
0914:
0915: if (log.isInfoEnabled()) {
0916: log.info("All job handlers started");
0917: }
0918: } /* startJobHandler() */
0919:
0920: /**
0921: * Stops all job handlers
0922: *
0923: * @throws ConfigurationException if there's an error getting the config
0924: * information beans.
0925: */
0926: protected void stopJobHandler() throws ConfigurationException {
0927: if (log.isInfoEnabled()) {
0928: log.info("Stops job handler(s)");
0929: }
0930:
0931: String oneConfigKey = null;
0932:
0933: // Iterate through each DB config
0934: for (Enumeration e = getAllConfigKeys(); e.hasMoreElements();) {
0935: oneConfigKey = (String) e.nextElement();
0936:
0937: // Retrieve the property setting for the DB config
0938: if (getContext(oneConfigKey).startJobHandler()) {
0939: if (log.isInfoEnabled()) {
0940: log.info("Job handler for configuration '"
0941: + oneConfigKey + "' interrupting...");
0942: }
0943:
0944: /* We do an inner "try" here so that if one job handler */
0945:
0946: /* can't start the whole system doesn't fail */
0947: JobHandler ts = (JobHandler) jobHandlers
0948: .get(oneConfigKey);
0949:
0950: if (ts != null) {
0951: ts.shutDown();
0952: }
0953:
0954: // Start a thread for the JobHandler Job
0955: }
0956: } /* for each config key */
0957:
0958: if (log.isInfoEnabled()) {
0959: log.info("All job handlers interrupted");
0960: }
0961: }
0962:
0963: /**
0964: * Set the "Web application directory" - this is used for translating
0965: * the %web-app% 'macro' that can be used in property and setup
0966: * values
0967: *
0968: * @param newDir the new directory for the webAppDirectory 'environment
0969: * variable'
0970: */
0971: public static void setWebAppDir(String newDir) {
0972: SystemMacros.getInstance().setWebAppDir(newDir);
0973: } /* setWebAppDir(String) */
0974:
0975: /**
0976: * Set the "context path" - this is used for translating
0977: * the %context% 'macro' that can be used in property and setup
0978: * values
0979: *
0980: * @param newContextPath the new contextPath value to use
0981: */
0982: public static void setContextPath(String newContextPath) {
0983: SystemMacros.getInstance().setContextPath(newContextPath);
0984: } /* setContextPath(String) */
0985:
0986: /**
0987: * set the controller factory to use.
0988: *
0989: * @param cf the new Controller Factory to use for the running system.
0990: * @see com.jcorporate.expresso.core.controller.ExpressoActionServlet for
0991: * an example use of this.
0992: */
0993: public synchronized static void setControllerFactory(
0994: ControllerFactory cf) {
0995: controllerFactory = cf;
0996: }
0997:
0998: /**
0999: * Get the web-app context path for this web application
1000: *
1001: * @return the context path string.
1002: */
1003: public static String getContextPath() {
1004: if (!isInitialized()) {
1005: throw new IllegalArgumentException(
1006: "ConfigManager not initialized");
1007: }
1008:
1009: return SystemMacros.getInstance().getContextPath();
1010: } /* getContextPath() */
1011:
1012: /**
1013: * Called by the initial load servlet to initialize the entire system
1014: *
1015: * @param c The servlet engine configuration
1016: * @throws ServletException Servlet exception if an error occurs initializing
1017: * the configuration system.
1018: */
1019: public static synchronized void config(ServletConfig c)
1020: throws ServletException {
1021:
1022: /* If we've already failed to configure, don't try again */
1023: if (configurationFailed) {
1024: throw new ServletException(
1025: "ConfigManager: Configuration has already been attempted and has failed - cannot re-run");
1026: }
1027:
1028: if (c == null) {
1029: ServletException se = new ServletException(
1030: "ConfigManager: ServletConfig may not be null");
1031: setConfigurationFailureException(se);
1032: throw se;
1033: }
1034: /* We initialize the default schema object here specifically in order */
1035: /* for it to do it's "version checking" against dependant packages */
1036:
1037: try {
1038: ServletContext sc = c.getServletContext();
1039: servletAPIVersion = Integer.toString(sc.getMajorVersion())
1040: + "_" + Integer.toString(sc.getMinorVersion());
1041: // setupLog.info("ConfigManager: System running servlet API " +
1042: // servletAPIVersion);
1043: configDir = StringUtil.notNull(c
1044: .getInitParameter("configDir"));
1045:
1046: if (configDir.equals("")) {
1047: configDir = StringUtil.notNull(sc
1048: .getInitParameter("configDir"));
1049: }
1050: if (configDir.equals("")) {
1051: ServletException se = new ServletException(
1052: "ConfigManager: No 'configDir' initial "
1053: + "parameter was read - unable to initialize. "
1054: + "Check web.xml to ensure the configDir parameter is set "
1055: + "to a non-blank value");
1056: setConfigurationFailureException(se);
1057: throw se;
1058: }
1059:
1060: String rootDir = StringUtil.notNull(sc.getRealPath("/"));
1061:
1062: // if (setupLog.isInfoEnabled()) {
1063: // setupLog.info("ConfigManager: Context root (webAppDir) is '" +
1064: // rootDir + "'");
1065: // }
1066:
1067: if (rootDir.equals("")) {
1068: // setupLog.info("Deploying inside a packed war file. Relative File URLs will throw Exceptions");
1069: rootDir = System.getProperty("expresso.home", "");
1070: if (rootDir.length() == 0) {
1071: log
1072: .warn("Deployed inside WAR file and no expresso.home "
1073: + "directory set. %WEB-APP% will expand to null");
1074: } else {
1075: configDir = FileUtil.makeAbsolutePath(rootDir,
1076: configDir);
1077:
1078: if (!('/' == configDir.charAt(0))) {
1079: configDir = "/" + configDir;
1080: }
1081:
1082: // setupLog.info("ConfigManager: Config dir is now '" +
1083: // configDir + "'");
1084: setWebAppDir(rootDir);
1085: }
1086: } else {
1087: configDir = FileUtil.makeAbsolutePath(rootDir,
1088: configDir);
1089:
1090: if (!('/' == configDir.charAt(0))) {
1091: configDir = "/" + configDir;
1092: }
1093:
1094: // setupLog.info("ConfigManager: Config dir is now '" +
1095: // configDir + "'");
1096:
1097: // protect against installation in "Program Files" directory
1098: if (configDir.indexOf(' ') != -1) {
1099: // setupLog.warn("Bad name for installation path: Reinstall in directory without a space in name.");
1100: System.err
1101: .println("Bad name for installation path: Reinstall in directory without a space in name.");
1102: }
1103: setWebAppDir(rootDir);
1104: }
1105:
1106: initLogManager(c);
1107:
1108: load(configDir);
1109: } catch (Throwable thrown) {
1110: if (log != null) {
1111: log.error(thrown);
1112: }
1113: setConfigurationFailureException(thrown);
1114: System.err
1115: .println("ConfigManager: Expresso configuration encountered an exception:");
1116: thrown.printStackTrace(System.err);
1117: configurationFailed = true;
1118: throw new ServletException(thrown);
1119: }
1120: }
1121:
1122: /**
1123: * Initialize Log Manager based upon the LogDirectory.
1124: *
1125: * @param sc the servlet configuration.
1126: */
1127: private static void initLogManager(ServletConfig sc) {
1128: String configDir = sc.getServletContext().getInitParameter(
1129: "configDir");
1130: String logDir = sc.getServletContext().getInitParameter(
1131: LOG_DIR_PARAM_NAME);
1132: String logConfig = null;
1133:
1134: if (!('/' == configDir.charAt(0))) {
1135: configDir = getWebAppDir() + configDir;
1136: }
1137:
1138: if (logDir != null && logDir.length() > 0
1139: && !('/' == logDir.charAt(0))) {
1140: logDir = getWebAppDir() + logDir;
1141: }
1142: //
1143: //expressoLogging can be initialized with or without a log directory
1144: //or a config dir directory. If log4j.xml exists in the classpath, the
1145: //system will initialize with that.
1146: //
1147: if (configDir != null && configDir.length() > 0) {
1148: logConfig = configDir + "/expressoLogging.xml";
1149: java.io.File f = new java.io.File(logConfig);
1150: if (f == null || !f.exists()) {
1151: logConfig = null;
1152: }
1153: }
1154:
1155: new LogManager(logConfig, logDir);
1156: }
1157:
1158: /**
1159: * "Second stage" configuration. Programs not running in the servlet
1160: * environment can call this method with a configuration directory
1161: * directly in order to set up Expresso. In a servlet environment, load
1162: * gets called from "config" above.
1163: *
1164: * @param theConfigDir The directory to load all config files from.
1165: */
1166: public static synchronized void load(String theConfigDir)
1167: throws DBException, ConfigurationException {
1168:
1169: StringUtil.assertNotBlank(theConfigDir,
1170: "No configuration directory specified");
1171: Logger.getLogger(ConfigManager.class); // todo remove this?
1172: ConfigManager.configDir = theConfigDir;
1173:
1174: ConfigManager instance = ConfigManager.getInstance();
1175: instance.readXMLConfig(configDir);
1176:
1177: // note: logging manager & directory handled elsewhere (servlet params) now
1178:
1179: //initialize the db pool
1180: if (log.isInfoEnabled()) {
1181: log.info("Initializing connection pool(s)");
1182: }
1183: ConfigManager.dbInitialize();
1184:
1185: //Read the DBOtherMap entries into memory
1186: ConfigManager.mapOtherDBs();
1187:
1188: /* read - or re-read - the setup values */
1189: if (log.isInfoEnabled()) {
1190: log.info("Reading setup values");
1191: }
1192: Setup.readSetups();
1193:
1194: if (log.isInfoEnabled()) {
1195: log.info("Initializing Schema Objects");
1196: }
1197:
1198: initializeAllDBObjects();
1199:
1200: com.jcorporate.expresso.core.dbobj.NextNumber.getInstance();
1201: CacheManager.getInstance();
1202:
1203: //Job Handler starting is the very last thing we want to do since dead
1204: //jobs CAN come to life while we're still trying to get everything up
1205: //and running.
1206: //
1207: // Start JobHandler thread(s)
1208: if (log.isInfoEnabled()) {
1209: log.info("Starting job handler(s)");
1210: }
1211: ConfigManager.startJobHandler();
1212: if (log.isInfoEnabled()) {
1213: log.info("Expresso initialization complete");
1214: }
1215: } /* load */
1216:
1217: /**
1218: * Method to "expand" some simple "macro" codes allowed in
1219: * property file and Setup values.
1220: *
1221: * @param propValue The 'property value' to expand.
1222: * @return The 'expanded' value of the property value
1223: */
1224: public static String expandValue(String propValue) {
1225: return SystemMacros.getInstance().expandValue(propValue);
1226: } /* expandValue(String) */
1227:
1228: /**
1229: * Return the pathname of the configuration directory (specified
1230: * as "configDir"
1231: *
1232: * @return The configuration directory that is used by expresso
1233: */
1234: public static String getConfigDir() {
1235: return configDir;
1236: } /* getConfigDir() */
1237:
1238: /**
1239: * Returns the controller factory object. Instantiates the default
1240: * controller factory if one doesn't exist.
1241: *
1242: * @return a ControllerFactory object to use for instantiating controllers
1243: */
1244: public static synchronized ControllerFactory getControllerFactory() {
1245: if (controllerFactory == null) {
1246: controllerFactory = new com.jcorporate.expresso.core.controller.DefaultControllerFactory();
1247: }
1248:
1249: return controllerFactory;
1250: }
1251:
1252: /**
1253: * Get the cached "other db" location for a specific object
1254: * Creation date: (1/5/01 6:57:06 PM)
1255: * author: Adam Rossi, PlatinumSolutions
1256: *
1257: * @param dbName java.lang.String
1258: * @param objectName the name to located
1259: * @return A String giving the data context for the other location
1260: */
1261: public static String getOtherDbLocation(String dbName,
1262: String objectName) {
1263: FastStringBuffer fsb = FastStringBuffer.getInstance();
1264: try {
1265: fsb.append(dbName);
1266: fsb.append("|");
1267: fsb.append(objectName);
1268: return (String) dbOtherMap.get(fsb.toString());
1269: } finally {
1270: fsb.release();
1271: }
1272: } /* getOtherDbLocation(String) */
1273:
1274: /**
1275: * Return a cloned Hashtable containing all of the DBOtherMap entries
1276: * author Adam Rossi, PlatinumSolutions
1277: *
1278: * @return java.util.Hashtable
1279: */
1280: public static Hashtable getOtherDBLocations() {
1281: return (Hashtable) dbOtherMap.clone();
1282: }
1283:
1284: /**
1285: * Map otherdb locations into a hashtable stored in memory.
1286: * <p/>
1287: * Creation date: (1/5/01 6:48:11 PM)
1288: * author: Adam Rossi, PlatinumSolutions
1289: *
1290: * @throws ConfigurationException if there is an error mapping these other
1291: * databases.
1292: */
1293: public static synchronized void mapOtherDBs()
1294: throws ConfigurationException {
1295: String oneKey = "";
1296: dbOtherMap.clear(); //Clear it since we may need to read.
1297:
1298: for (Enumeration ek = getAllConfigKeys(); ek.hasMoreElements();) {
1299: oneKey = (String) ek.nextElement();
1300:
1301: ConfigContext oneContext = getContext(oneKey);
1302:
1303: if (oneContext.hasSetupTables() && oneContext.isActive()) {
1304: if (log.isInfoEnabled()) {
1305: log
1306: .info("Reading DBObject mappings to other databases, context '"
1307: + oneKey + "'...");
1308: }
1309: //This sets thread local variables with the local registry settings.
1310: //We set it as a superuser instance for initialization purposes
1311: //only. Once the first requests come through, we initialize it
1312: //through the Filter.
1313: new MutableRequestRegistry(oneKey, SuperUser.SUPER_USER);
1314:
1315: try {
1316: SchemaList sl = new SchemaList(
1317: SecuredDBObject.SYSTEM_ACCOUNT);
1318: sl.setDataContext(oneKey);
1319: sl.count();
1320: } catch (DBException e) {
1321: if (log.isInfoEnabled()) {
1322: log
1323: .info("Context: "
1324: + oneKey
1325: + " does not have a SchemaList yet. Skipping for now");
1326: continue;
1327: }
1328: }
1329:
1330: int i = 0;
1331:
1332: try {
1333: DBOtherMap otherDB = new DBOtherMap();
1334: otherDB.setDataContext(oneKey);
1335:
1336: DBOtherMap oneOtherDB = null;
1337: FastStringBuffer fsb = FastStringBuffer
1338: .getInstance();
1339: try {
1340: for (Iterator allOtherDB = otherDB
1341: .searchAndRetrieveList().iterator(); allOtherDB
1342: .hasNext();) {
1343: oneOtherDB = (DBOtherMap) allOtherDB.next();
1344: fsb.append(oneKey);
1345: fsb.append("|");
1346: fsb
1347: .append(oneOtherDB
1348: .getField("DBObjName"));
1349: dbOtherMap.put(fsb.toString(), oneOtherDB
1350: .getField("DBConnName"));
1351: fsb.clear();
1352: i++;
1353: } /* for each mapping entry found in this context */
1354: } finally {
1355: fsb.release();
1356: }
1357:
1358: if (log.isInfoEnabled()) {
1359: log
1360: .info("Added "
1361: + i
1362: + " entries to the DBObject Other Database Map.");
1363: }
1364: } catch (DBException de) {
1365: if (oneKey.equalsIgnoreCase(TestSystemInitializer
1366: .getTestContext())) {
1367: log
1368: .warn("Didn't read test database mapping context: "
1369: + de.getMessage());
1370: } else {
1371: log.error(
1372: "Unable to read database mapping entries for context '"
1373: + oneKey + "'", de);
1374: }
1375: }
1376: } else { /* if this context has the standard tables */
1377: if (log.isInfoEnabled()) {
1378: log
1379: .info("DB/Context '"
1380: + oneKey
1381: + "' is not an Expresso database, or is not active - not reading mapping entries from this context");
1382: }
1383: }
1384: } /* for each context */
1385:
1386: } /* mapOtherDBs() */
1387:
1388: /**
1389: * Re-read all properties and other values, re-initialize everything
1390: *
1391: * @param req The servlet request to use
1392: * @param c The servlet config handed to us in the init() method.
1393: */
1394: public static void reInitialize(HttpServletRequest req,
1395: ServletConfig c) throws ServletException {
1396: try {
1397: DBConnectionPool.reInitialize();
1398: checkInitialized(req, c);
1399: } catch (DBException de) {
1400: System.err.println("ConfigManager: Error re-initializing:");
1401: de.printStackTrace(System.err);
1402: }
1403:
1404: } /* reInitialize(HttpServletRequest, ServletConfig) */
1405:
1406: /**
1407: * Check if the configuration info needs to be read, and read
1408: * it if so.<br>
1409: * Immediately returns if the config manager has already been
1410: * initialized successfully.<br>
1411: * Any servlet can check this to make sure Expresso has been
1412: * started up successfully - if not, it calls load as needed
1413: * to perform/re-perform the startup.
1414: *
1415: * @param req The servlet request given by the servlet container
1416: * @param c The servlet configuration
1417: */
1418: public static void checkInitialized(HttpServletRequest req,
1419: ServletConfig c) throws ServletException {
1420:
1421: // If properties have been defined, Expresso must have been initialized once
1422: // Otherwise, call the config method of ConfigManager to do the actuall init.
1423: // of Expresso.
1424: if (!isInitialized()) {
1425: System.err
1426: .println("ConfigManager: Expresso was not initialized - initializing now");
1427: config(c);
1428: }
1429:
1430: setRequest(req);
1431: } /* checkInitialized(HttpServletRequest, ServletConfig) */
1432:
1433: /**
1434: * This function is used by webservers to set global variables such as
1435: * server prefix, or context path. This is usually set by checkLogin(),
1436: * or any other first pages that are reached.
1437: *
1438: * @param req a HttpServletRequest
1439: */
1440: public static synchronized void setRequest(HttpServletRequest req) {
1441: if (myRequest == null) {
1442: myRequest = req;
1443: SystemMacros sm = SystemMacros.getInstance();
1444: sm.setContextPath(GenericDispatcher.getContextPath(req));
1445: sm.setServerPrefix(req.getServerName() + ":"
1446: + req.getServerPort());
1447: }
1448: }
1449:
1450: //////////////////////////////////////////////////////////////////////
1451: // START OF STRUTS 1.1 INTEGRATION
1452: //////////////////////////////////////////////////////////////////////
1453:
1454: /**
1455: * Store the action mappings per module to allow fast reverse based
1456: * lookup based on the controller name.
1457: * <p/>
1458: * <p/>
1459: * It is possible that the same controller is used across
1460: * action mappings and also across module (sub applications). So
1461: * this data structure takes account of the multiple mappings to
1462: * module names and save a list of possible action mappings
1463: * related to a controller class name.
1464: * </p>
1465: * <p/>
1466: * <p/>
1467: * <b>PLEASE NOTE</b> from Struts 1.1 the old
1468: * <code>org.apache.struts.action.ActionMapping</code> is deprecated
1469: * and has been replaced with <code>org.apache.struts.config.ActionConfig</code>
1470: * which is part of <code>org.apache.struts.config.ModuleConfig</code>
1471: * <p/>
1472: * </p>
1473: */
1474: public static void storeModuleActionConfig(ModuleConfig moduleConfig) {
1475: String prefixName = moduleConfig.getPrefix();
1476: ActionConfig actionConfig[] = moduleConfig.findActionConfigs();
1477: if (log.isDebugEnabled()) {
1478: log.debug("ConfigManager.saveModuleActionConfig() prefix=`"
1479: + prefixName + "'");
1480: }
1481:
1482: synchronized (mapModuleMapping) {
1483: Map mapMappings = new HashMap();
1484: for (int j = 0; j < actionConfig.length; ++j) {
1485: String controllerName = actionConfig[j].getType();
1486: List list = (List) mapMappings.get(controllerName);
1487: if (list == null) {
1488: list = new ArrayList();
1489: }
1490: list.add(actionConfig[j]);
1491: mapMappings.put(controllerName, list);
1492: if (log.isDebugEnabled()) {
1493: log.debug(" " + controllerName + " => { `"
1494: + actionConfig[j].getPath() + "' "
1495: + "name:`" + actionConfig[j].getName()
1496: + "' " + "scope:`"
1497: + actionConfig[j].getScope() + "' "
1498: + "input:`" + actionConfig[j].getInput()
1499: + "' " + "attribute:`"
1500: + actionConfig[j].getAttribute() + "' "
1501: + "parameter:`"
1502: + actionConfig[j].getParameter() + "' "
1503: + "validate:`"
1504: + actionConfig[j].getValidate() + "' "
1505: + "}");
1506: }
1507: }
1508:
1509: mapModuleMapping.put(prefixName, mapMappings);
1510: }
1511: }
1512:
1513: /**
1514: * Gets the action mapping associated with the controller and default root module.
1515: * Perform a 'reverse-mapping', that is, locate a Struts action mapping
1516: * by looking for the given controller name (and optional state name)
1517: *
1518: * @param controllerName the classname of the controller to look up.
1519: * @param stateName the name of the state to lookup within that controller
1520: * @return the ActionConfig associated with the parameters specified
1521: * @see #getActionConfig( String,String,String )
1522: */
1523: public static ActionConfig getActionConfig(String controllerName,
1524: String stateName) {
1525: return getActionConfig("", controllerName, stateName);
1526: }
1527:
1528: /**
1529: * Gets the action mapping associated with the controller and the module name.
1530: * Perform a 'reverse-mapping', that is, locate a Struts action mapping
1531: * by looking for the given controller name (and optional state name).
1532: * If the stateName is <code>null</code> this method will attempt to
1533: * dynamically load the controller class, instantiate an object instance
1534: * and retrieve the controller class's initial state.
1535: * <p/>
1536: * <p/>
1537: * <p/>
1538: * The action mapping is determined by looking at
1539: * <code>ActionConfig</code> records in Struts configuration,
1540: * retrieving all the <em>local</em> action forward and comparing
1541: * its name to the state forward. This means that in your Struts
1542: * XML configuration you must define a local action forward with
1543: * the same name as the state Method.
1544: * <p/>
1545: * </p>
1546: * <p/>
1547: * <p/>
1548: * <p/>
1549: * If no action mapping can be determined by�looking for a
1550: * particular matching local action forward, then the first action
1551: * mapping is returned if exists. Please note the first action
1552: * mapping is not necessarily the first action mapping declared in
1553: * the XML configuration. This cannot be guaranteed, because the
1554: * implementation may changed in the future.
1555: * <p/>
1556: * </p>
1557: * <p/>
1558: * <pre>
1559: * <action path="/Register"
1560: * type="com.jcorporate.expresso.services.controller.SimpleRegistration"
1561: * name="default" scope="request" validate="false" >
1562: * <forward name="showDBMenu"
1563: * path="/expresso/jsp/register/dbmenu.jsp" />
1564: * <forward name="promptAddRecord"
1565: * path="/expresso/jsp/register/regAdd.jsp" />
1566: * <forward name="promptUpdateRecord"
1567: * path="/expresso/jsp/register/regAdd.jsp" />
1568: * ...
1569: * </action>
1570: * <pre>
1571: * <p/>
1572: * <p/>
1573: * In order for the above action mapping "/Register" to be returned then
1574: * you need to declare a <em>unique</em> local action forward name, if you
1575: * use the same controller class for multiple actions. For example "showDBMenu"
1576: * could be the unique local forward.
1577: * </p>
1578: *
1579: * @param moduleName the Struts module name
1580: * @param controllerName the classname of the controller to look up.
1581: * @param stateName the name of the state to lookup within that controller
1582: * @return the ActionConfig associated with the parameters specified
1583: * @see #storeModuleActionConfig( ModuleConfig moduleConfig)
1584: */
1585: public static ActionConfig getActionConfig(String moduleName,
1586: String controllerName, String stateName) {
1587: if (log.isDebugEnabled()) {
1588: log.debug("CF.getActionConfig() moduleName=`" + moduleName
1589: + "', controllerName=`" + controllerName
1590: + "', stateName=`" + stateName + "'");
1591: }
1592:
1593: if (moduleName == null) {
1594: throw new IllegalArgumentException(
1595: "ConfigManager.getActionMapping(): "
1596: + "parameter moduleName cannot be null");
1597: }
1598: if (controllerName == null) {
1599: throw new IllegalArgumentException(
1600: "ConfigManager.getActionMapping(): "
1601: + "parameter controllerName cannot be null");
1602: }
1603:
1604: if (stateName == null || stateName.length() == 0) {
1605: try {
1606: com.jcorporate.expresso.core.controller.Controller c = ConfigManager
1607: .getControllerFactory().getController(
1608: moduleName, controllerName);
1609:
1610: stateName = c.getInitialState();
1611: if (stateName == null || stateName.length() == 0) {
1612: throw new IllegalArgumentException(
1613: "ConfigManager.getMapping(): "
1614: + "stateName was null and there is no defined initial state for: "
1615: + controllerName);
1616: }
1617: if (log.isDebugEnabled()) {
1618: log.debug("using initial state =`" + stateName
1619: + "'");
1620: }
1621: } catch (ControllerException ex) {
1622: throw new RuntimeException(
1623: "ConfigManager.getMapping(): "
1624: + "stateName was null and can't construct controller of name: "
1625: + controllerName, ex);
1626: } catch (ClassCastException ex) {
1627: log.error("Error getting controller", ex);
1628: throw new IllegalArgumentException(
1629: "ClassCastException getting" + " controller: "
1630: + ex.toString());
1631: }
1632: }
1633:
1634: synchronized (mapModuleMapping) {
1635: Map mapMappings = (Map) mapModuleMapping.get(moduleName);
1636: if (mapMappings != null) {
1637: List list = (List) mapMappings.get(controllerName);
1638: if (list != null) {
1639: for (int j = 0; j < list.size(); ++j) {
1640: ActionConfig oneConfig = (ActionConfig) list
1641: .get(j);
1642: if (StringUtil
1643: .notNull(oneConfig.getParameter())
1644: .equals(stateName)) {
1645: if (log.isDebugEnabled()) {
1646: log
1647: .debug("CM.getActionConfig() *FOUND* parameter=`"
1648: + oneConfig
1649: .getParameter()
1650: + "' actionConfig:"
1651: + oneConfig.getName()
1652: + ","
1653: + oneConfig.getPath());
1654: }
1655: return oneConfig;
1656: }
1657:
1658: ForwardConfig aForward = findForwardConfig(
1659: oneConfig, stateName);
1660: if (aForward != null) {
1661: if (log.isDebugEnabled()) {
1662: log
1663: .debug("CM.getActionConfig() *FOUND* forwards=`"
1664: + aForward.getName()
1665: + "',`"
1666: + aForward.getPath()
1667: + "' actionConfig:"
1668: + oneConfig.getName()
1669: + ","
1670: + oneConfig.getPath());
1671: }
1672: return oneConfig;
1673: }
1674: }
1675:
1676: // If we still have not found an action mapping
1677: // then we return the first one on the list and
1678: // assume this will be correct most of the time.
1679: if (list.size() > 0) {
1680: ActionConfig oneConfig = (ActionConfig) list
1681: .get(0);
1682: if (log.isDebugEnabled()) {
1683: log
1684: .debug("CM.getActionConfig() *FOUND* using the FIRST actionConfig:"
1685: + oneConfig.getName()
1686: + ","
1687: + oneConfig.getPath());
1688: }
1689: return oneConfig;
1690: }
1691: }
1692: }
1693: }
1694:
1695: return (null);
1696: }
1697:
1698: /**
1699: * Find a forward config given an action config and a state name Does not
1700: * return higher level forwards, just the one for the given state IF it exists
1701: *
1702: * @param oneConfig the ActionConfig for the controller
1703: * @param stateName the state name for the controller
1704: * @return ForwardConfig instance for that parameter combination
1705: */
1706: public static final ForwardConfig findForwardConfig(
1707: ActionConfig oneConfig, String stateName) {
1708:
1709: ForwardConfig forwards[] = oneConfig.findForwardConfigs();
1710: for (int k = 0; k < forwards.length; ++k) {
1711: if (forwards[k].getName().equals(stateName)) {
1712: return forwards[k];
1713: }
1714: }
1715:
1716: return null;
1717: }
1718:
1719: /**
1720: * Gets <em>all</em> the action mappings associated with the
1721: * controller and the default module. Perform a
1722: * 'reverse-mapping', that is, locate a Struts action mappings by
1723: * looking for the given controller name.
1724: *
1725: * @param controllerName the classname of the controller to look up.
1726: * @return the ActionConfig associated with the parameters specified
1727: * @see #getActionConfigList( String,String )
1728: */
1729: public static List getActionConfigList(String controllerName) {
1730: return getActionConfigList("", controllerName);
1731: }
1732:
1733: /**
1734: * Gets <em>all</em> the action mappings associated with the controller
1735: * and the module name.
1736: * Perform a 'reverse-mapping', that is, locate a Struts action mapping
1737: * by looking for the given controller name.
1738: *
1739: * @param moduleName the Struts module name
1740: * @param controllerName the classname of the controller to look up.
1741: * @return the ActionConfig list associated with the parameters specified
1742: * @see #storeModuleActionConfig( ModuleConfig moduleConfig)
1743: */
1744: public static List getActionConfigList(String moduleName,
1745: String controllerName) {
1746: if (moduleName == null) {
1747: throw new IllegalArgumentException(
1748: "ConfigManager.getActionConfigList(): "
1749: + "parameter moduleName cannot be null");
1750: }
1751: if (controllerName == null) {
1752: throw new IllegalArgumentException(
1753: "ConfigManager.getActionConfigList(): "
1754: + "parameter controllerName cannot be null");
1755: }
1756:
1757: List result = new ArrayList();
1758:
1759: synchronized (mapModuleMapping) {
1760: Map mapMappings = (Map) mapModuleMapping.get(moduleName);
1761: if (mapMappings != null) {
1762: List mappings = (List) mapMappings.get(controllerName);
1763: if (mappings != null) {
1764: // Protect the internal data structure: always
1765: // return a copy of the list.
1766: result.addAll(mappings);
1767: }
1768: }
1769: }
1770:
1771: return result;
1772: }
1773:
1774: /**
1775: * Perform a 'reverse-mapping', that is, locate a Struts action mapping
1776: * by looking for the given controller name (and optional state name)
1777: *
1778: * @param controllerName the classname of the controller to look up.
1779: * @param stateName the name of the state to lookup within that controller
1780: * @return the ActionMapping associated with the parameters specified
1781: * @deprecated this method is now deprecated and does no anything since Struts 1.1
1782: * {@link #getActionConfig(String moduleName, String controllerName, String stateName )}
1783: */
1784: public static ActionMapping getMapping(String controllerName,
1785: String stateName) {
1786: ActionMapping mapping = null;
1787: ActionConfig config = getActionConfig("", controllerName,
1788: stateName);
1789: if (config != null) {
1790: // Because `org.apache.struts.action.ActionMapping' is a
1791: // direct subclass of
1792: // `org.apache.struts.action.util.ActionConfig' we can use
1793: // the common beans utils to copy the properties from one
1794: // to the other easily.
1795: mapping = new ActionMapping();
1796: try {
1797: BeanUtils.copyProperties(mapping, config);
1798: } catch (Exception e) {
1799: log.error("BeanUtils failed to copy properties", e);
1800: e.printStackTrace();
1801: }
1802: }
1803:
1804: return mapping;
1805: } /* getMapping(String controllerName, String stateName) */
1806:
1807: //////////////////////////////////////////////////////////////////////
1808: // END OF STRUTS 1.1 INTEGRATION
1809: //////////////////////////////////////////////////////////////////////
1810:
1811: /**
1812: * Read the Expresso-config.xml file, populating the configuration tree as we go
1813: * <p/>
1814: * This method utilizes the Strut's XML digester to perform it's configuration
1815: * readings. When Struts 1.1 is eventually integrated, the package will move
1816: * to apache.commons package.
1817: *
1818: * @param configDir The directory that the expresso-config.xml resides in.
1819: * @throws ConfigurationException if something goes wrong in reading the XML
1820: * file.
1821: */
1822: private void readXMLConfig(String configDir)
1823: throws ConfigurationException {
1824: Logger setupLog = Logger.getLogger(ConfigManager.class);
1825: setupLog.info("ConfigManager: Reading XML config");
1826:
1827: setSAXParser();
1828:
1829: Digester digester = new Digester();
1830: URL url = ConfigManager.class
1831: .getResource(EXPRESSO_DTD_COPY_LOCATION);
1832:
1833: if (url != null) {
1834: digester
1835: .register(
1836: "-//Jcorporate Ltd//DTD Expresso Configuration 4.0//EN",
1837: url.toString());
1838: } else {
1839: ConfigurationException ce = new ConfigurationException(
1840: "ConfigManager: Unable to get URL to the expresso-config dtd from: "
1841: + EXPRESSO_DTD_COPY_LOCATION
1842: + " relative to classes directory (DTD should be copied there).");
1843: setConfigurationFailureException(ce);
1844: throw ce;
1845: }
1846:
1847: myConfig = new ConfigExpresso();
1848:
1849: ConfigErrorHandler myHandler = new ConfigErrorHandler();
1850: digester.setErrorHandler(myHandler);
1851: digester.setUseContextClassLoader(true);
1852: // ClassLoader cl = ConfigManager.class.getClassLoader();
1853: // if (cl != null) {
1854: // digester.setClassLoader(ConfigManager.class.getClassLoader());
1855: // } else {
1856: // digester.setClassLoader(Thread.currentThread().getContextClassLoader());
1857: // }
1858: // digester.setDebug(9); // is a no-op in digester v.1.3
1859:
1860: this .setDigesterRules(myConfig, digester);
1861:
1862: FileInputStream fin = null;
1863:
1864: try {
1865: fin = new FileInputStream(configDir
1866: + "/expresso-config.xml");
1867: } catch (FileNotFoundException fe) {
1868: ConfigurationException ce = new ConfigurationException(
1869: "No such file as '" + configDir
1870: + "/expresso-config.xml");
1871: setConfigurationFailureException(ce);
1872: throw ce;
1873: }
1874: try {
1875: digester.parse(fin);
1876: } catch (IOException ie) {
1877: System.err
1878: .println("ConfigManager: IOException reading expresso-config.xml:");
1879: ie.printStackTrace(System.err);
1880: configurationFailed = true;
1881: setConfigurationFailureException(ie);
1882: throw new ConfigurationException(
1883: "IO Exception reading expresso-config.xml");
1884: } catch (SAXException se) {
1885: System.err
1886: .println("ConfigManager: SAXException reading expresso-config.xml:");
1887: se.printStackTrace(System.err);
1888: setConfigurationFailureException(se);
1889:
1890: if (se.getException() != null) {
1891: System.err
1892: .println("ConfigManager: Nested SAX Exception:");
1893: se.getException().printStackTrace(System.err);
1894: }
1895:
1896: configurationFailed = true;
1897: throw new ConfigurationException(
1898: "SAX Exception reading expresso-config.xml");
1899: } catch (IllegalArgumentException ia) {
1900: configurationFailed = true;
1901: setConfigurationFailureException(ia);
1902: throw new ConfigurationException(
1903: "Illegal Setup Value Specified", ia);
1904: } finally {
1905: if (fin != null) {
1906: try {
1907: fin.close();
1908: } catch (IOException ex) {
1909: setupLog.error("Error closing file input stream",
1910: ex);
1911: }
1912: }
1913: }
1914:
1915: digester = null;
1916: System.gc(); //Digester is an expensive memory allocation, clean up now.
1917:
1918: //Output any errors or warnings.
1919: if (myHandler.anyErrorsOrWarnings()) {
1920: Exception oneException = null;
1921: Vector warnings = myHandler.getWarnings();
1922:
1923: if (warnings.size() > 0) {
1924: System.err.println("ConfigManager: XML warnings:");
1925:
1926: for (Enumeration ee2 = warnings.elements(); ee2
1927: .hasMoreElements();) {
1928: oneException = (Exception) ee2.nextElement();
1929: oneException.printStackTrace(System.err);
1930: setConfigurationFailureException(oneException);
1931: }
1932: } /* if any warnings */
1933:
1934: Vector errors = myHandler.getErrors();
1935:
1936: if (errors.size() > 0) {
1937: System.err.println("ConfigManager: XML errors:");
1938:
1939: for (Enumeration ee = errors.elements(); ee
1940: .hasMoreElements();) {
1941: oneException = (Exception) ee.nextElement();
1942: oneException.printStackTrace(System.err);
1943: setConfigurationFailureException(oneException);
1944: }
1945: } /* if any errors */
1946:
1947: Exception fatal = myHandler.getFatalException();
1948:
1949: if (fatal != null) {
1950: System.err
1951: .println("ConfigManager: Fatal XML exception:");
1952: setConfigurationFailureException(oneException);
1953: fatal.printStackTrace(System.err);
1954: }
1955:
1956: configurationFailed = true;
1957: throw new ConfigurationException(
1958: "Unable to parse expresso-config.xml successfully. "
1959: + "Please see your 'system.err' log file for details of the problem");
1960: }
1961:
1962: System.err
1963: .println("ConfigManager: Done reading XML config - no errors or warnings");
1964:
1965: //myConfig.display();
1966:
1967: /* Load the contexts into a hashtable for easy access */
1968: ConfigContext oneContext = null;
1969:
1970: Vector contexts = myConfig.getContexts();
1971: int contextsize = contexts.size();
1972: for (int i = 0; i < contextsize; i++) {
1973: //Remove any non-active contexts while we're at it.
1974: oneContext = (ConfigContext) contexts.elementAt(i);
1975: if (oneContext.isActive() == true) {
1976: allContexts.put(oneContext.getName(), oneContext);
1977: } else {
1978: contexts.removeElementAt(i);
1979: contextsize -= 1;
1980: i--;
1981: }
1982: }
1983:
1984: xmlConfigOk = true;
1985: }
1986:
1987: /**
1988: * Set up the rules for the digester
1989: *
1990: * @param myConfig The root of the bean accepting the digester input
1991: * @param digester an instantiated Digester ready to accept the rules.
1992: */
1993: protected void setDigesterRules(ConfigExpresso myConfig,
1994: Digester digester) {
1995: digester.push(myConfig);
1996:
1997: /* Top-level configuration */
1998: digester.addSetProperties("expresso-config");
1999: digester.addCallMethod("expresso-config/logDirectory",
2000: "setLogDirectory", 0);
2001: digester.addCallMethod("expresso-config/strongCrypto",
2002: "setStrongCrypto", 0);
2003: digester.addCallMethod("expresso-config/cryptoKey",
2004: "setCryptoKey", 0);
2005: digester.addCallMethod("expresso-config/servletAPI",
2006: "setServletAPI", 0);
2007: digester.addCallMethod("expresso-config/encryptMode",
2008: "setEncryptMode", 0);
2009:
2010: digester.addCallMethod("expresso-config/httpPort",
2011: "setHttpPort", 0);
2012: digester.addCallMethod("expresso-config/sslPort", "setSslPort",
2013: 0);
2014:
2015: /* Cache Manager configuration */
2016: digester.addObjectCreate("expresso-config/cacheManager",
2017: "com.jcorporate.expresso.core.misc.ConfigCacheManager");
2018: digester
2019: .addSetProperties("expresso-config/context/cacheManager");
2020: digester.addSetNext("expresso-config/cacheManager",
2021: "addCacheManager",
2022: "com.jcorporate.expresso.core.misc.ConfigCacheManager");
2023:
2024: /* Each class handler */
2025: digester.addObjectCreate(
2026: "expresso-config/class-handlers/class-handler",
2027: "com.jcorporate.expresso.core.misc.ConfigClassHandler");
2028: digester
2029: .addSetProperties("expresso-config/class-handlers/class-handler");
2030: digester.addSetNext(
2031: "expresso-config/class-handlers/class-handler",
2032: "addClassHandler",
2033: "com.jcorporate.expresso.core.misc.ConfigClassHandler");
2034: digester
2035: .addObjectCreate(
2036: "expresso-config/class-handlers/class-handler/handler-parameter",
2037: "com.jcorporate.expresso.core.misc.ConfigClassHandlerParameter");
2038: digester
2039: .addSetProperties("expresso-config/class-handlers/class-handler/handler-parameter");
2040: digester
2041: .addSetNext(
2042: "expresso-config/class-handlers/class-handler/handler-parameter",
2043: "addParameter",
2044: "com.jcorporate.expresso.core.misc.ConfigClassHandlerParameter");
2045:
2046: /* Each context */
2047: digester.addObjectCreate("expresso-config/context",
2048: "com.jcorporate.expresso.core.misc.ConfigContext");
2049: digester.addSetProperties("expresso-config/context");
2050: digester.addCallMethod("expresso-config/context/description",
2051: "setDescription", 0);
2052: digester.addCallMethod("expresso-config/context/images",
2053: "setImages", 0);
2054: digester.addCallMethod(
2055: "expresso-config/context/startJobHandler",
2056: "setStartJobHandler", 0);
2057: digester.addCallMethod(
2058: "expresso-config/context/showStackTrace",
2059: "setShowStackTrace", 0);
2060: digester.addCallMethod("expresso-config/context/mailDebug",
2061: "setMailDebug", 0);
2062: digester.addCallMethod("expresso-config/context/expressoDir",
2063: "setExpressoDir", 0);
2064: digester.addCallMethod(
2065: "expresso-config/context/hasSetupTables",
2066: "setHasSetupTables", 0);
2067: digester.addSetNext("expresso-config/context", "addContext",
2068: "com.jcorporate.expresso.core.misc.ConfigContext");
2069:
2070: /* Jdbc definition within the context */
2071: digester.addObjectCreate("expresso-config/context/jdbc",
2072: "com.jcorporate.expresso.core.misc.ConfigJdbc");
2073: digester.addCallMethod(
2074: "expresso-config/context/jdbc/dbWildcard",
2075: "addWildcard", 0);
2076: digester.addSetProperties("expresso-config/context/jdbc");
2077: digester.addSetNext("expresso-config/context/jdbc", "addJdbc",
2078: "com.jcorporate.expresso.core.misc.ConfigJdbc");
2079:
2080: /* Jndi definition within the context/jdbc */
2081: digester.addObjectCreate("expresso-config/context/jdbc/jndi",
2082: "com.jcorporate.expresso.core.misc.ConfigJndi");
2083: digester.addSetProperties("expresso-config/context/jdbc/jndi");
2084: digester.addSetNext("expresso-config/context/jdbc/jndi",
2085: "addJndi",
2086: "com.jcorporate.expresso.core.misc.ConfigJndi");
2087:
2088: /* Path mapping configuration within the Context */
2089: digester.addObjectCreate(
2090: "expresso-config/context/path-mappings/path-mapping",
2091: "com.jcorporate.expresso.core.misc.ConfigPathMapping");
2092: digester
2093: .addSetProperties("expresso-config/context/path-mappings/path-mapping");
2094: digester.addSetNext(
2095: "expresso-config/context/path-mappings/path-mapping",
2096: "addPathMapping",
2097: "com.jcorporate.expresso.core.misc.ConfigPathMapping");
2098: digester
2099: .addCallMethod(
2100: "expresso-config/context/path-mappings/path-mapping/url-pattern",
2101: "setUrlPattern", 0);
2102: digester
2103: .addCallMethod(
2104: "expresso-config/context/path-mappings/path-mapping/path",
2105: "setPath", 0);
2106: digester
2107: .addObjectCreate(
2108: "expresso-config/context/path-mappings/path-mapping/param",
2109: "com.jcorporate.expresso.core.misc.ConfigPathParam");
2110: digester
2111: .addSetNext(
2112: "expresso-config/context/path-mappings/path-mapping/param",
2113: "addParam",
2114: "com.jcorporate.expresso.core.misc.ConfigPathParam");
2115: digester
2116: .addObjectCreate(
2117: "expresso-config/context/path-mappings/path-mapping/fixed-param",
2118: "com.jcorporate.expresso.core.misc.ConfigPathFixedParam");
2119: digester
2120: .addSetNext(
2121: "expresso-config/context/path-mappings/path-mapping/fixed-param",
2122: "addFixedParam",
2123: "com.jcorporate.expresso.core.misc.ConfigPathFixedParam");
2124:
2125: //digester.addCallMethod("expresso-config/context/path-mappings/path-mapping/fixed-param",
2126: // "addFixedParam", 0);
2127: digester
2128: .addCallMethod(
2129: "expresso-config/context/path-mappings/path-mapping/param/param-name",
2130: "setName", 0);
2131: digester
2132: .addCallMethod(
2133: "expresso-config/context/path-mappings/path-mapping/param/param-number",
2134: "setNumber", 0);
2135: digester
2136: .addCallMethod(
2137: "expresso-config/context/path-mappings/path-mapping/fixed-param/param-name",
2138: "setName", 0);
2139: digester
2140: .addCallMethod(
2141: "expresso-config/context/path-mappings/path-mapping/fixed-param/param-value",
2142: "setValue", 0);
2143:
2144: /* LDAP definition within the context */
2145: digester.addObjectCreate("expresso-config/context/ldap",
2146: "com.jcorporate.expresso.core.misc.ConfigLdap");
2147: digester.addSetProperties("expresso-config/context/ldap");
2148: digester.addSetNext("expresso-config/context/ldap", "addLdap",
2149: "com.jcorporate.expresso.core.misc.ConfigLdap");
2150:
2151: /* Setup values default entry */
2152: digester.addObjectCreate(
2153: "expresso-config/context/setupDefault",
2154: "com.jcorporate.expresso.core.misc.ConfigSetupDefault");
2155: digester
2156: .addSetProperties("expresso-config/context/setupDefault");
2157: digester.addSetNext("expresso-config/context/setupDefault",
2158: "addSetupDefault",
2159: "com.jcorporate.expresso.core.misc.ConfigSetupDefault");
2160:
2161: /* Type mappings */
2162: digester.addObjectCreate(
2163: "expresso-config/context/type-mapping",
2164: "com.jcorporate.expresso.core.misc.ConfigTypeMapping");
2165: digester.addSetNext("expresso-config/context/type-mapping",
2166: "addTypeMapping",
2167: "com.jcorporate.expresso.core.misc.ConfigTypeMapping");
2168: digester.addCallMethod(
2169: "expresso-config/context/type-mapping/java-type",
2170: "setJavaType", 0);
2171: digester.addCallMethod(
2172: "expresso-config/context/type-mapping/db-type",
2173: "setDBType", 0);
2174: digester.addCallMethod(
2175: "expresso-config/context/type-mapping/expresso-type",
2176: "setExpressoType", 0);
2177:
2178: /* Custom properties */
2179: digester
2180: .addObjectCreate(
2181: "expresso-config/context/customProperty",
2182: "com.jcorporate.expresso.core.misc.ConfigCustomProperty");
2183: digester
2184: .addSetNext("expresso-config/context/customProperty",
2185: "addCustomProperty",
2186: "com.jcorporate.expresso.core.misc.ConfigCustomProperty");
2187: digester
2188: .addSetProperties("expresso-config/context/customProperty");
2189: digester.addCallMethod(
2190: "expresso-config/context/customProperty/name",
2191: "setName", 0);
2192: digester.addCallMethod(
2193: "expresso-config/context/customProperty/value",
2194: "setValue", 0);
2195: //digester.setDebug(configDebugLevel); // is a no-op in v.1.3 anyway
2196: digester.setValidating(true);
2197:
2198: }
2199:
2200: /*
2201: * Goes through a pre-determined list of SAX parsers,
2202: * the first one found is used to parse XML config files.
2203: */
2204: protected void setSAXParser() {
2205:
2206: //
2207: //Constructor globally sets things for us.
2208: //
2209: new SaxParserConfigurer();
2210: }
2211:
2212: } /* ConfigManager */
|