Source Code Cross Referenced for ActionServlet.java in  » Web-Framework » struts-1.3.8 » org » apache » struts » action » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Framework » struts 1.3.8 » org.apache.struts.action 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $Id: ActionServlet.java 483039 2006-12-06 11:34:28Z niallp $
0003:         *
0004:         * Licensed to the Apache Software Foundation (ASF) under one
0005:         * or more contributor license agreements.  See the NOTICE file
0006:         * distributed with this work for additional information
0007:         * regarding copyright ownership.  The ASF licenses this file
0008:         * to you under the Apache License, Version 2.0 (the
0009:         * "License"); you may not use this file except in compliance
0010:         * with the License.  You may obtain a copy of the License at
0011:         *
0012:         *  http://www.apache.org/licenses/LICENSE-2.0
0013:         *
0014:         * Unless required by applicable law or agreed to in writing,
0015:         * software distributed under the License is distributed on an
0016:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0017:         * KIND, either express or implied.  See the License for the
0018:         * specific language governing permissions and limitations
0019:         * under the License.
0020:         */
0021:        package org.apache.struts.action;
0022:
0023:        import org.apache.commons.beanutils.BeanUtils;
0024:        import org.apache.commons.beanutils.ConvertUtils;
0025:        import org.apache.commons.beanutils.PropertyUtils;
0026:        import org.apache.commons.beanutils.converters.BigDecimalConverter;
0027:        import org.apache.commons.beanutils.converters.BigIntegerConverter;
0028:        import org.apache.commons.beanutils.converters.BooleanConverter;
0029:        import org.apache.commons.beanutils.converters.ByteConverter;
0030:        import org.apache.commons.beanutils.converters.CharacterConverter;
0031:        import org.apache.commons.beanutils.converters.DoubleConverter;
0032:        import org.apache.commons.beanutils.converters.FloatConverter;
0033:        import org.apache.commons.beanutils.converters.IntegerConverter;
0034:        import org.apache.commons.beanutils.converters.LongConverter;
0035:        import org.apache.commons.beanutils.converters.ShortConverter;
0036:        import org.apache.commons.chain.CatalogFactory;
0037:        import org.apache.commons.chain.config.ConfigParser;
0038:        import org.apache.commons.digester.Digester;
0039:        import org.apache.commons.digester.RuleSet;
0040:        import org.apache.commons.logging.Log;
0041:        import org.apache.commons.logging.LogFactory;
0042:        import org.apache.struts.Globals;
0043:        import org.apache.struts.config.ActionConfig;
0044:        import org.apache.struts.config.ConfigRuleSet;
0045:        import org.apache.struts.config.ExceptionConfig;
0046:        import org.apache.struts.config.FormBeanConfig;
0047:        import org.apache.struts.config.FormPropertyConfig;
0048:        import org.apache.struts.config.ForwardConfig;
0049:        import org.apache.struts.config.MessageResourcesConfig;
0050:        import org.apache.struts.config.ModuleConfig;
0051:        import org.apache.struts.config.ModuleConfigFactory;
0052:        import org.apache.struts.config.PlugInConfig;
0053:        import org.apache.struts.util.MessageResources;
0054:        import org.apache.struts.util.MessageResourcesFactory;
0055:        import org.apache.struts.util.ModuleUtils;
0056:        import org.apache.struts.util.RequestUtils;
0057:        import org.xml.sax.InputSource;
0058:        import org.xml.sax.SAXException;
0059:
0060:        import javax.servlet.ServletContext;
0061:        import javax.servlet.ServletException;
0062:        import javax.servlet.UnavailableException;
0063:        import javax.servlet.http.HttpServlet;
0064:        import javax.servlet.http.HttpServletRequest;
0065:        import javax.servlet.http.HttpServletResponse;
0066:
0067:        import java.io.IOException;
0068:        import java.io.InputStream;
0069:
0070:        import java.math.BigDecimal;
0071:        import java.math.BigInteger;
0072:
0073:        import java.net.MalformedURLException;
0074:        import java.net.URL;
0075:        import java.net.URLConnection;
0076:
0077:        import java.util.ArrayList;
0078:        import java.util.Enumeration;
0079:        import java.util.Iterator;
0080:        import java.util.List;
0081:        import java.util.MissingResourceException;
0082:
0083:        /**
0084:         * <p><strong>ActionServlet</strong> provides the "controller" in the
0085:         * Model-View-Controller (MVC) design pattern for web applications that is
0086:         * commonly known as "Model 2".  This nomenclature originated with a
0087:         * description in the JavaServerPages Specification, version 0.92, and has
0088:         * persisted ever since (in the absence of a better name).</p>
0089:         *
0090:         * <p>Generally, a "Model 2" application is architected as follows:</p>
0091:         *
0092:         * <ul>
0093:         *
0094:         * <li>The user interface will generally be created with server pages, which
0095:         * will not themselves contain any business logic. These pages represent the
0096:         * "view" component of an MVC architecture.</li>
0097:         *
0098:         * <li>Forms and hyperlinks in the user interface that require business logic
0099:         * to be executed will be submitted to a request URI that is mapped to this
0100:         * servlet.</li>
0101:         *
0102:         * <li>There can be <b>one</b> instance of this servlet class, which receives
0103:         * and processes all requests that change the state of a user's interaction
0104:         * with the application. The servlet delegates the handling of a request to a
0105:         * {@link RequestProcessor} object. This component represents the "controller"
0106:         * component of an MVC architecture. </li>
0107:         *
0108:         * <li>The <code>RequestProcessor</code> selects and invokes an {@link Action}
0109:         * class to perform the requested business logic, or delegates the response to
0110:         * another resource.</li>
0111:         *
0112:         * <li>The <code>Action</code> classes can manipulate the state of the
0113:         * application's interaction with the user, typically by creating or modifying
0114:         * JavaBeans that are stored as request or session attributes (depending on
0115:         * how long they need to be available). Such JavaBeans represent the "model"
0116:         * component of an MVC architecture.</li>
0117:         *
0118:         * <li>Instead of producing the next page of the user interface directly,
0119:         * <code>Action</code> classes generally return an {@link ActionForward} to
0120:         * indicate which resource should handle the response. If the
0121:         * <code>Action</code> does not return null, the <code>RequestProcessor</code>
0122:         * forwards or redirects to the specified resource (by utilizing
0123:         * <code>RequestDispatcher.forward</code> or <code>Response.sendRedirect</code>)
0124:         * so as to produce the next page of the user interface.</li>
0125:         *
0126:         * </ul>
0127:         *
0128:         * <p>The standard version of <code>RequestsProcessor</code> implements the
0129:         * following logic for each incoming HTTP request. You can override some or
0130:         * all of this functionality by subclassing this object and implementing your
0131:         * own version of the processing.</p>
0132:         *
0133:         * <ul>
0134:         *
0135:         * <li>Identify, from the incoming request URI, the substring that will be
0136:         * used to select an action procedure.</li>
0137:         *
0138:         * <li>Use this substring to map to the Java class name of the corresponding
0139:         * action class (an implementation of the <code>Action</code> interface).
0140:         * </li>
0141:         *
0142:         * <li>If this is the first request for a particular <code>Action</code>
0143:         * class, instantiate an instance of that class and cache it for future
0144:         * use.</li>
0145:         *
0146:         * <li>Optionally populate the properties of an <code>ActionForm</code> bean
0147:         * associated with this mapping.</li>
0148:         *
0149:         * <li>Call the <code>execute</code> method of this <code>Action</code> class,
0150:         * passing on a reference to the mapping that was used, the relevant form-bean
0151:         * (if any), and the request and the response that were passed to the
0152:         * controller by the servlet container (thereby providing access to any
0153:         * specialized properties of the mapping itself as well as to the
0154:         * ServletContext). </li>
0155:         *
0156:         * </ul>
0157:         *
0158:         * <p>The standard version of <code>ActionServlet</code> is configured based
0159:         * on the following servlet initialization parameters, which you will specify
0160:         * in the web application deployment descriptor (<code>/WEB-INF/web.xml</code>)
0161:         * for your application.  Subclasses that specialize this servlet are free to
0162:         * define additional initialization parameters. </p>
0163:         *
0164:         * <ul>
0165:         *
0166:         * <li><strong>config</strong> - Comma-separated list of context-relative
0167:         * path(s) to the XML resource(s) containing the configuration information for
0168:         * the default module.  (Multiple files support since Struts 1.1)
0169:         * [/WEB-INF/struts-config.xml].</li>
0170:         *
0171:         * <li><strong>config/${module}</strong> - Comma-separated list of
0172:         * Context-relative path(s) to the XML resource(s) containing the
0173:         * configuration information for the module that will use the specified prefix
0174:         * (/${module}). This can be repeated as many times as required for multiple
0175:         * modules. (Since Struts 1.1)</li>
0176:         *
0177:         * <li><strong>configFactory</strong> - The Java class name of the
0178:         * <code>ModuleConfigFactory</code> used to create the implementation of the
0179:         * ModuleConfig interface. </li>
0180:         *
0181:         * <li><strong>convertNull</strong> - Force simulation of the Struts 1.0
0182:         * behavior when populating forms. If set to true, the numeric Java wrapper
0183:         * class types (like <code>java.lang.Integer</code>) will default to null
0184:         * (rather than 0). (Since Struts 1.1) [false] </li>
0185:         *
0186:         * <li><strong>rulesets </strong> - Comma-delimited list of fully qualified
0187:         * classnames of additional <code>org.apache.commons.digester.RuleSet</code>
0188:         * instances that should be added to the <code>Digester</code> that will be
0189:         * processing <code>struts-config.xml</code> files.  By default, only the
0190:         * <code>RuleSet</code> for the standard configuration elements is loaded.
0191:         * (Since Struts 1.1)</li>
0192:         *
0193:         * <li><strong>validating</strong> - Should we use a validating XML parser to
0194:         * process the configuration file (strongly recommended)? [true]</li>
0195:         *
0196:         * <li><strong>chainConfig</strong> - Comma-separated list of either
0197:         * context-relative or classloader path(s) to load commons-chain catalog
0198:         * definitions from.  If none specified, the default Struts catalog that is
0199:         * provided with Struts will be used.</li>
0200:         *
0201:         * </ul>
0202:         *
0203:         * @version $Rev: 483039 $ $Date: 2005-10-14 19:54:16 -0400 (Fri, 14 Oct 2005)
0204:         *          $
0205:         */
0206:        public class ActionServlet extends HttpServlet {
0207:            /**
0208:             * <p>Commons Logging instance.</p>
0209:             *
0210:             * @since Struts 1.1
0211:             */
0212:            protected static Log log = LogFactory.getLog(ActionServlet.class);
0213:
0214:            // ----------------------------------------------------- Instance Variables
0215:
0216:            /**
0217:             * <p>Comma-separated list of context-relative path(s) to our
0218:             * configuration resource(s) for the default module.</p>
0219:             */
0220:            protected String config = "/WEB-INF/struts-config.xml";
0221:
0222:            /**
0223:             * <p>Comma-separated list of context or classloader-relative path(s) that
0224:             * contain the configuration for the default commons-chain
0225:             * catalog(s).</p>
0226:             */
0227:            protected String chainConfig = "org/apache/struts/chain/chain-config.xml";
0228:
0229:            /**
0230:             * <p>The Digester used to produce ModuleConfig objects from a Struts
0231:             * configuration file.</p>
0232:             *
0233:             * @since Struts 1.1
0234:             */
0235:            protected Digester configDigester = null;
0236:
0237:            /**
0238:             * <p>The flag to request backwards-compatible conversions for form bean
0239:             * properties of the Java wrapper class types.</p>
0240:             *
0241:             * @since Struts 1.1
0242:             */
0243:            protected boolean convertNull = false;
0244:
0245:            /**
0246:             * <p>The resources object for our internal resources.</p>
0247:             */
0248:            protected MessageResources internal = null;
0249:
0250:            /**
0251:             * <p>The Java base name of our internal resources.</p>
0252:             *
0253:             * @since Struts 1.1
0254:             */
0255:            protected String internalName = "org.apache.struts.action.ActionResources";
0256:
0257:            /**
0258:             * <p>The set of public identifiers, and corresponding resource names, for
0259:             * the versions of the configuration file DTDs that we know about.  There
0260:             * <strong>MUST</strong> be an even number of Strings in this list!</p>
0261:             */
0262:            protected String[] registrations = {
0263:                    "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN",
0264:                    "/org/apache/struts/resources/struts-config_1_0.dtd",
0265:                    "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN",
0266:                    "/org/apache/struts/resources/struts-config_1_1.dtd",
0267:                    "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN",
0268:                    "/org/apache/struts/resources/struts-config_1_2.dtd",
0269:                    "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN",
0270:                    "/org/apache/struts/resources/struts-config_1_3.dtd",
0271:                    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",
0272:                    "/org/apache/struts/resources/web-app_2_3.dtd" };
0273:
0274:            /**
0275:             * <p>The URL pattern to which we are mapped in our web application
0276:             * deployment descriptor.</p>
0277:             */
0278:            protected String servletMapping = null; // :FIXME: - multiples?
0279:
0280:            /**
0281:             * <p>The servlet name under which we are registered in our web
0282:             * application deployment descriptor.</p>
0283:             */
0284:            protected String servletName = null;
0285:
0286:            // ---------------------------------------------------- HttpServlet Methods
0287:
0288:            /**
0289:             * <p>Gracefully shut down this controller servlet, releasing any
0290:             * resources that were allocated at initialization.</p>
0291:             */
0292:            public void destroy() {
0293:                if (log.isDebugEnabled()) {
0294:                    log.debug(internal.getMessage("finalizing"));
0295:                }
0296:
0297:                destroyModules();
0298:                destroyInternal();
0299:                getServletContext().removeAttribute(Globals.ACTION_SERVLET_KEY);
0300:
0301:                // Release our LogFactory and Log instances (if any)
0302:                ClassLoader classLoader = Thread.currentThread()
0303:                        .getContextClassLoader();
0304:
0305:                if (classLoader == null) {
0306:                    classLoader = ActionServlet.class.getClassLoader();
0307:                }
0308:
0309:                try {
0310:                    LogFactory.release(classLoader);
0311:                } catch (Throwable t) {
0312:                    ; // Servlet container doesn't have the latest version
0313:
0314:                    // of commons-logging-api.jar installed
0315:                    // :FIXME: Why is this dependent on the container's version of
0316:                    // commons-logging? Shouldn't this depend on the version packaged
0317:                    // with Struts?
0318:
0319:                    /*
0320:                      Reason: LogFactory.release(classLoader); was added as
0321:                      an attempt to investigate the OutOfMemory error reported on
0322:                      Bugzilla #14042. It was committed for version 1.136 by craigmcc
0323:                     */
0324:                }
0325:
0326:                CatalogFactory.clear();
0327:                PropertyUtils.clearDescriptors();
0328:            }
0329:
0330:            /**
0331:             * <p>Initialize this servlet.  Most of the processing has been factored
0332:             * into support methods so that you can override particular functionality
0333:             * at a fairly granular level.</p>
0334:             *
0335:             * @throws ServletException if we cannot configure ourselves correctly
0336:             */
0337:            public void init() throws ServletException {
0338:                final String configPrefix = "config/";
0339:                final int configPrefixLength = configPrefix.length() - 1;
0340:
0341:                // Wraps the entire initialization in a try/catch to better handle
0342:                // unexpected exceptions and errors to provide better feedback
0343:                // to the developer
0344:                try {
0345:                    initInternal();
0346:                    initOther();
0347:                    initServlet();
0348:                    initChain();
0349:
0350:                    getServletContext().setAttribute(
0351:                            Globals.ACTION_SERVLET_KEY, this );
0352:                    initModuleConfigFactory();
0353:
0354:                    // Initialize modules as needed
0355:                    ModuleConfig moduleConfig = initModuleConfig("", config);
0356:
0357:                    initModuleMessageResources(moduleConfig);
0358:                    initModulePlugIns(moduleConfig);
0359:                    initModuleFormBeans(moduleConfig);
0360:                    initModuleForwards(moduleConfig);
0361:                    initModuleExceptionConfigs(moduleConfig);
0362:                    initModuleActions(moduleConfig);
0363:                    moduleConfig.freeze();
0364:
0365:                    Enumeration names = getServletConfig()
0366:                            .getInitParameterNames();
0367:
0368:                    while (names.hasMoreElements()) {
0369:                        String name = (String) names.nextElement();
0370:
0371:                        if (!name.startsWith(configPrefix)) {
0372:                            continue;
0373:                        }
0374:
0375:                        String prefix = name.substring(configPrefixLength);
0376:
0377:                        moduleConfig = initModuleConfig(prefix,
0378:                                getServletConfig().getInitParameter(name));
0379:                        initModuleMessageResources(moduleConfig);
0380:                        initModulePlugIns(moduleConfig);
0381:                        initModuleFormBeans(moduleConfig);
0382:                        initModuleForwards(moduleConfig);
0383:                        initModuleExceptionConfigs(moduleConfig);
0384:                        initModuleActions(moduleConfig);
0385:                        moduleConfig.freeze();
0386:                    }
0387:
0388:                    this .initModulePrefixes(this .getServletContext());
0389:
0390:                    this .destroyConfigDigester();
0391:                } catch (UnavailableException ex) {
0392:                    throw ex;
0393:                } catch (Throwable t) {
0394:                    // The follow error message is not retrieved from internal message
0395:                    // resources as they may not have been able to have been
0396:                    // initialized
0397:                    log
0398:                            .error(
0399:                                    "Unable to initialize Struts ActionServlet due to an "
0400:                                            + "unexpected exception or error thrown, so marking the "
0401:                                            + "servlet as unavailable.  Most likely, this is due to an "
0402:                                            + "incorrect or missing library dependency.",
0403:                                    t);
0404:                    throw new UnavailableException(t.getMessage());
0405:                }
0406:            }
0407:
0408:            /**
0409:             * <p>Saves a String[] of module prefixes in the ServletContext under
0410:             * Globals.MODULE_PREFIXES_KEY.  <strong>NOTE</strong> - the "" prefix for
0411:             * the default module is not included in this list.</p>
0412:             *
0413:             * @param context The servlet context.
0414:             * @since Struts 1.2
0415:             */
0416:            protected void initModulePrefixes(ServletContext context) {
0417:                ArrayList prefixList = new ArrayList();
0418:
0419:                Enumeration names = context.getAttributeNames();
0420:
0421:                while (names.hasMoreElements()) {
0422:                    String name = (String) names.nextElement();
0423:
0424:                    if (!name.startsWith(Globals.MODULE_KEY)) {
0425:                        continue;
0426:                    }
0427:
0428:                    String prefix = name.substring(Globals.MODULE_KEY.length());
0429:
0430:                    if (prefix.length() > 0) {
0431:                        prefixList.add(prefix);
0432:                    }
0433:                }
0434:
0435:                String[] prefixes = (String[]) prefixList
0436:                        .toArray(new String[prefixList.size()]);
0437:
0438:                context.setAttribute(Globals.MODULE_PREFIXES_KEY, prefixes);
0439:            }
0440:
0441:            /**
0442:             * <p>Process an HTTP "GET" request.</p>
0443:             *
0444:             * @param request  The servlet request we are processing
0445:             * @param response The servlet response we are creating
0446:             * @throws IOException      if an input/output error occurs
0447:             * @throws ServletException if a servlet exception occurs
0448:             */
0449:            public void doGet(HttpServletRequest request,
0450:                    HttpServletResponse response) throws IOException,
0451:                    ServletException {
0452:                process(request, response);
0453:            }
0454:
0455:            /**
0456:             * <p>Process an HTTP "POST" request.</p>
0457:             *
0458:             * @param request  The servlet request we are processing
0459:             * @param response The servlet response we are creating
0460:             * @throws IOException      if an input/output error occurs
0461:             * @throws ServletException if a servlet exception occurs
0462:             */
0463:            public void doPost(HttpServletRequest request,
0464:                    HttpServletResponse response) throws IOException,
0465:                    ServletException {
0466:                process(request, response);
0467:            }
0468:
0469:            // --------------------------------------------------------- Public Methods
0470:
0471:            /**
0472:             * <p>Remember a servlet mapping from our web application deployment
0473:             * descriptor, if it is for this servlet.</p>
0474:             *
0475:             * @param servletName The name of the servlet being mapped
0476:             * @param urlPattern  The URL pattern to which this servlet is mapped
0477:             */
0478:            public void addServletMapping(String servletName, String urlPattern) {
0479:                if (servletName == null) {
0480:                    return;
0481:                }
0482:
0483:                if (servletName.equals(this .servletName)) {
0484:                    if (log.isDebugEnabled()) {
0485:                        log.debug("Process servletName=" + servletName
0486:                                + ", urlPattern=" + urlPattern);
0487:                    }
0488:
0489:                    this .servletMapping = urlPattern;
0490:                }
0491:            }
0492:
0493:            /**
0494:             * <p>Return the <code>MessageResources</code> instance containing our
0495:             * internal message strings.</p>
0496:             *
0497:             * @return the <code>MessageResources</code> instance containing our
0498:             *         internal message strings.
0499:             * @since Struts 1.1
0500:             */
0501:            public MessageResources getInternal() {
0502:                return (this .internal);
0503:            }
0504:
0505:            // ------------------------------------------------------ Protected Methods
0506:
0507:            /**
0508:             * <p>Gracefully terminate use of any modules associated with this
0509:             * application (if any).</p>
0510:             *
0511:             * @since Struts 1.1
0512:             */
0513:            protected void destroyModules() {
0514:                ArrayList values = new ArrayList();
0515:                Enumeration names = getServletContext().getAttributeNames();
0516:
0517:                while (names.hasMoreElements()) {
0518:                    values.add(names.nextElement());
0519:                }
0520:
0521:                Iterator keys = values.iterator();
0522:
0523:                while (keys.hasNext()) {
0524:                    String name = (String) keys.next();
0525:                    Object value = getServletContext().getAttribute(name);
0526:
0527:                    if (!(value instanceof  ModuleConfig)) {
0528:                        continue;
0529:                    }
0530:
0531:                    ModuleConfig config = (ModuleConfig) value;
0532:
0533:                    if (this .getProcessorForModule(config) != null) {
0534:                        this .getProcessorForModule(config).destroy();
0535:                    }
0536:
0537:                    getServletContext().removeAttribute(name);
0538:
0539:                    PlugIn[] plugIns = (PlugIn[]) getServletContext()
0540:                            .getAttribute(
0541:                                    Globals.PLUG_INS_KEY + config.getPrefix());
0542:
0543:                    if (plugIns != null) {
0544:                        for (int i = 0; i < plugIns.length; i++) {
0545:                            int j = plugIns.length - (i + 1);
0546:
0547:                            plugIns[j].destroy();
0548:                        }
0549:
0550:                        getServletContext().removeAttribute(
0551:                                Globals.PLUG_INS_KEY + config.getPrefix());
0552:                    }
0553:                }
0554:            }
0555:
0556:            /**
0557:             * <p>Gracefully release any configDigester instance that we have created.
0558:             * </p>
0559:             *
0560:             * @since Struts 1.1
0561:             */
0562:            protected void destroyConfigDigester() {
0563:                configDigester = null;
0564:            }
0565:
0566:            /**
0567:             * <p>Gracefully terminate use of the internal MessageResources.</p>
0568:             */
0569:            protected void destroyInternal() {
0570:                internal = null;
0571:            }
0572:
0573:            /**
0574:             * <p>Return the module configuration object for the currently selected
0575:             * module.</p>
0576:             *
0577:             * @param request The servlet request we are processing
0578:             * @return The module configuration object for the currently selected
0579:             *         module.
0580:             * @since Struts 1.1
0581:             */
0582:            protected ModuleConfig getModuleConfig(HttpServletRequest request) {
0583:                ModuleConfig config = (ModuleConfig) request
0584:                        .getAttribute(Globals.MODULE_KEY);
0585:
0586:                if (config == null) {
0587:                    config = (ModuleConfig) getServletContext().getAttribute(
0588:                            Globals.MODULE_KEY);
0589:                }
0590:
0591:                return (config);
0592:            }
0593:
0594:            /**
0595:             * <p>Look up and return the {@link RequestProcessor} responsible for the
0596:             * specified module, creating a new one if necessary.</p>
0597:             *
0598:             * @param config The module configuration for which to acquire and return
0599:             *               a RequestProcessor.
0600:             * @return The {@link RequestProcessor} responsible for the specified
0601:             *         module,
0602:             * @throws ServletException If we cannot instantiate a RequestProcessor
0603:             *                          instance a {@link UnavailableException} is
0604:             *                          thrown, meaning your application is not loaded
0605:             *                          and will not be available.
0606:             * @since Struts 1.1
0607:             */
0608:            protected synchronized RequestProcessor getRequestProcessor(
0609:                    ModuleConfig config) throws ServletException {
0610:                RequestProcessor processor = this .getProcessorForModule(config);
0611:
0612:                if (processor == null) {
0613:                    try {
0614:                        processor = (RequestProcessor) RequestUtils
0615:                                .applicationInstance(config
0616:                                        .getControllerConfig()
0617:                                        .getProcessorClass());
0618:                    } catch (Exception e) {
0619:                        throw new UnavailableException(
0620:                                "Cannot initialize RequestProcessor of class "
0621:                                        + config.getControllerConfig()
0622:                                                .getProcessorClass() + ": " + e);
0623:                    }
0624:
0625:                    processor.init(this , config);
0626:
0627:                    String key = Globals.REQUEST_PROCESSOR_KEY
0628:                            + config.getPrefix();
0629:
0630:                    getServletContext().setAttribute(key, processor);
0631:                }
0632:
0633:                return (processor);
0634:            }
0635:
0636:            /**
0637:             * <p>Returns the RequestProcessor for the given module or null if one
0638:             * does not exist.  This method will not create a RequestProcessor.</p>
0639:             *
0640:             * @param config The ModuleConfig.
0641:             * @return The <code>RequestProcessor</code> for the given module, or
0642:             *         <code>null</code> if one does not exist.
0643:             */
0644:            private RequestProcessor getProcessorForModule(ModuleConfig config) {
0645:                String key = Globals.REQUEST_PROCESSOR_KEY + config.getPrefix();
0646:
0647:                return (RequestProcessor) getServletContext().getAttribute(key);
0648:            }
0649:
0650:            /**
0651:             * <p>Initialize the factory used to create the module configuration.</p>
0652:             *
0653:             * @since Struts 1.2
0654:             */
0655:            protected void initModuleConfigFactory() {
0656:                String configFactory = getServletConfig().getInitParameter(
0657:                        "configFactory");
0658:
0659:                if (configFactory != null) {
0660:                    ModuleConfigFactory.setFactoryClass(configFactory);
0661:                }
0662:            }
0663:
0664:            /**
0665:             * <p>Initialize the module configuration information for the specified
0666:             * module.</p>
0667:             *
0668:             * @param prefix Module prefix for this module
0669:             * @param paths  Comma-separated list of context-relative resource path(s)
0670:             *               for this modules's configuration resource(s)
0671:             * @return The new module configuration instance.
0672:             * @throws ServletException if initialization cannot be performed
0673:             * @since Struts 1.1
0674:             */
0675:            protected ModuleConfig initModuleConfig(String prefix, String paths)
0676:                    throws ServletException {
0677:                if (log.isDebugEnabled()) {
0678:                    log.debug("Initializing module path '" + prefix
0679:                            + "' configuration from '" + paths + "'");
0680:                }
0681:
0682:                // Parse the configuration for this module
0683:                ModuleConfigFactory factoryObject = ModuleConfigFactory
0684:                        .createFactory();
0685:                ModuleConfig config = factoryObject.createModuleConfig(prefix);
0686:
0687:                // Configure the Digester instance we will use
0688:                Digester digester = initConfigDigester();
0689:
0690:                List urls = splitAndResolvePaths(paths);
0691:                URL url;
0692:
0693:                for (Iterator i = urls.iterator(); i.hasNext();) {
0694:                    url = (URL) i.next();
0695:                    digester.push(config);
0696:                    this .parseModuleConfigFile(digester, url);
0697:                }
0698:
0699:                getServletContext().setAttribute(
0700:                        Globals.MODULE_KEY + config.getPrefix(), config);
0701:
0702:                return config;
0703:            }
0704:
0705:            /**
0706:             * <p>Parses one module config file.</p>
0707:             *
0708:             * @param digester Digester instance that does the parsing
0709:             * @param path     The path to the config file to parse.
0710:             * @throws UnavailableException if file cannot be read or parsed
0711:             * @since Struts 1.2
0712:             * @deprecated use parseModuleConfigFile(Digester digester, URL url)
0713:             *             instead
0714:             */
0715:            protected void parseModuleConfigFile(Digester digester, String path)
0716:                    throws UnavailableException {
0717:                try {
0718:                    List paths = splitAndResolvePaths(path);
0719:
0720:                    if (paths.size() > 0) {
0721:                        // Get first path as was the old behavior
0722:                        URL url = (URL) paths.get(0);
0723:
0724:                        parseModuleConfigFile(digester, url);
0725:                    } else {
0726:                        throw new UnavailableException("Cannot locate path "
0727:                                + path);
0728:                    }
0729:                } catch (UnavailableException ex) {
0730:                    throw ex;
0731:                } catch (ServletException ex) {
0732:                    handleConfigException(path, ex);
0733:                }
0734:            }
0735:
0736:            /**
0737:             * <p>Parses one module config file.</p>
0738:             *
0739:             * @param digester Digester instance that does the parsing
0740:             * @param url      The url to the config file to parse.
0741:             * @throws UnavailableException if file cannot be read or parsed
0742:             * @since Struts 1.3
0743:             */
0744:            protected void parseModuleConfigFile(Digester digester, URL url)
0745:                    throws UnavailableException {
0746:
0747:                try {
0748:                    digester.parse(url);
0749:                } catch (IOException e) {
0750:                    handleConfigException(url.toString(), e);
0751:                } catch (SAXException e) {
0752:                    handleConfigException(url.toString(), e);
0753:                }
0754:            }
0755:
0756:            /**
0757:             * <p>Simplifies exception handling in the parseModuleConfigFile
0758:             * method.<p>
0759:             *
0760:             * @param path The path to which the exception relates.
0761:             * @param e    The exception to be wrapped and thrown.
0762:             * @throws UnavailableException as a wrapper around Exception
0763:             */
0764:            private void handleConfigException(String path, Exception e)
0765:                    throws UnavailableException {
0766:                String msg = internal.getMessage("configParse", path);
0767:
0768:                log.error(msg, e);
0769:                throw new UnavailableException(msg);
0770:            }
0771:
0772:            /**
0773:             * <p>Handle errors related to creating an instance of the specified
0774:             * class.</p>
0775:             *
0776:             * @param className The className that could not be instantiated.
0777:             * @param e         The exception that was caught.
0778:             * @throws ServletException to communicate the error.
0779:             */
0780:            private void handleCreationException(String className, Exception e)
0781:                    throws ServletException {
0782:                String errorMessage = internal.getMessage(
0783:                        "configExtends.creation", className);
0784:
0785:                log.error(errorMessage, e);
0786:                throw new UnavailableException(errorMessage);
0787:            }
0788:
0789:            /**
0790:             * <p>General handling for exceptions caught while inheriting config
0791:             * information.</p>
0792:             *
0793:             * @param configType The type of configuration object of configName.
0794:             * @param configName The name of the config that could not be extended.
0795:             * @param e          The exception that was caught.
0796:             * @throws ServletException to communicate the error.
0797:             */
0798:            private void handleGeneralExtensionException(String configType,
0799:                    String configName, Exception e) throws ServletException {
0800:                String errorMessage = internal.getMessage("configExtends",
0801:                        configType, configName);
0802:
0803:                log.error(errorMessage, e);
0804:                throw new UnavailableException(errorMessage);
0805:            }
0806:
0807:            /**
0808:             * <p>Handle errors caused by required fields that were not
0809:             * specified.</p>
0810:             *
0811:             * @param field      The name of the required field that was not found.
0812:             * @param configType The type of configuration object of configName.
0813:             * @param configName The name of the config that's missing the required
0814:             *                   value.
0815:             * @throws ServletException to communicate the error.
0816:             */
0817:            private void handleValueRequiredException(String field,
0818:                    String configType, String configName)
0819:                    throws ServletException {
0820:                String errorMessage = internal.getMessage(
0821:                        "configFieldRequired", field, configType, configName);
0822:
0823:                log.error(errorMessage);
0824:                throw new UnavailableException(errorMessage);
0825:            }
0826:
0827:            /**
0828:             * <p>Initialize the plug ins for the specified module.</p>
0829:             *
0830:             * @param config ModuleConfig information for this module
0831:             * @throws ServletException if initialization cannot be performed
0832:             * @since Struts 1.1
0833:             */
0834:            protected void initModulePlugIns(ModuleConfig config)
0835:                    throws ServletException {
0836:                if (log.isDebugEnabled()) {
0837:                    log.debug("Initializing module path '" + config.getPrefix()
0838:                            + "' plug ins");
0839:                }
0840:
0841:                PlugInConfig[] plugInConfigs = config.findPlugInConfigs();
0842:                PlugIn[] plugIns = new PlugIn[plugInConfigs.length];
0843:
0844:                getServletContext().setAttribute(
0845:                        Globals.PLUG_INS_KEY + config.getPrefix(), plugIns);
0846:
0847:                for (int i = 0; i < plugIns.length; i++) {
0848:                    try {
0849:                        plugIns[i] = (PlugIn) RequestUtils
0850:                                .applicationInstance(plugInConfigs[i]
0851:                                        .getClassName());
0852:                        BeanUtils.populate(plugIns[i], plugInConfigs[i]
0853:                                .getProperties());
0854:
0855:                        // Pass the current plugIn config object to the PlugIn.
0856:                        // The property is set only if the plugin declares it.
0857:                        // This plugin config object is needed by Tiles
0858:                        try {
0859:                            PropertyUtils.setProperty(plugIns[i],
0860:                                    "currentPlugInConfigObject",
0861:                                    plugInConfigs[i]);
0862:                        } catch (Exception e) {
0863:                            ;
0864:
0865:                            // FIXME Whenever we fail silently, we must document a valid
0866:                            // reason for doing so.  Why should we fail silently if a
0867:                            // property can't be set on the plugin?
0868:
0869:                            /**
0870:                             * Between version 1.138-1.140 cedric made these changes.
0871:                             * The exceptions are caught to deal with containers
0872:                             * applying strict security. This was in response to bug
0873:                             * #15736
0874:                             *
0875:                             * Recommend that we make the currentPlugInConfigObject part
0876:                             * of the PlugIn Interface if we can, Rob
0877:                             */
0878:                        }
0879:
0880:                        plugIns[i].init(this , config);
0881:                    } catch (ServletException e) {
0882:                        throw e;
0883:                    } catch (Exception e) {
0884:                        String errMsg = internal.getMessage("plugIn.init",
0885:                                plugInConfigs[i].getClassName());
0886:
0887:                        log(errMsg, e);
0888:                        throw new UnavailableException(errMsg);
0889:                    }
0890:                }
0891:            }
0892:
0893:            /**
0894:             * <p>Initialize the form beans for the specified module.</p>
0895:             *
0896:             * @param config ModuleConfig information for this module
0897:             * @throws ServletException if initialization cannot be performed
0898:             * @since Struts 1.3
0899:             */
0900:            protected void initModuleFormBeans(ModuleConfig config)
0901:                    throws ServletException {
0902:                if (log.isDebugEnabled()) {
0903:                    log.debug("Initializing module path '" + config.getPrefix()
0904:                            + "' form beans");
0905:                }
0906:
0907:                // Process form bean extensions.
0908:                FormBeanConfig[] formBeans = config.findFormBeanConfigs();
0909:
0910:                for (int i = 0; i < formBeans.length; i++) {
0911:                    FormBeanConfig beanConfig = formBeans[i];
0912:
0913:                    processFormBeanExtension(beanConfig, config);
0914:                }
0915:
0916:                for (int i = 0; i < formBeans.length; i++) {
0917:                    FormBeanConfig formBean = formBeans[i];
0918:
0919:                    // Verify that required fields are all present for the form config
0920:                    if (formBean.getType() == null) {
0921:                        handleValueRequiredException("type",
0922:                                formBean.getName(), "form bean");
0923:                    }
0924:
0925:                    // ... and the property configs
0926:                    FormPropertyConfig[] fpcs = formBean
0927:                            .findFormPropertyConfigs();
0928:
0929:                    for (int j = 0; j < fpcs.length; j++) {
0930:                        FormPropertyConfig property = fpcs[j];
0931:
0932:                        if (property.getType() == null) {
0933:                            handleValueRequiredException("type", property
0934:                                    .getName(), "form property");
0935:                        }
0936:                    }
0937:
0938:                    // Force creation and registration of DynaActionFormClass instances
0939:                    // for all dynamic form beans
0940:                    if (formBean.getDynamic()) {
0941:                        formBean.getDynaActionFormClass();
0942:                    }
0943:                }
0944:            }
0945:
0946:            /**
0947:             * <p>Extend the form bean's configuration as necessary.</p>
0948:             *
0949:             * @param beanConfig   the configuration to process.
0950:             * @param moduleConfig the module configuration for this module.
0951:             * @throws ServletException if initialization cannot be performed.
0952:             */
0953:            protected void processFormBeanExtension(FormBeanConfig beanConfig,
0954:                    ModuleConfig moduleConfig) throws ServletException {
0955:                try {
0956:                    if (!beanConfig.isExtensionProcessed()) {
0957:                        if (log.isDebugEnabled()) {
0958:                            log.debug("Processing extensions for '"
0959:                                    + beanConfig.getName() + "'");
0960:                        }
0961:
0962:                        beanConfig = processFormBeanConfigClass(beanConfig,
0963:                                moduleConfig);
0964:
0965:                        beanConfig.processExtends(moduleConfig);
0966:                    }
0967:                } catch (ServletException e) {
0968:                    throw e;
0969:                } catch (Exception e) {
0970:                    handleGeneralExtensionException("FormBeanConfig",
0971:                            beanConfig.getName(), e);
0972:                }
0973:            }
0974:
0975:            /**
0976:             * <p>Checks if the current beanConfig is using the correct class based on
0977:             * the class of its ancestor form bean config.</p>
0978:             *
0979:             * @param beanConfig   The form bean to check.
0980:             * @param moduleConfig The config for the current module.
0981:             * @return The form bean config using the correct class as determined by
0982:             *         the config's ancestor and its own overridden value.
0983:             * @throws UnavailableException if an instance of the form bean config
0984:             *                              class cannot be created.
0985:             * @throws ServletException     on class creation error
0986:             */
0987:            protected FormBeanConfig processFormBeanConfigClass(
0988:                    FormBeanConfig beanConfig, ModuleConfig moduleConfig)
0989:                    throws ServletException {
0990:                String ancestor = beanConfig.getExtends();
0991:
0992:                if (ancestor == null) {
0993:                    // Nothing to do, then
0994:                    return beanConfig;
0995:                }
0996:
0997:                // Make sure that this bean is of the right class
0998:                FormBeanConfig baseConfig = moduleConfig
0999:                        .findFormBeanConfig(ancestor);
1000:
1001:                if (baseConfig == null) {
1002:                    throw new UnavailableException("Unable to find "
1003:                            + "form bean '" + ancestor + "' to extend.");
1004:                }
1005:
1006:                // Was our bean's class overridden already?
1007:                if (beanConfig.getClass().equals(FormBeanConfig.class)) {
1008:                    // Ensure that our bean is using the correct class
1009:                    if (!baseConfig.getClass().equals(beanConfig.getClass())) {
1010:                        // Replace the bean with an instance of the correct class
1011:                        FormBeanConfig newBeanConfig = null;
1012:                        String baseConfigClassName = baseConfig.getClass()
1013:                                .getName();
1014:
1015:                        try {
1016:                            newBeanConfig = (FormBeanConfig) RequestUtils
1017:                                    .applicationInstance(baseConfigClassName);
1018:
1019:                            // copy the values
1020:                            BeanUtils.copyProperties(newBeanConfig, beanConfig);
1021:
1022:                            FormPropertyConfig[] fpc = beanConfig
1023:                                    .findFormPropertyConfigs();
1024:
1025:                            for (int i = 0; i < fpc.length; i++) {
1026:                                newBeanConfig.addFormPropertyConfig(fpc[i]);
1027:                            }
1028:                        } catch (Exception e) {
1029:                            handleCreationException(baseConfigClassName, e);
1030:                        }
1031:
1032:                        // replace beanConfig with newBeanConfig
1033:                        moduleConfig.removeFormBeanConfig(beanConfig);
1034:                        moduleConfig.addFormBeanConfig(newBeanConfig);
1035:                        beanConfig = newBeanConfig;
1036:                    }
1037:                }
1038:
1039:                return beanConfig;
1040:            }
1041:
1042:            /**
1043:             * <p>Initialize the forwards for the specified module.</p>
1044:             *
1045:             * @param config ModuleConfig information for this module
1046:             * @throws ServletException if initialization cannot be performed
1047:             */
1048:            protected void initModuleForwards(ModuleConfig config)
1049:                    throws ServletException {
1050:                if (log.isDebugEnabled()) {
1051:                    log.debug("Initializing module path '" + config.getPrefix()
1052:                            + "' forwards");
1053:                }
1054:
1055:                // Process forwards extensions.
1056:                ForwardConfig[] forwards = config.findForwardConfigs();
1057:
1058:                for (int i = 0; i < forwards.length; i++) {
1059:                    ForwardConfig forward = forwards[i];
1060:
1061:                    processForwardExtension(forward, config, null);
1062:                }
1063:
1064:                for (int i = 0; i < forwards.length; i++) {
1065:                    ForwardConfig forward = forwards[i];
1066:
1067:                    // Verify that required fields are all present for the forward
1068:                    if (forward.getPath() == null) {
1069:                        handleValueRequiredException("path", forward.getName(),
1070:                                "global forward");
1071:                    }
1072:                }
1073:            }
1074:
1075:            /**
1076:             * <p>Extend the forward's configuration as necessary.  If actionConfig is
1077:             * provided, then this method will process the forwardConfig as part
1078:             * of that actionConfig.  If actionConfig is null, the forwardConfig
1079:             * will be processed as a global forward.</p>
1080:             *
1081:             * @param forwardConfig the configuration to process.
1082:             * @param moduleConfig  the module configuration for this module.
1083:             * @param actionConfig  If applicable, the config for the current action.
1084:             * @throws ServletException if initialization cannot be performed.
1085:             */
1086:            protected void processForwardExtension(ForwardConfig forwardConfig,
1087:                    ModuleConfig moduleConfig, ActionConfig actionConfig)
1088:                    throws ServletException {
1089:                try {
1090:                    if (!forwardConfig.isExtensionProcessed()) {
1091:                        if (log.isDebugEnabled()) {
1092:                            log.debug("Processing extensions for '"
1093:                                    + forwardConfig.getName() + "'");
1094:                        }
1095:
1096:                        forwardConfig = processForwardConfigClass(
1097:                                forwardConfig, moduleConfig, actionConfig);
1098:
1099:                        forwardConfig
1100:                                .processExtends(moduleConfig, actionConfig);
1101:                    }
1102:                } catch (ServletException e) {
1103:                    throw e;
1104:                } catch (Exception e) {
1105:                    handleGeneralExtensionException("Forward", forwardConfig
1106:                            .getName(), e);
1107:                }
1108:            }
1109:
1110:            /**
1111:             * <p>Checks if the current forwardConfig is using the correct class based
1112:             * on the class of its configuration ancestor.  If actionConfig is
1113:             * provided, then this method will process the forwardConfig as part
1114:             * of that actionConfig.  If actionConfig is null, the forwardConfig
1115:             * will be processed as a global forward.</p>
1116:             *
1117:             * @param forwardConfig The forward to check.
1118:             * @param moduleConfig  The config for the current module.
1119:             * @param actionConfig  If applicable, the config for the current action.
1120:             * @return The forward config using the correct class as determined by the
1121:             *         config's ancestor and its own overridden value.
1122:             * @throws UnavailableException if an instance of the forward config class
1123:             *                              cannot be created.
1124:             * @throws ServletException     on class creation error
1125:             */
1126:            protected ForwardConfig processForwardConfigClass(
1127:                    ForwardConfig forwardConfig, ModuleConfig moduleConfig,
1128:                    ActionConfig actionConfig) throws ServletException {
1129:                String ancestor = forwardConfig.getExtends();
1130:
1131:                if (ancestor == null) {
1132:                    // Nothing to do, then
1133:                    return forwardConfig;
1134:                }
1135:
1136:                // Make sure that this config is of the right class
1137:                ForwardConfig baseConfig = null;
1138:                if (actionConfig != null) {
1139:                    // Look for this in the actionConfig
1140:                    baseConfig = actionConfig.findForwardConfig(ancestor);
1141:                }
1142:
1143:                if (baseConfig == null) {
1144:                    // Either this is a forwardConfig that inherits a global config,
1145:                    //  or actionConfig is null
1146:                    baseConfig = moduleConfig.findForwardConfig(ancestor);
1147:                }
1148:
1149:                if (baseConfig == null) {
1150:                    throw new UnavailableException("Unable to find "
1151:                            + "forward '" + ancestor + "' to extend.");
1152:                }
1153:
1154:                // Was our forwards's class overridden already?
1155:                if (forwardConfig.getClass().equals(ActionForward.class)) {
1156:                    // Ensure that our forward is using the correct class
1157:                    if (!baseConfig.getClass().equals(forwardConfig.getClass())) {
1158:                        // Replace the config with an instance of the correct class
1159:                        ForwardConfig newForwardConfig = null;
1160:                        String baseConfigClassName = baseConfig.getClass()
1161:                                .getName();
1162:
1163:                        try {
1164:                            newForwardConfig = (ForwardConfig) RequestUtils
1165:                                    .applicationInstance(baseConfigClassName);
1166:
1167:                            // copy the values
1168:                            BeanUtils.copyProperties(newForwardConfig,
1169:                                    forwardConfig);
1170:                        } catch (Exception e) {
1171:                            handleCreationException(baseConfigClassName, e);
1172:                        }
1173:
1174:                        // replace forwardConfig with newForwardConfig
1175:                        if (actionConfig != null) {
1176:                            actionConfig.removeForwardConfig(forwardConfig);
1177:                            actionConfig.addForwardConfig(newForwardConfig);
1178:                        } else {
1179:                            // this is a global forward
1180:                            moduleConfig.removeForwardConfig(forwardConfig);
1181:                            moduleConfig.addForwardConfig(newForwardConfig);
1182:                        }
1183:                        forwardConfig = newForwardConfig;
1184:                    }
1185:                }
1186:
1187:                return forwardConfig;
1188:            }
1189:
1190:            /**
1191:             * <p>Initialize the exception handlers for the specified module.</p>
1192:             *
1193:             * @param config ModuleConfig information for this module
1194:             * @throws ServletException if initialization cannot be performed
1195:             * @since Struts 1.3
1196:             */
1197:            protected void initModuleExceptionConfigs(ModuleConfig config)
1198:                    throws ServletException {
1199:                if (log.isDebugEnabled()) {
1200:                    log.debug("Initializing module path '" + config.getPrefix()
1201:                            + "' forwards");
1202:                }
1203:
1204:                // Process exception config extensions.
1205:                ExceptionConfig[] exceptions = config.findExceptionConfigs();
1206:
1207:                for (int i = 0; i < exceptions.length; i++) {
1208:                    ExceptionConfig exception = exceptions[i];
1209:
1210:                    processExceptionExtension(exception, config, null);
1211:                }
1212:
1213:                for (int i = 0; i < exceptions.length; i++) {
1214:                    ExceptionConfig exception = exceptions[i];
1215:
1216:                    // Verify that required fields are all present for the config
1217:                    if (exception.getKey() == null) {
1218:                        handleValueRequiredException("key",
1219:                                exception.getType(), "global exception config");
1220:                    }
1221:                }
1222:            }
1223:
1224:            /**
1225:             * <p>Extend the exception's configuration as necessary. If actionConfig is
1226:             * provided, then this method will process the exceptionConfig as part
1227:             * of that actionConfig.  If actionConfig is null, the exceptionConfig
1228:             * will be processed as a global forward.</p>
1229:             *
1230:             * @param exceptionConfig the configuration to process.
1231:             * @param moduleConfig    the module configuration for this module.
1232:             * @param actionConfig  If applicable, the config for the current action.
1233:             * @throws ServletException if initialization cannot be performed.
1234:             */
1235:            protected void processExceptionExtension(
1236:                    ExceptionConfig exceptionConfig, ModuleConfig moduleConfig,
1237:                    ActionConfig actionConfig) throws ServletException {
1238:                try {
1239:                    if (!exceptionConfig.isExtensionProcessed()) {
1240:                        if (log.isDebugEnabled()) {
1241:                            log.debug("Processing extensions for '"
1242:                                    + exceptionConfig.getType() + "'");
1243:                        }
1244:
1245:                        exceptionConfig = processExceptionConfigClass(
1246:                                exceptionConfig, moduleConfig, actionConfig);
1247:
1248:                        exceptionConfig.processExtends(moduleConfig,
1249:                                actionConfig);
1250:                    }
1251:                } catch (ServletException e) {
1252:                    throw e;
1253:                } catch (Exception e) {
1254:                    handleGeneralExtensionException("Exception",
1255:                            exceptionConfig.getType(), e);
1256:                }
1257:            }
1258:
1259:            /**
1260:             * <p>Checks if the current exceptionConfig is using the correct class
1261:             * based on the class of its configuration ancestor. If actionConfig is
1262:             * provided, then this method will process the exceptionConfig as part
1263:             * of that actionConfig.  If actionConfig is null, the exceptionConfig
1264:             * will be processed as a global forward.</p>
1265:             *
1266:             * @param exceptionConfig The config to check.
1267:             * @param moduleConfig    The config for the current module.
1268:             * @param actionConfig  If applicable, the config for the current action.
1269:             * @return The exception config using the correct class as determined by
1270:             *         the config's ancestor and its own overridden value.
1271:             * @throws ServletException if an instance of the exception config class
1272:             *                          cannot be created.
1273:             */
1274:            protected ExceptionConfig processExceptionConfigClass(
1275:                    ExceptionConfig exceptionConfig, ModuleConfig moduleConfig,
1276:                    ActionConfig actionConfig) throws ServletException {
1277:                String ancestor = exceptionConfig.getExtends();
1278:
1279:                if (ancestor == null) {
1280:                    // Nothing to do, then
1281:                    return exceptionConfig;
1282:                }
1283:
1284:                // Make sure that this config is of the right class
1285:                ExceptionConfig baseConfig = null;
1286:                if (actionConfig != null) {
1287:                    baseConfig = actionConfig.findExceptionConfig(ancestor);
1288:                }
1289:
1290:                if (baseConfig == null) {
1291:                    // This means either there's no actionConfig anyway, or the
1292:                    // ancestor is not defined within the action.
1293:                    baseConfig = moduleConfig.findExceptionConfig(ancestor);
1294:                }
1295:
1296:                if (baseConfig == null) {
1297:                    throw new UnavailableException("Unable to find "
1298:                            + "exception config '" + ancestor + "' to extend.");
1299:                }
1300:
1301:                // Was our config's class overridden already?
1302:                if (exceptionConfig.getClass().equals(ExceptionConfig.class)) {
1303:                    // Ensure that our config is using the correct class
1304:                    if (!baseConfig.getClass().equals(
1305:                            exceptionConfig.getClass())) {
1306:                        // Replace the config with an instance of the correct class
1307:                        ExceptionConfig newExceptionConfig = null;
1308:                        String baseConfigClassName = baseConfig.getClass()
1309:                                .getName();
1310:
1311:                        try {
1312:                            newExceptionConfig = (ExceptionConfig) RequestUtils
1313:                                    .applicationInstance(baseConfigClassName);
1314:
1315:                            // copy the values
1316:                            BeanUtils.copyProperties(newExceptionConfig,
1317:                                    exceptionConfig);
1318:                        } catch (Exception e) {
1319:                            handleCreationException(baseConfigClassName, e);
1320:                        }
1321:
1322:                        // replace exceptionConfig with newExceptionConfig
1323:                        if (actionConfig != null) {
1324:                            actionConfig.removeExceptionConfig(exceptionConfig);
1325:                            actionConfig.addExceptionConfig(newExceptionConfig);
1326:                        } else {
1327:                            moduleConfig.removeExceptionConfig(exceptionConfig);
1328:                            moduleConfig.addExceptionConfig(newExceptionConfig);
1329:                        }
1330:                        exceptionConfig = newExceptionConfig;
1331:                    }
1332:                }
1333:
1334:                return exceptionConfig;
1335:            }
1336:
1337:            /**
1338:             * <p>Initialize the action configs for the specified module.</p>
1339:             *
1340:             * @param config ModuleConfig information for this module
1341:             * @throws ServletException if initialization cannot be performed
1342:             * @since Struts 1.3
1343:             */
1344:            protected void initModuleActions(ModuleConfig config)
1345:                    throws ServletException {
1346:                if (log.isDebugEnabled()) {
1347:                    log.debug("Initializing module path '" + config.getPrefix()
1348:                            + "' action configs");
1349:                }
1350:
1351:                // Process ActionConfig extensions.
1352:                ActionConfig[] actionConfigs = config.findActionConfigs();
1353:
1354:                for (int i = 0; i < actionConfigs.length; i++) {
1355:                    ActionConfig actionConfig = actionConfigs[i];
1356:
1357:                    processActionConfigExtension(actionConfig, config);
1358:                }
1359:
1360:                for (int i = 0; i < actionConfigs.length; i++) {
1361:                    ActionConfig actionConfig = actionConfigs[i];
1362:
1363:                    // Verify that required fields are all present for the forward
1364:                    // configs
1365:                    ForwardConfig[] forwards = actionConfig
1366:                            .findForwardConfigs();
1367:
1368:                    for (int j = 0; j < forwards.length; j++) {
1369:                        ForwardConfig forward = forwards[j];
1370:
1371:                        if (forward.getPath() == null) {
1372:                            handleValueRequiredException("path", forward
1373:                                    .getName(), "action forward");
1374:                        }
1375:                    }
1376:
1377:                    // ... and the exception configs
1378:                    ExceptionConfig[] exceptions = actionConfig
1379:                            .findExceptionConfigs();
1380:
1381:                    for (int j = 0; j < exceptions.length; j++) {
1382:                        ExceptionConfig exception = exceptions[j];
1383:
1384:                        if (exception.getKey() == null) {
1385:                            handleValueRequiredException("key", exception
1386:                                    .getType(), "action exception config");
1387:                        }
1388:                    }
1389:                }
1390:            }
1391:
1392:            /**
1393:             * <p>Extend the action's configuration as necessary.</p>
1394:             *
1395:             * @param actionConfig the configuration to process.
1396:             * @param moduleConfig the module configuration for this module.
1397:             * @throws ServletException if initialization cannot be performed.
1398:             */
1399:            protected void processActionConfigExtension(
1400:                    ActionConfig actionConfig, ModuleConfig moduleConfig)
1401:                    throws ServletException {
1402:                try {
1403:                    if (!actionConfig.isExtensionProcessed()) {
1404:                        if (log.isDebugEnabled()) {
1405:                            log.debug("Processing extensions for '"
1406:                                    + actionConfig.getPath() + "'");
1407:                        }
1408:
1409:                        actionConfig = processActionConfigClass(actionConfig,
1410:                                moduleConfig);
1411:
1412:                        actionConfig.processExtends(moduleConfig);
1413:                    }
1414:
1415:                    // Process forwards extensions.
1416:                    ForwardConfig[] forwards = actionConfig
1417:                            .findForwardConfigs();
1418:                    for (int i = 0; i < forwards.length; i++) {
1419:                        ForwardConfig forward = forwards[i];
1420:                        processForwardExtension(forward, moduleConfig,
1421:                                actionConfig);
1422:                    }
1423:
1424:                    // Process exception extensions.
1425:                    ExceptionConfig[] exceptions = actionConfig
1426:                            .findExceptionConfigs();
1427:                    for (int i = 0; i < exceptions.length; i++) {
1428:                        ExceptionConfig exception = exceptions[i];
1429:                        processExceptionExtension(exception, moduleConfig,
1430:                                actionConfig);
1431:                    }
1432:                } catch (ServletException e) {
1433:                    throw e;
1434:                } catch (Exception e) {
1435:                    handleGeneralExtensionException("Action", actionConfig
1436:                            .getPath(), e);
1437:                }
1438:            }
1439:
1440:            /**
1441:             * <p>Checks if the current actionConfig is using the correct class based
1442:             * on the class of its ancestor ActionConfig.</p>
1443:             *
1444:             * @param actionConfig The action config to check.
1445:             * @param moduleConfig The config for the current module.
1446:             * @return The config object using the correct class as determined by the
1447:             *         config's ancestor and its own overridden value.
1448:             * @throws ServletException if an instance of the action config class
1449:             *                          cannot be created.
1450:             */
1451:            protected ActionConfig processActionConfigClass(
1452:                    ActionConfig actionConfig, ModuleConfig moduleConfig)
1453:                    throws ServletException {
1454:                String ancestor = actionConfig.getExtends();
1455:
1456:                if (ancestor == null) {
1457:                    // Nothing to do, then
1458:                    return actionConfig;
1459:                }
1460:
1461:                // Make sure that this config is of the right class
1462:                ActionConfig baseConfig = moduleConfig
1463:                        .findActionConfig(ancestor);
1464:
1465:                if (baseConfig == null) {
1466:                    throw new UnavailableException("Unable to find "
1467:                            + "action config for '" + ancestor + "' to extend.");
1468:                }
1469:
1470:                // Was our actionConfig's class overridden already?
1471:                if (actionConfig.getClass().equals(ActionMapping.class)) {
1472:                    // Ensure that our config is using the correct class
1473:                    if (!baseConfig.getClass().equals(actionConfig.getClass())) {
1474:                        // Replace the config with an instance of the correct class
1475:                        ActionConfig newActionConfig = null;
1476:                        String baseConfigClassName = baseConfig.getClass()
1477:                                .getName();
1478:
1479:                        try {
1480:                            newActionConfig = (ActionConfig) RequestUtils
1481:                                    .applicationInstance(baseConfigClassName);
1482:
1483:                            // copy the values
1484:                            BeanUtils.copyProperties(newActionConfig,
1485:                                    actionConfig);
1486:
1487:                            // copy the forward and exception configs, too
1488:                            ForwardConfig[] forwards = actionConfig
1489:                                    .findForwardConfigs();
1490:
1491:                            for (int i = 0; i < forwards.length; i++) {
1492:                                newActionConfig.addForwardConfig(forwards[i]);
1493:                            }
1494:
1495:                            ExceptionConfig[] exceptions = actionConfig
1496:                                    .findExceptionConfigs();
1497:
1498:                            for (int i = 0; i < exceptions.length; i++) {
1499:                                newActionConfig
1500:                                        .addExceptionConfig(exceptions[i]);
1501:                            }
1502:                        } catch (Exception e) {
1503:                            handleCreationException(baseConfigClassName, e);
1504:                        }
1505:
1506:                        // replace actionConfig with newActionConfig
1507:                        moduleConfig.removeActionConfig(actionConfig);
1508:                        moduleConfig.addActionConfig(newActionConfig);
1509:                        actionConfig = newActionConfig;
1510:                    }
1511:                }
1512:
1513:                return actionConfig;
1514:            }
1515:
1516:            /**
1517:             * <p>Initialize the application <code>MessageResources</code> for the
1518:             * specified module.</p>
1519:             *
1520:             * @param config ModuleConfig information for this module
1521:             * @throws ServletException if initialization cannot be performed
1522:             * @since Struts 1.1
1523:             */
1524:            protected void initModuleMessageResources(ModuleConfig config)
1525:                    throws ServletException {
1526:                MessageResourcesConfig[] mrcs = config
1527:                        .findMessageResourcesConfigs();
1528:
1529:                for (int i = 0; i < mrcs.length; i++) {
1530:                    if ((mrcs[i].getFactory() == null)
1531:                            || (mrcs[i].getParameter() == null)) {
1532:                        continue;
1533:                    }
1534:
1535:                    if (log.isDebugEnabled()) {
1536:                        log.debug("Initializing module path '"
1537:                                + config.getPrefix()
1538:                                + "' message resources from '"
1539:                                + mrcs[i].getParameter() + "'");
1540:                    }
1541:
1542:                    String factory = mrcs[i].getFactory();
1543:
1544:                    MessageResourcesFactory.setFactoryClass(factory);
1545:
1546:                    MessageResourcesFactory factoryObject = MessageResourcesFactory
1547:                            .createFactory();
1548:
1549:                    factoryObject.setConfig(mrcs[i]);
1550:
1551:                    MessageResources resources = factoryObject
1552:                            .createResources(mrcs[i].getParameter());
1553:
1554:                    resources.setReturnNull(mrcs[i].getNull());
1555:                    resources.setEscape(mrcs[i].isEscape());
1556:                    getServletContext().setAttribute(
1557:                            mrcs[i].getKey() + config.getPrefix(), resources);
1558:                }
1559:            }
1560:
1561:            /**
1562:             * <p>Create (if needed) and return a new <code>Digester</code> instance
1563:             * that has been initialized to process Struts module configuration files
1564:             * and configure a corresponding <code>ModuleConfig</code> object (which
1565:             * must be pushed on to the evaluation stack before parsing begins).</p>
1566:             *
1567:             * @return A new configured <code>Digester</code> instance.
1568:             * @throws ServletException if a Digester cannot be configured
1569:             * @since Struts 1.1
1570:             */
1571:            protected Digester initConfigDigester() throws ServletException {
1572:                // :FIXME: Where can ServletException be thrown?
1573:                // Do we have an existing instance?
1574:                if (configDigester != null) {
1575:                    return (configDigester);
1576:                }
1577:
1578:                // Create a new Digester instance with standard capabilities
1579:                configDigester = new Digester();
1580:                configDigester.setNamespaceAware(true);
1581:                configDigester.setValidating(this .isValidating());
1582:                configDigester.setUseContextClassLoader(true);
1583:                configDigester.addRuleSet(new ConfigRuleSet());
1584:
1585:                for (int i = 0; i < registrations.length; i += 2) {
1586:                    URL url = this .getClass().getResource(registrations[i + 1]);
1587:
1588:                    if (url != null) {
1589:                        configDigester.register(registrations[i], url
1590:                                .toString());
1591:                    }
1592:                }
1593:
1594:                this .addRuleSets();
1595:
1596:                // Return the completely configured Digester instance
1597:                return (configDigester);
1598:            }
1599:
1600:            /**
1601:             * <p>Add any custom RuleSet instances to configDigester that have been
1602:             * specified in the <code>rulesets</code> init parameter.</p>
1603:             *
1604:             * @throws ServletException if an error occurs
1605:             */
1606:            private void addRuleSets() throws ServletException {
1607:                String rulesets = getServletConfig().getInitParameter(
1608:                        "rulesets");
1609:
1610:                if (rulesets == null) {
1611:                    rulesets = "";
1612:                }
1613:
1614:                rulesets = rulesets.trim();
1615:
1616:                String ruleset;
1617:
1618:                while (rulesets.length() > 0) {
1619:                    int comma = rulesets.indexOf(",");
1620:
1621:                    if (comma < 0) {
1622:                        ruleset = rulesets.trim();
1623:                        rulesets = "";
1624:                    } else {
1625:                        ruleset = rulesets.substring(0, comma).trim();
1626:                        rulesets = rulesets.substring(comma + 1).trim();
1627:                    }
1628:
1629:                    if (log.isDebugEnabled()) {
1630:                        log
1631:                                .debug("Configuring custom Digester Ruleset of type "
1632:                                        + ruleset);
1633:                    }
1634:
1635:                    try {
1636:                        RuleSet instance = (RuleSet) RequestUtils
1637:                                .applicationInstance(ruleset);
1638:
1639:                        this .configDigester.addRuleSet(instance);
1640:                    } catch (Exception e) {
1641:                        log
1642:                                .error(
1643:                                        "Exception configuring custom Digester RuleSet",
1644:                                        e);
1645:                        throw new ServletException(e);
1646:                    }
1647:                }
1648:            }
1649:
1650:            /**
1651:             * <p>Check the status of the <code>validating</code> initialization
1652:             * parameter.</p>
1653:             *
1654:             * @return true if the module Digester should validate.
1655:             */
1656:            private boolean isValidating() {
1657:                boolean validating = true;
1658:                String value = getServletConfig()
1659:                        .getInitParameter("validating");
1660:
1661:                if ("false".equalsIgnoreCase(value)
1662:                        || "no".equalsIgnoreCase(value)
1663:                        || "n".equalsIgnoreCase(value)
1664:                        || "0".equalsIgnoreCase(value)) {
1665:                    validating = false;
1666:                }
1667:
1668:                return validating;
1669:            }
1670:
1671:            /**
1672:             * <p>Initialize our internal MessageResources bundle.</p>
1673:             *
1674:             * @throws ServletException     if we cannot initialize these resources
1675:             * @throws UnavailableException if we cannot load  resources
1676:             */
1677:            protected void initInternal() throws ServletException {
1678:                try {
1679:                    internal = MessageResources
1680:                            .getMessageResources(internalName);
1681:                } catch (MissingResourceException e) {
1682:                    log.error("Cannot load internal resources from '"
1683:                            + internalName + "'", e);
1684:                    throw new UnavailableException(
1685:                            "Cannot load internal resources from '"
1686:                                    + internalName + "'");
1687:                }
1688:            }
1689:
1690:            /**
1691:             * <p>Parse the configuration documents specified by the
1692:             * <code>chainConfig</code> init-param to configure the default {@link
1693:             * org.apache.commons.chain.Catalog} that is registered in the {@link
1694:             * CatalogFactory} instance for this application.</p>
1695:             *
1696:             * @throws ServletException if an error occurs.
1697:             */
1698:            protected void initChain() throws ServletException {
1699:                // Parse the configuration file specified by path or resource
1700:                try {
1701:                    String value;
1702:
1703:                    value = getServletConfig().getInitParameter("chainConfig");
1704:
1705:                    if (value != null) {
1706:                        chainConfig = value;
1707:                    }
1708:
1709:                    ConfigParser parser = new ConfigParser();
1710:                    List urls = splitAndResolvePaths(chainConfig);
1711:                    URL resource;
1712:
1713:                    for (Iterator i = urls.iterator(); i.hasNext();) {
1714:                        resource = (URL) i.next();
1715:                        log.info("Loading chain catalog from " + resource);
1716:                        parser.parse(resource);
1717:                    }
1718:                } catch (Exception e) {
1719:                    log.error("Exception loading resources", e);
1720:                    throw new ServletException(e);
1721:                }
1722:            }
1723:
1724:            /**
1725:             * <p>Initialize other global characteristics of the controller
1726:             * servlet.</p>
1727:             *
1728:             * @throws ServletException if we cannot initialize these resources
1729:             */
1730:            protected void initOther() throws ServletException {
1731:                String value;
1732:
1733:                value = getServletConfig().getInitParameter("config");
1734:
1735:                if (value != null) {
1736:                    config = value;
1737:                }
1738:
1739:                // Backwards compatibility for form beans of Java wrapper classes
1740:                // Set to true for strict Struts 1.0 compatibility
1741:                value = getServletConfig().getInitParameter("convertNull");
1742:
1743:                if ("true".equalsIgnoreCase(value)
1744:                        || "yes".equalsIgnoreCase(value)
1745:                        || "on".equalsIgnoreCase(value)
1746:                        || "y".equalsIgnoreCase(value)
1747:                        || "1".equalsIgnoreCase(value)) {
1748:                    convertNull = true;
1749:                }
1750:
1751:                if (convertNull) {
1752:                    ConvertUtils.deregister();
1753:                    ConvertUtils.register(new BigDecimalConverter(null),
1754:                            BigDecimal.class);
1755:                    ConvertUtils.register(new BigIntegerConverter(null),
1756:                            BigInteger.class);
1757:                    ConvertUtils.register(new BooleanConverter(null),
1758:                            Boolean.class);
1759:                    ConvertUtils.register(new ByteConverter(null), Byte.class);
1760:                    ConvertUtils.register(new CharacterConverter(null),
1761:                            Character.class);
1762:                    ConvertUtils.register(new DoubleConverter(null),
1763:                            Double.class);
1764:                    ConvertUtils
1765:                            .register(new FloatConverter(null), Float.class);
1766:                    ConvertUtils.register(new IntegerConverter(null),
1767:                            Integer.class);
1768:                    ConvertUtils.register(new LongConverter(null), Long.class);
1769:                    ConvertUtils
1770:                            .register(new ShortConverter(null), Short.class);
1771:                }
1772:            }
1773:
1774:            /**
1775:             * <p>Initialize the servlet mapping under which our controller servlet is
1776:             * being accessed.  This will be used in the <code>&html:form&gt;</code>
1777:             * tag to generate correct destination URLs for form submissions.</p>
1778:             *
1779:             * @throws ServletException if error happens while scanning web.xml
1780:             */
1781:            protected void initServlet() throws ServletException {
1782:                // Remember our servlet name
1783:                this .servletName = getServletConfig().getServletName();
1784:
1785:                // Prepare a Digester to scan the web application deployment descriptor
1786:                Digester digester = new Digester();
1787:
1788:                digester.push(this );
1789:                digester.setNamespaceAware(true);
1790:                digester.setValidating(false);
1791:
1792:                // Register our local copy of the DTDs that we can find
1793:                for (int i = 0; i < registrations.length; i += 2) {
1794:                    URL url = this .getClass().getResource(registrations[i + 1]);
1795:
1796:                    if (url != null) {
1797:                        digester.register(registrations[i], url.toString());
1798:                    }
1799:                }
1800:
1801:                // Configure the processing rules that we need
1802:                digester.addCallMethod("web-app/servlet-mapping",
1803:                        "addServletMapping", 2);
1804:                digester
1805:                        .addCallParam("web-app/servlet-mapping/servlet-name", 0);
1806:                digester.addCallParam("web-app/servlet-mapping/url-pattern", 1);
1807:
1808:                // Process the web application deployment descriptor
1809:                if (log.isDebugEnabled()) {
1810:                    log
1811:                            .debug("Scanning web.xml for controller servlet mapping");
1812:                }
1813:
1814:                InputStream input = getServletContext().getResourceAsStream(
1815:                        "/WEB-INF/web.xml");
1816:
1817:                if (input == null) {
1818:                    log.error(internal.getMessage("configWebXml"));
1819:                    throw new ServletException(internal
1820:                            .getMessage("configWebXml"));
1821:                }
1822:
1823:                try {
1824:                    digester.parse(input);
1825:                } catch (IOException e) {
1826:                    log.error(internal.getMessage("configWebXml"), e);
1827:                    throw new ServletException(e);
1828:                } catch (SAXException e) {
1829:                    log.error(internal.getMessage("configWebXml"), e);
1830:                    throw new ServletException(e);
1831:                } finally {
1832:                    try {
1833:                        input.close();
1834:                    } catch (IOException e) {
1835:                        log.error(internal.getMessage("configWebXml"), e);
1836:                        throw new ServletException(e);
1837:                    }
1838:                }
1839:
1840:                // Record a servlet context attribute (if appropriate)
1841:                if (log.isDebugEnabled()) {
1842:                    log.debug("Mapping for servlet '" + servletName + "' = '"
1843:                            + servletMapping + "'");
1844:                }
1845:
1846:                if (servletMapping != null) {
1847:                    getServletContext().setAttribute(Globals.SERVLET_KEY,
1848:                            servletMapping);
1849:                }
1850:            }
1851:
1852:            /**
1853:             * <p>Takes a comma-delimited string and splits it into paths, then
1854:             * resolves those paths using the ServletContext and appropriate
1855:             * ClassLoader.  When loading from the classloader, multiple resources per
1856:             * path are supported to support, for example, multiple jars containing
1857:             * the same named config file.</p>
1858:             *
1859:             * @param paths A comma-delimited string of paths
1860:             * @return A list of resolved URL's for all found resources
1861:             * @throws ServletException if a servlet exception is thrown
1862:             */
1863:            protected List splitAndResolvePaths(String paths)
1864:                    throws ServletException {
1865:                ClassLoader loader = Thread.currentThread()
1866:                        .getContextClassLoader();
1867:
1868:                if (loader == null) {
1869:                    loader = this .getClass().getClassLoader();
1870:                }
1871:
1872:                ArrayList resolvedUrls = new ArrayList();
1873:
1874:                URL resource;
1875:                String path = null;
1876:
1877:                try {
1878:                    // Process each specified resource path
1879:                    while (paths.length() > 0) {
1880:                        resource = null;
1881:
1882:                        int comma = paths.indexOf(',');
1883:
1884:                        if (comma >= 0) {
1885:                            path = paths.substring(0, comma).trim();
1886:                            paths = paths.substring(comma + 1);
1887:                        } else {
1888:                            path = paths.trim();
1889:                            paths = "";
1890:                        }
1891:
1892:                        if (path.length() < 1) {
1893:                            break;
1894:                        }
1895:
1896:                        if (path.charAt(0) == '/') {
1897:                            resource = getServletContext().getResource(path);
1898:                        }
1899:
1900:                        if (resource == null) {
1901:                            if (log.isDebugEnabled()) {
1902:                                log.debug("Unable to locate " + path
1903:                                        + " in the servlet context, "
1904:                                        + "trying classloader.");
1905:                            }
1906:
1907:                            Enumeration e = loader.getResources(path);
1908:
1909:                            if (!e.hasMoreElements()) {
1910:                                String msg = internal.getMessage(
1911:                                        "configMissing", path);
1912:
1913:                                log.error(msg);
1914:                                throw new UnavailableException(msg);
1915:                            } else {
1916:                                while (e.hasMoreElements()) {
1917:                                    resolvedUrls.add(e.nextElement());
1918:                                }
1919:                            }
1920:                        } else {
1921:                            resolvedUrls.add(resource);
1922:                        }
1923:                    }
1924:                } catch (MalformedURLException e) {
1925:                    handleConfigException(path, e);
1926:                } catch (IOException e) {
1927:                    handleConfigException(path, e);
1928:                }
1929:
1930:                return resolvedUrls;
1931:            }
1932:
1933:            /**
1934:             * <p>Perform the standard request processing for this request, and create
1935:             * the corresponding response.</p>
1936:             *
1937:             * @param request  The servlet request we are processing
1938:             * @param response The servlet response we are creating
1939:             * @throws IOException      if an input/output error occurs
1940:             * @throws ServletException if a servlet exception is thrown
1941:             */
1942:            protected void process(HttpServletRequest request,
1943:                    HttpServletResponse response) throws IOException,
1944:                    ServletException {
1945:                ModuleUtils.getInstance().selectModule(request,
1946:                        getServletContext());
1947:
1948:                ModuleConfig config = getModuleConfig(request);
1949:
1950:                RequestProcessor processor = getProcessorForModule(config);
1951:
1952:                if (processor == null) {
1953:                    processor = getRequestProcessor(config);
1954:                }
1955:
1956:                processor.process(request, response);
1957:            }
1958:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.