You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by cr...@apache.org on 2002/01/13 01:25:38 UTC

cvs commit: jakarta-struts/web/exercise-taglib/WEB-INF web.xml

craigmcc    02/01/12 16:25:37

  Modified:    conf/share struts-config_1_1.dtd
               doc      struts-bean.xml struts-html.xml struts-logic.xml
               src/example/org/apache/struts/webapp/example
                        EditRegistrationAction.java
                        EditSubscriptionAction.java
                        SaveRegistrationAction.java
                        SaveSubscriptionAction.java
               src/share/org/apache/struts/action Action.java
                        ActionError.java ActionException.java
                        ActionFormBean.java ActionFormBeans.java
                        ActionForward.java ActionForwards.java
                        ActionMapping.java ActionMappings.java
                        ActionMessage.java ActionResources.properties
                        ActionServlet.java ActionServletWrapper.java
                        ExceptionHandler.java
               src/share/org/apache/struts/actions
                        LookupDispatchAction.java
               src/share/org/apache/struts/config ActionConfig.java
                        ApplicationConfig.java ConfigRuleSet.java
                        ControllerConfig.java DataSourceConfig.java
                        ExceptionConfig.java ForwardConfig.java
                        MessageResourcesConfig.java
               src/share/org/apache/struts/taglib/bean IncludeTag.java
                        MessageTag.java ResourceTag.java StrutsTag.java
               src/share/org/apache/struts/taglib/html ErrorsTag.java
                        FormTag.java ImageTag.java ImgTag.java LinkTag.java
                        RewriteTag.java
               src/share/org/apache/struts/taglib/logic ForwardTag.java
                        RedirectTag.java
               src/share/org/apache/struts/taglib/template InsertTag.java
               src/share/org/apache/struts/upload
                        DiskMultipartRequestHandler.java
               src/share/org/apache/struts/util RequestUtils.java
               web/exercise-taglib html-select.jsp
               web/exercise-taglib/WEB-INF web.xml
  Added:       src/exercise-taglib/org/apache/struts/webapp/exercise
                        ApplicationResources.properties
  Removed:     src/share/org/apache/struts/action ActionExceptions.java
                        ContextHelper.java
               src/share/org/apache/struts/actions AddFormBeanAction.java
                        AddForwardAction.java AddMappingAction.java
                        ReloadAction.java RemoveFormBeanAction.java
                        RemoveForwardAction.java RemoveMappingAction.java
  Log:
  Initial check-in of the *big* changes for multi-application support.
  
  All the existing standard apps work -- haven't tested the contrib stuff yet.
  
  WARNING:  The head branch is probably going to be unstable for a while
  until these changes settle down.
  
  Revision  Changes    Path
  1.6       +47 -34    jakarta-struts/conf/share/struts-config_1_1.dtd
  
  Index: struts-config_1_1.dtd
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/conf/share/struts-config_1_1.dtd,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- struts-config_1_1.dtd	31 Dec 2001 01:58:26 -0000	1.5
  +++ struts-config_1_1.dtd	13 Jan 2002 00:25:35 -0000	1.6
  @@ -11,7 +11,7 @@
          "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
          "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
   
  -     $Id: struts-config_1_1.dtd,v 1.5 2001/12/31 01:58:26 craigmcc Exp $
  +     $Id: struts-config_1_1.dtd,v 1.6 2002/01/13 00:25:35 craigmcc Exp $
   -->
   
   
  @@ -59,8 +59,8 @@
   <!ENTITY % PropName "CDATA">
   
   
  -<!-- A "RequestPath" is a context-relative URI path, beginning with a slash,
  -     that identifies a mapped resource (such as a JSP page or a servlet)
  +<!-- A "RequestPath" is an application-relative URI path, beginning with a
  +     slash, that identifies a mapped resource (such as a JSP page or a servlet)
        within this web application.
   -->
   <!ENTITY % RequestPath "CDATA">
  @@ -159,7 +159,7 @@
   
   <!-- The "global-exceptions" element configures the global handling of
        exceptions thrown by Actions to mappable resources (identified by
  -     context-relative URI paths).  A global "exception" handler for a
  +     application-relative URI paths).  A global "exception" handler for a
        particular exception class can be locally overridden by defining an
        "exception" element with the same "type" attribute.
   -->
  @@ -174,13 +174,10 @@
       handler          Fully qualified Java class name of the exception handler
                        which should handle this exception.
   
  -    hierarchical     Determines if the exception's class hierarchy should be
  -                     used to determine the correct handler.
  -
       key              Message resources key specifying the error message
                        associated with this exception.
   
  -    path             The context-relative path of the resource to
  +    path             The application-relative path of the resource to
                        forward to if this exception occurs.
   
       scope            Identifier of the scope ("request" or "session")
  @@ -193,7 +190,6 @@
   <!ELEMENT exception (icon?, display-name?, description?, set-property*)>
   <!ATTLIST exception      id             ID              #IMPLIED>
   <!ATTLIST exception      handler        %ClassName;     "org.apache.struts.action.ExceptionHandler">
  -<!ATTLIST exception      hierarchical   %Boolean;       #IMPLIED>
   <!ATTLIST exception      key            CDATA           #IMPLIED>
   <!ATTLIST exception      path           %RequestPath;   #IMPLIED>
   <!ATTLIST exception      scope          CDATA           #IMPLIED>
  @@ -240,9 +236,9 @@
   
   <!-- The "global-forwards" element configures the global mappings of logical
        names (used within the application) to mappable resources (identified
  -     by context-relative URI paths).  A global "forward" with a particular name
  -     can be locally overridden by defining a "forward" of the same name within
  -     an "action" element.  The following attribute are defined:
  +     by application-relative URI paths).  A global "forward" with a particular
  +     name can be locally overridden by defining a "forward" of the same name
  +     within an "action" element.  The following attribute are defined:
   
        type            Fully qualified Java class name of the implementation
                        class used for ActionForward objects.  DEPRECATED.
  @@ -258,18 +254,24 @@
   
   
   <!-- The "forward" element describes a mapping of a logical name (used within
  -     the application) to a mappable resource identified by a context-relative
  -     URI path.  The following attributes are defined:
  +     the application) to a mappable resource identified by an
  +     application-relative URI path.  The following attributes are defined:
   
        className       Fully qualified Java class name of the ActionForward
                        implementation class to use.  Defaults to the value
                        configured as the "forward" initialization parameter
                        to the Struts controller servlet.
   
  +    contextRelative  Set to "true" if the path should be considered relative
  +                     to the entire web application, rather than prefixed with
  +                     the sub-application prefix, if it starts with a "/".
  +
        name            Unique identifier of this forward, used to reference it
                        in application action classes.
   
  -     path            The context-relative path of the mapped resource.
  +     path            The application-relative or context-relative path of
  +                     the mapped resource (determined by the selected value
  +                     for the "contextRelative" attribute).
   
        redirect        Set to "true" if sendRedirect() should be used to forward
                        to this resource, or "false" in order to use
  @@ -278,6 +280,7 @@
   <!ELEMENT forward (icon?, display-name?, description?, set-property*)>
   <!ATTLIST forward        id             ID              #IMPLIED>
   <!ATTLIST forward        className      %ClassName;     #IMPLIED>
  +<!ATTLIST forward        contextRelative %Boolean;      #IMPLIED>
   <!ATTLIST forward        name           CDATA           #REQUIRED>
   <!ATTLIST forward        path           %RequestPath;   #REQUIRED>
   <!ATTLIST forward        redirect       %Boolean;       #IMPLIED>
  @@ -315,27 +318,29 @@
                        configured as the "mapping" initialization parameter
                        to the Struts controller servlet.
   
  -     forward         Context-relative path of the servlet or JSP resource that
  -                     will process this request, instead of instantiating and
  -                     calling the Action class specified by "type".  Exactly one
  -                     of "forward", "include", or "type" must be specified.
  -
  -     include         Context-relative path of the servlet or JSP resource that
  -                     will process this request, instead of instantiating and
  -                     calling the Action class specified by "type".  Exactly one
  -                     of "forward", "include", or "type" must be specified.
  -
  -     input           Context-relative path of the input form to which control
  -                     should be returned if a validation error is encountered.
  -                     Required if "name" is specified and the input bean
  -                     returns validation errors.  Optional if "name" is
  -                     specified and the input bean does not return validation
  +     forward         Application-relative path of the servlet or JSP resource
  +                     that will process this request, instead of instantiating
  +                     and calling the Action class specified by "type".
  +                     Exactly one of "forward", "include", or "type" must be
  +                     specified.
  +
  +     include         Application-relative path of the servlet or JSP resource
  +                     that will process this request, instead of instantiating
  +                     and calling the Action class specified by "type".
  +                     Exactly one of "forward", "include", or "type" must be
  +                     specified.
  +
  +     input           Application-relative path of the input form to which
  +                     control should be returned if a validation error is
  +                     encountered.  Required if "name" is specified and the
  +                     input bean returns validation errors.  Optional if "name"
  +                     is specified and the input bean does not return validation
                        errors.  Not allowed if "name" is not specified.
   
        name            Name of the form bean, if any, that is associated
                        with this action.
   
  -     path            The context-relative path of the submitted request,
  +     path            The Application-relative path of the submitted request,
                        starting with a "/" character, and without the
                        filename extension if extension mapping is used.
   
  @@ -399,6 +404,8 @@
                        to be set on each response.  May be overridden by a
                        forwarded-to servlet or JSP page.  [text/html]
   
  +     debug           Debugging detail level for this application.  [0]
  +
        locale          Set to true if you want a Locale object stored in the
                        user's session if not already present.  [true]
   
  @@ -407,6 +414,10 @@
                        by a "K", "M", or "G", which are interpreted to mean
                        kilobytes, megabytes, or gigabytes, respectively.  [250M]
   
  +     multipartClass  The fully qualified Java class name of the multipart
  +                     request handler class to be used.
  +                     [org.apache.struts.upload.DiskMultipartRequestHandler]
  +
        nocache         Set to <code>true</code> if you want Struts to add
                        HTTP headers for defeating caching to every response.
                        [false]
  @@ -416,11 +427,13 @@
   -->
   <!ELEMENT controller     EMPTY>
   <!ATTLIST controller     id             ID              #IMPLIED>
  -<!ATTLIST controller     bufferSize     %Integer;        #IMPLIED>
  +<!ATTLIST controller     bufferSize     %Integer;       #IMPLIED>
   <!ATTLIST controller     contentType    CDATA           #IMPLIED>
  -<!ATTLIST controller     locale         %Boolean;        #IMPLIED>
  +<!ATTLIST controller     debug          %Integer;       #IMPLIED>  
  +<!ATTLIST controller     locale         %Boolean;       #IMPLIED>
   <!ATTLIST controller     maxFileSize    CDATA           #IMPLIED>
  -<!ATTLIST controller     nocache        %Boolean;        #IMPLIED>
  +<!ATTLIST controller     multipartClass %ClassName;     #IMPLIED>
  +<!ATTLIST controller     nocache        %Boolean;       #IMPLIED>
   <!ATTLIST controller     tempDir        CDATA           #IMPLIED>
   
   
  
  
  
  1.10      +7 -7      jakarta-struts/doc/struts-bean.xml
  
  Index: struts-bean.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/doc/struts-bean.xml,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- struts-bean.xml	17 Dec 2001 11:10:30 -0000	1.9
  +++ struts-bean.xml	13 Jan 2002 00:25:35 -0000	1.10
  @@ -343,12 +343,12 @@
       <ul>
       <li><em>forward</em> - Use the value of this attribute as the name
           of a global <code>ActionForward</code> to be looked up, and
  -        use the context-relative URI found there.</li>
  +        use the application-relative or context-relative URI found there.</li>
       <li><em>href</em> - Use the value of this attribute unchanged (since
           this might link to a resource external to the application, the
           session identifier is <strong>not</strong> included.</li>
  -    <li><em>page</em> - Use the value of this attribute as a context-relative
  -        URI to the desired resource.</li>
  +    <li><em>page</em> - Use the value of this attribute as an
  +        application-relative URI to the desired resource.</li>
       </ul>
       </info>
   
  @@ -401,8 +401,8 @@
         <required>false</required>
         <rtexprvalue>true</rtexprvalue>
         <info>
  -      <p>Context-relative name (starting with a '/') of the web application
  -      request to be dispatched, and whose response data is to be made
  +      <p>Application-relative name (starting with a '/') of the web application
  +      resource to be dispatched, and whose response data is to be made
         available as a bean.  <strong>DEPRECATED - Use the "page" attribute
         instead</strong>.</p>
         </info>
  @@ -413,7 +413,7 @@
         <required>false</required>
         <rtexprvalue>true</rtexprvalue>
         <info>
  -      <p>Context-relative URI (starting with a '/') of the web application
  +      <p>Application-relative URI (starting with a '/') of the web application
         resource to be included.</p>
         </info>
       </attribute>
  @@ -729,7 +729,7 @@
         <required>true</required>
         <rtexprvalue>true</rtexprvalue>
         <info>
  -      <p>Context-relative name (starting with a '/') of the web application
  +      <p>Application-relative name (starting with a '/') of the web application
         resource to be loaded and made available.</p>
         </info>
       </attribute>
  
  
  
  1.29      +11 -9     jakarta-struts/doc/struts-html.xml
  
  Index: struts-html.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/doc/struts-html.xml,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- struts-html.xml	28 Dec 2001 06:57:19 -0000	1.28
  +++ struts-html.xml	13 Jan 2002 00:25:35 -0000	1.29
  @@ -1640,7 +1640,7 @@
                   <required>false</required>
                   <rtexprvalue>true</rtexprvalue>
                   <info>
  -                <p>The context-relative path of the image for this
  +                <p>The application-relative path of the image for this
                   input tag.</p>
                   </info>
           </attribute>
  @@ -1651,7 +1651,7 @@
                   <rtexprvalue>true</rtexprvalue>
                   <info>
                   <p>The key of the message resources string specifying the
  -                context-relative path of the image for this input tag.</p>
  +                application-relative path of the image for this input tag.</p>
                   </info>
           </attribute>
   
  @@ -2006,7 +2006,7 @@
                     <required>false</required>
                     <rtexprvalue>true</rtexprvalue>
                     <info>
  -                  <p>The context-relative path, starting with a slash, of
  +                  <p>The application-relative path, starting with a slash, of
                     the image to be displayed by this tag.  The rendered
                     URL for this image will automatically prepend the context
                     path of this web application (in the same manner as the
  @@ -2024,7 +2024,7 @@
                     <info>
                     <p>The message key, in the message resources bundle named by
                     the <code>bundle</code> attribute, of the String to be
  -                  used as the context-relative path for this image.</p>
  +                  used as the application-relative path for this image.</p>
                     </info>
                   </attribute>
   
  @@ -2199,12 +2199,14 @@
                   <ul>
                   <li><em>forward</em> - Use the value of this attribute as the
                       name of a global <code>ActionForward</code> to be looked
  -                    up, and use the context-relative URI found there.</li>
  +                    up, and use the application-relative or context-relative
  +                    URI found there.</li>
                   <li><em>href</em> - Use the value of this attribute unchanged.
                       </li>
                   <li><em>page</em> - Use the value of this attribute as a
  -                    context-relative URI, and generate a server-relative URI
  -                    by including the context path.</li>
  +                    application-relative URI, and generate a server-relative
  +                    URI by including the context path and application
  +                    prefix.</li>
                   </ul>
   
                   <p>Normally, the hyperlink you specify with one of the
  @@ -2495,7 +2497,7 @@
                     <required>false</required>
                     <rtexprvalue>true</rtexprvalue>
                     <info>
  -                  <p>The context-relative path (beginning with a "/"
  +                  <p>The applicaiton-relative path (beginning with a "/"
                     character) to which this hyperlink will transfer control
                     if activated.  This hyperlink may be dynamically modified
                     by the inclusion of query parameters, as described in the
  @@ -4067,7 +4069,7 @@
                     <required>false</required>
                     <rtexprvalue>true</rtexprvalue>
                     <info>
  -                  <p>The context-relative path (beginning with a "/"
  +                  <p>The application-relative path (beginning with a "/"
                     character) to which this hyperlink will transfer control
                     if activated.  This hyperlink may be dynamically modified
                     by the inclusion of query parameters, as described in the
  
  
  
  1.11      +5 -4      jakarta-struts/doc/struts-logic.xml
  
  Index: struts-logic.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/doc/struts-logic.xml,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- struts-logic.xml	16 Oct 2001 15:56:35 -0000	1.10
  +++ struts-logic.xml	13 Jan 2002 00:25:35 -0000	1.11
  @@ -1483,12 +1483,13 @@
                   <ul>
                   <li><em>forward</em> - Use the value of this attribute as the
                       name of a global <code>ActionForward</code> to be looked
  -                    up, and use the context-relative URI found there.</li>
  +                    up, and use the application-relative or context-relative
  +                    URI found there.</li>
                   <li><em>href</em> - Use the value of this attribute unchanged.
                       </li>
  -                <li><em>page</em> - Use the value of this attribute as a
  -                    context-relative URI, and generate a server-relative URI
  -                    by including the context path.</li>
  +                <li><em>page</em> - Use the value of this attribute as an
  +                    applicaiton-relative URI, and generate a server-relative
  +                    URI by including the context path.</li>
                   </ul>
   
                   <p>Normally, the redirect you specify with one of the
  
  
  
  1.4       +5 -5      jakarta-struts/src/example/org/apache/struts/webapp/example/EditRegistrationAction.java
  
  Index: EditRegistrationAction.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/example/org/apache/struts/webapp/example/EditRegistrationAction.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- EditRegistrationAction.java	16 Jul 2001 00:44:51 -0000	1.3
  +++ EditRegistrationAction.java	13 Jan 2002 00:25:35 -0000	1.4
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/example/org/apache/struts/webapp/example/EditRegistrationAction.java,v 1.3 2001/07/16 00:44:51 craigmcc Exp $
  - * $Revision: 1.3 $
  - * $Date: 2001/07/16 00:44:51 $
  + * $Header: /home/cvs/jakarta-struts/src/example/org/apache/struts/webapp/example/EditRegistrationAction.java,v 1.4 2002/01/13 00:25:35 craigmcc Exp $
  + * $Revision: 1.4 $
  + * $Date: 2002/01/13 00:25:35 $
    *
    * ====================================================================
    *
  @@ -87,7 +87,7 @@
    * User (if any).
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.3 $ $Date: 2001/07/16 00:44:51 $
  + * @version $Revision: 1.4 $ $Date: 2002/01/13 00:25:35 $
    */
   
   public final class EditRegistrationAction extends Action {
  @@ -136,7 +136,7 @@
   		if (servlet.getDebug() >= 1)
   		    servlet.log(" User is not logged on in session "
   	                        + session.getId());
  -		return (servlet.findForward("logon"));
  +		return (mapping.findForward("logon"));
   	    }
   	}
   
  
  
  
  1.4       +5 -5      jakarta-struts/src/example/org/apache/struts/webapp/example/EditSubscriptionAction.java
  
  Index: EditSubscriptionAction.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/example/org/apache/struts/webapp/example/EditSubscriptionAction.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- EditSubscriptionAction.java	16 Jul 2001 00:44:51 -0000	1.3
  +++ EditSubscriptionAction.java	13 Jan 2002 00:25:35 -0000	1.4
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/example/org/apache/struts/webapp/example/EditSubscriptionAction.java,v 1.3 2001/07/16 00:44:51 craigmcc Exp $
  - * $Revision: 1.3 $
  - * $Date: 2001/07/16 00:44:51 $
  + * $Header: /home/cvs/jakarta-struts/src/example/org/apache/struts/webapp/example/EditSubscriptionAction.java,v 1.4 2002/01/13 00:25:35 craigmcc Exp $
  + * $Revision: 1.4 $
  + * $Date: 2002/01/13 00:25:35 $
    *
    * ====================================================================
    *
  @@ -86,7 +86,7 @@
    * <code>SubscriptionForm</code> from the currently specified subscription.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.3 $ $Date: 2001/07/16 00:44:51 $
  + * @version $Revision: 1.4 $ $Date: 2002/01/13 00:25:35 $
    */
   
   public final class EditSubscriptionAction extends Action {
  @@ -134,7 +134,7 @@
   	    if (servlet.getDebug() >= 1)
   	        servlet.log(" User is not logged on in session "
   	                    + session.getId());
  -	    return (servlet.findForward("logon"));
  +	    return (mapping.findForward("logon"));
   	}
   
   	// Identify the relevant subscription
  
  
  
  1.4       +5 -5      jakarta-struts/src/example/org/apache/struts/webapp/example/SaveRegistrationAction.java
  
  Index: SaveRegistrationAction.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/example/org/apache/struts/webapp/example/SaveRegistrationAction.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- SaveRegistrationAction.java	16 Jul 2001 00:44:51 -0000	1.3
  +++ SaveRegistrationAction.java	13 Jan 2002 00:25:35 -0000	1.4
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/example/org/apache/struts/webapp/example/SaveRegistrationAction.java,v 1.3 2001/07/16 00:44:51 craigmcc Exp $
  - * $Revision: 1.3 $
  - * $Date: 2001/07/16 00:44:51 $
  + * $Header: /home/cvs/jakarta-struts/src/example/org/apache/struts/webapp/example/SaveRegistrationAction.java,v 1.4 2002/01/13 00:25:35 craigmcc Exp $
  + * $Revision: 1.4 $
  + * $Date: 2002/01/13 00:25:35 $
    *
    * ====================================================================
    *
  @@ -89,7 +89,7 @@
    * registration is created, the user is also implicitly logged on.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.3 $ $Date: 2001/07/16 00:44:51 $
  + * @version $Revision: 1.4 $ $Date: 2002/01/13 00:25:35 $
    */
   
   public final class SaveRegistrationAction extends Action {
  @@ -139,7 +139,7 @@
               if (servlet.getDebug() >= 1)
                   servlet.log(" User is not logged on in session "
                               + session.getId());
  -	    return (servlet.findForward("logon"));
  +	    return (mapping.findForward("logon"));
           }
   
   	// Was this transaction cancelled?
  
  
  
  1.4       +5 -5      jakarta-struts/src/example/org/apache/struts/webapp/example/SaveSubscriptionAction.java
  
  Index: SaveSubscriptionAction.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/example/org/apache/struts/webapp/example/SaveSubscriptionAction.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- SaveSubscriptionAction.java	16 Jul 2001 00:44:51 -0000	1.3
  +++ SaveSubscriptionAction.java	13 Jan 2002 00:25:35 -0000	1.4
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/example/org/apache/struts/webapp/example/SaveSubscriptionAction.java,v 1.3 2001/07/16 00:44:51 craigmcc Exp $
  - * $Revision: 1.3 $
  - * $Date: 2001/07/16 00:44:51 $
  + * $Header: /home/cvs/jakarta-struts/src/example/org/apache/struts/webapp/example/SaveSubscriptionAction.java,v 1.4 2002/01/13 00:25:35 craigmcc Exp $
  + * $Revision: 1.4 $
  + * $Date: 2002/01/13 00:25:35 $
    *
    * ====================================================================
    *
  @@ -88,7 +88,7 @@
    * updates the mail subscription entered by the user.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.3 $ $Date: 2001/07/16 00:44:51 $
  + * @version $Revision: 1.4 $ $Date: 2002/01/13 00:25:35 $
    */
   
   public final class SaveSubscriptionAction extends Action {
  @@ -136,7 +136,7 @@
               if (servlet.getDebug() >= 1)
                   servlet.log(" User is not logged on in session "
                               + session.getId());
  -	    return (servlet.findForward("logon"));
  +	    return (mapping.findForward("logon"));
           }
   
   	// Is there a related Subscription object?
  
  
  
  1.1                  jakarta-struts/src/exercise-taglib/org/apache/struts/webapp/exercise/ApplicationResources.properties
  
  	<<Binary file>>
  
  
  1.34      +130 -75   jakarta-struts/src/share/org/apache/struts/action/Action.java
  
  Index: Action.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/Action.java,v
  retrieving revision 1.33
  retrieving revision 1.34
  diff -u -r1.33 -r1.34
  --- Action.java	31 Dec 2001 01:14:36 -0000	1.33
  +++ Action.java	13 Jan 2002 00:25:35 -0000	1.34
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/Action.java,v 1.33 2001/12/31 01:14:36 craigmcc Exp $
  - * $Revision: 1.33 $
  - * $Date: 2001/12/31 01:14:36 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/Action.java,v 1.34 2002/01/13 00:25:35 craigmcc Exp $
  + * $Revision: 1.34 $
  + * $Date: 2002/01/13 00:25:35 $
    *
    * ====================================================================
    *
  @@ -84,11 +84,12 @@
    * HTTP request and the corresponding business logic that should be executed to
    * process this request.  The controller (ActionServlet) will select an
    * appropriate Action for each request, create an instance (if necessary),
  - * and call the <code>perform</code> method.
  - * <p>
  - * Actions must be programmed in a thread-safe manner, because the controller
  - * will share the same instance for multiple simultaneous requests.  In
  - * this means you should design with the following items in mind:
  + * and call the <code>perform</code> method.</p>
  + *
  + * <p>Actions must be programmed in a thread-safe manner, because the
  + * controller will share the same instance for multiple simultaneous
  + * requests.  This means you should design with the following items in mind:
  + * </p>
    * <ul>
    * <li>Instance and static variables MUST NOT be used to store information
    *     related to the state of a particular request.  They MAY be used to
  @@ -98,17 +99,17 @@
    *     however, resource classes should be designed to provide their own
    *     protection where necessary.</li>
    * </ul>
  - * <p>
  - * When an <code>Action</code> instance is first created, the controller
  + *
  + * <p>When an <code>Action</code> instance is first created, the controller
    * servlet will call <code>setServlet()</code> with a non-null argument to
    * identify the controller servlet instance to which this Action is attached.
    * When the controller servlet is to be shut down (or restarted), the
    * <code>setServlet()</code> method will be called with a <code>null</code>
    * argument, which can be used to clean up any allocated resources in use
  - * by this Action.
  + * by this Action.</p>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.33 $ $Date: 2001/12/31 01:14:36 $
  + * @version $Revision: 1.34 $ $Date: 2002/01/13 00:25:35 $
    */
   
   public class Action {
  @@ -150,13 +151,6 @@
       public static final String ERROR_KEY =
         "org.apache.struts.action.ERROR";
   
  -    /**
  -     * The request attributes key under which your action should store an
  -     * <code>org.apache.struts.action.ActionMessages</code> object, if you
  -     * are using the corresponding custom tag library elements.
  -     */
  -    public static final String MESSAGE_KEY =
  -      "org.apache.struts.action.ACTION_MESSAGE";
   
       /**
        * The request attributes key under which Struts custom tags might store a
  @@ -173,6 +167,8 @@
        * <code>org.apache.struts.action.ActionFormBeans</code> collection
        * is normally stored, unless overridden when initializing our
        * ActionServlet.
  +     *
  +     * @deprecated Replaced by collection in ApplicationConfig
        */
       public static final String FORM_BEANS_KEY =
           "org.apache.struts.action.FORM_BEANS";
  @@ -183,6 +179,8 @@
        * <code>org.apache.struts.action.ActionForwards</code> collection
        * is normally stored, unless overridden when initializing our
        * ActionServlet.
  +     *
  +     * @deprecated Replaced by collection in ApplicationConfig.
        */
       public static final String FORWARDS_KEY =
         "org.apache.struts.action.FORWARDS";
  @@ -213,15 +211,27 @@
        * <code>org.apache.struts.action.ActionMappings</code> collection
        * is normally stored, unless overridden when initializing our
        * ActionServlet.
  +     *
  +     * @deprecated Replaced by collection in ApplicationConfig
        */
       public static final String MAPPINGS_KEY =
         "org.apache.struts.action.MAPPINGS";
   
   
       /**
  -     * <p>The context attributes key under which our application resources are
  -     * normally stored, unless overridden when initializing our ActionServlet.
  -     * </p>
  +     * The request attributes key under which your action should store an
  +     * <code>org.apache.struts.action.ActionMessages</code> object, if you
  +     * are using the corresponding custom tag library elements.
  +     */
  +    public static final String MESSAGE_KEY =
  +      "org.apache.struts.action.ACTION_MESSAGE";
  +
  +
  +    /**
  +     * <p>The base of the context attributes key under which our
  +     * application <code>MessageResources</code> will be stored.  This
  +     * will be suffixed with the actual application prefix (including the
  +     * leading "/" character) to form the actual resources key.</p>
        *
        * <p>For each request processed by the controller servlet, the
        * <code>MessageResources</code> object for the application selected by
  @@ -304,6 +314,56 @@
   
   
       /**
  +     * Process the specified HTTP request, and create the corresponding HTTP
  +     * response (or forward to another web component that will create it),
  +     * with provision for handling exceptions thrown by the business logic.
  +     *
  +     * @param mapping The ActionMapping used to select this instance
  +     * @param form The optional ActionForm bean for this request (if any)
  +     * @param request The non-HTTP request we are processing
  +     * @param response The non-HTTP response we are creating
  +     *
  +     * @exception Exception if the application business logic throws
  +     *  an exception
  +     */
  +    public ActionForward execute(ActionMapping mapping,
  +                                 ActionForm form,
  +                                 ServletRequest request,
  +                                 ServletResponse response)
  +        throws Exception {
  +
  +        // Call the deprecated method for backwards compatibility
  +        return (perform(mapping, form, request, response));
  +
  +    }
  +
  +
  +    /**
  +     * Process the specified HTTP request, and create the corresponding HTTP
  +     * response (or forward to another web component that will create it),
  +     * with provision for handling exceptions thrown by the business logic.
  +     *
  +     * @param mapping The ActionMapping used to select this instance
  +     * @param form The optional ActionForm bean for this request (if any)
  +     * @param request The HTTP request we are processing
  +     * @param response The HTTP response we are creating
  +     *
  +     * @exception Exception if the application business logic throws
  +     *  an exception
  +     */
  +    public ActionForward execute(ActionMapping mapping,
  +                                 ActionForm form,
  +                                 HttpServletRequest request,
  +                                 HttpServletResponse response)
  +        throws Exception {
  +
  +        // Call the deprecated method for backwards compatibility
  +        return (perform(mapping, form, request, response));
  +
  +    }
  +
  +
  +    /**
        * Process the specified non-HTTP request, and create the corresponding
        * non-HTTP response (or forward to another web component that will create
        * it).  Return an <code>ActionForward</code> instance describing where
  @@ -368,31 +428,6 @@
       }
   
   
  -    /**
  -     * Process the specified HTTP request, and create the corresponding HTTP
  -     * response (or forward to another web component that will create it),
  -     * with provision for handling exceptions thrown by the business logic.
  -     *
  -     * @param mapping The ActionMapping used to select this instance
  -     * @param form The optional ActionForm bean for this request (if any)
  -     * @param request The HTTP request we are processing
  -     * @param response The HTTP response we are creating
  -     *
  -     * @exception Exception if the application business logic throws
  -     *  an exception
  -     */
  -    public ActionForward execute(ActionMapping mapping,
  -                                 ActionForm form,
  -                                 HttpServletRequest request,
  -                                 HttpServletResponse response)
  -        throws Exception {
  -
  -        // Call the deprecated method
  -        return (perform(mapping, form, request, response));
  -
  -    }
  -
  -
       // ---------------------------------------------------- Protected Methods
   
   
  @@ -429,26 +464,44 @@
        */
       protected Locale getLocale(HttpServletRequest request) {
   
  -    HttpSession session = request.getSession();
  -    Locale locale = (Locale) session.getAttribute(LOCALE_KEY);
  -    if (locale == null)
  -        locale = defaultLocale;
  -    return (locale);
  +        HttpSession session = request.getSession();
  +        Locale locale = (Locale) session.getAttribute(LOCALE_KEY);
  +        if (locale == null)
  +            locale = defaultLocale;
  +        return (locale);
   
       }
   
   
       /**
  -     * Return the message resources for this application.
  +     * Return the message resources for the default sub-application.
  +     *
  +     * @deprecated This method can only return the resources for the default
  +     *  sub-application.  Use getResources(HttpServletRequest) to get the
  +     *  resources for the current sub-application.
        */
       protected MessageResources getResources() {
   
  -    return (servlet.getResources());
  +        return ((MessageResources)
  +                servlet.getServletContext().getAttribute(Action.MESSAGES_KEY));
   
       }
   
   
       /**
  +     * Return the message resources for the current sub-application.
  +     *
  +     * @param request The servlet request we are processing
  +     */
  +    protected MessageResources getResources(HttpServletRequest request) {
  +
  +        return ((MessageResources) request.getAttribute(Action.MESSAGES_KEY));
  +
  +    }
  +
  +
  +
  +    /**
        * Returns <code>true</code> if the current form's cancel button was
        * pressed.  This method will check if the cancel button generated by
        * <strong>CancelTag</strong> was pressed by the user in the
  @@ -564,22 +617,23 @@
       protected void saveErrors(HttpServletRequest request,
                     ActionErrors errors) {
   
  -    // Remove any error messages attribute if none are required
  -    if ((errors == null) || errors.empty()) {
  -        request.removeAttribute(ERROR_KEY);
  -        return;
  -    }
  +        // Remove any error messages attribute if none are required
  +        if ((errors == null) || errors.empty()) {
  +            request.removeAttribute(ERROR_KEY);
  +            return;
  +        }
   
  -    // Save the error messages we need
  -    request.setAttribute(ERROR_KEY, errors);
  +        // Save the error messages we need
  +        request.setAttribute(ERROR_KEY, errors);
   
       }
   
  +
       /**
        * Save the specified messages keys into the appropriate request
  -     * attribute for use by the &lt;struts:messages&gt; tag (if messages="true" is set),
  -     * if any messages are required.  Otherwise, ensure that the request
  -     * attribute is not created.
  +     * attribute for use by the &lt;struts:messages&gt; tag (if
  +     * messages="true" is set), if any messages are required.  Otherwise,
  +     * ensure that the request attribute is not created.
        *
        * @param request   The servlet request we are processing
        * @param messages  Messages object
  @@ -587,17 +641,18 @@
       protected void saveMessages(HttpServletRequest request,
                       ActionMessages messages) {
   
  -    // Remove any messages attribute if none are required
  -    if ((messages == null) || messages.empty()) {
  -        request.removeAttribute(MESSAGE_KEY);
  -        return;
  -    }
  +        // Remove any messages attribute if none are required
  +        if ((messages == null) || messages.empty()) {
  +            request.removeAttribute(MESSAGE_KEY);
  +            return;
  +        }
   
  -    // Save the messages we need
  -    request.setAttribute(MESSAGE_KEY, messages);
  +        // Save the messages we need
  +        request.setAttribute(MESSAGE_KEY, messages);
   
       }
   
  +
       /**
        * Save a new transaction token in the user's current session, creating
        * a new session if necessary.
  @@ -623,10 +678,10 @@
        */
       protected void setLocale(HttpServletRequest request, Locale locale) {
   
  -    HttpSession session = request.getSession();
  -    if (locale == null)
  -        locale = defaultLocale;
  -    session.setAttribute(LOCALE_KEY, locale);
  +        HttpSession session = request.getSession();
  +        if (locale == null)
  +            locale = defaultLocale;
  +        session.setAttribute(LOCALE_KEY, locale);
   
       }
   
  
  
  
  1.6       +8 -8      jakarta-struts/src/share/org/apache/struts/action/ActionError.java
  
  Index: ActionError.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionError.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ActionError.java	2 Nov 2001 04:14:44 -0000	1.5
  +++ ActionError.java	13 Jan 2002 00:25:35 -0000	1.6
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionError.java,v 1.5 2001/11/02 04:14:44 martinc Exp $
  - * $Revision: 1.5 $
  - * $Date: 2001/11/02 04:14:44 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionError.java,v 1.6 2002/01/13 00:25:35 craigmcc Exp $
  + * $Revision: 1.6 $
  + * $Date: 2002/01/13 00:25:35 $
    *
    * ====================================================================
    *
  @@ -66,18 +66,18 @@
   
   
   /**
  - * An encapsulation of an individual error message returned by the
  + * <p>An encapsulation of an individual error message returned by the
    * <code>validate()</code> method of an <code>ActionForm</code>, consisting
    * of a message key (to be used to look up message text in an appropriate
    * message resources database) plus up to four placeholder objects that can
  - * be used for parametric replacement in the message text.
  + * be used for parametric replacement in the message text.</p>
    *
  - * The placeholder objects are referenced in the message text using the same
  + * <p>The placeholder objects are referenced in the message text using the same
    * syntax used by the JDK <code>MessageFormat</code> class. Thus, the first
  - * placeholder is '{0}', the second is '{1}', etc.
  + * placeholder is '{0}', the second is '{1}', etc.</p>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.5 $ $Date: 2001/11/02 04:14:44 $
  + * @version $Revision: 1.6 $ $Date: 2002/01/13 00:25:35 $
    */
   
   public class ActionError extends ActionMessage implements Serializable {
  
  
  
  1.2       +10 -164   jakarta-struts/src/share/org/apache/struts/action/ActionException.java
  
  Index: ActionException.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionException.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ActionException.java	31 Dec 2001 01:14:36 -0000	1.1
  +++ ActionException.java	13 Jan 2002 00:25:35 -0000	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionException.java,v 1.1 2001/12/31 01:14:36 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2001/12/31 01:14:36 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionException.java,v 1.2 2002/01/13 00:25:35 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2002/01/13 00:25:35 $
    *
    * ====================================================================
    *
  @@ -60,7 +60,9 @@
    */
   package org.apache.struts.action;
   
  -import java.io.Serializable;
  +
  +import org.apache.struts.config.ExceptionConfig;
  +
   
   /**
    * An <strong>ActionException</strong> represents a potential exception
  @@ -91,167 +93,11 @@
    * </ul>
    *
    * @author ldonlan
  - * @version $Revision: 1.1 $ $Date: 2001/12/31 01:14:36 $
  + * @version $Revision: 1.2 $ $Date: 2002/01/13 00:25:35 $
  + *
  + * @deprecated Replaced by org.apache.struts.config.ExceptionConfig
    */
  -public class ActionException implements Serializable {
  -
  -    /** Holds value of property key. */
  -    private String key;
  -
  -    /** Holds value of property type. */
  -    private String type;
  -
  -    /** Holds value of property path. */
  -    private String path;
  -
  -    /** Holds value of property exClass. */
  -    private Class exClass;
  -
  -    /** Holds value of property hierachal. */
  -    private boolean hierarchical = true;
  -
  -    /** Holds value of property scope. */
  -    private String scope = "request";
  -
  -    /** Holds value of handler. */
  -    private String handler;
  -
  -    /** Holds value of property handlerClass */
  -    private Class handlerClass;
  -
  -    /** Creates new ActionException */
  -    public ActionException() {
  -
  -    }
  -
  -    /**
  -     * Returns the key associated with the exception.
  -     * @return Value of property key.
  -     */
  -    public String getKey() {
  -        return key;
  -    }
  -
  -    /**
  -     * Setter for property key.
  -     * @param key New value of property key.
  -     */
  -    public void setKey(String key) {
  -        this.key = key;
  -    }
  -
  -    /**
  -     * Returns the fully qualified type of the exception
  -     * @return Value of property type.
  -     */
  -    public String getType() {
  -        return type;
  -    }
  -
  -    /**
  -     * Setter for property type.
  -     * @param type New value of property type.
  -     * @todo Need to clean up this logging, but don't want to die if
  -     * an exception is mistyped, etc.
  -     */
  -    public void setType(String type){
  -        this.type = type;
  -        try{
  -            exClass = Class.forName(type);
  -        }catch(ClassNotFoundException ex){
  -            System.out.println("[ActionException] - Could not instantiate: " +
  -            ex.getClass() + " " + type);
  -            exClass = null;
  -        }
  -
  -    }
  -
  -    /**
  -     * Returns the path associated with the exception.
  -     * @return Value of property path.
  -     */
  -    public String getPath() {
  -        return path;
  -    }
  -
  -    /**
  -     * Setter for property path.
  -     * @param path New value of property path.
  -     */
  -    public void setPath(String path) {
  -        this.path = path;
  -    }
  -
  -    /**
  -     * Getter for property exClass.  Will be null if the type could not
  -     * be used to create a class instance.
  -     * @return Value of property exClass.
  -     */
  -    public Class getExClass() {
  -        return exClass;
  -    }
  -
  -    /** Getter for property hierachal.
  -     * @return Value of property hierachal.
  -     */
  -    public boolean isHierarchical() {
  -        return hierarchical;
  -    }
  -
  -    /** Setter for property hierachal.
  -     * @param hierarchical  */
  -    public void setHierarchical(boolean hierarchical) {
  -        this.hierarchical = hierarchical;
  -    }
  -
  -    /** Getter for property scope.
  -     * @return Value of property scope.
  -     */
  -    public String getScope() {
  -        return scope;
  -    }
  -
  -    /** Setter for property scope.
  -     * @param scope New value of property scope.
  -     */
  -    public void setScope(String scope) {
  -        this.scope = scope;
  -    }
  -
  -    /**
  -     * Returns the fully qualified type of the exception handler
  -     * @return Value of property handler.
  -     */
  -    public String getHandler() {
  -        return handler;
  -    }
  -
  -    /**
  -     * Setter for property handler.
  -     * @param type New value of property handler.
  -     * @todo Need to clean up this logging, but don't want to die if
  -     * an exception is mistyped, etc.
  -     */
  -    public void setHandler(String handler){
  -        this.handler = handler;
  -        try{
  -            handlerClass = Class.forName(handler);
  -        }catch(ClassNotFoundException ex){
  -            System.out.println("[ActionException] - Could not instantiate: " +
  -            ex.getClass() + " " + handler);
  -            handlerClass = null;
  -        }
  -    }
  -
  -
  -    /**
  -     * Getter for property handler.  Will be null if the handler could not
  -     * be used to create a class instance.
  -     * @return Value of property handlerClass.
  -     */
  -    public Class getHandlerClass() {
  -        return handlerClass;
  -    }
  +public class ActionException extends ExceptionConfig {
   
       /**
        *Returns an instance of an <b>ActionError</b> configured for
  
  
  
  1.4       +11 -84    jakarta-struts/src/share/org/apache/struts/action/ActionFormBean.java
  
  Index: ActionFormBean.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionFormBean.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ActionFormBean.java	21 Feb 2001 00:35:43 -0000	1.3
  +++ ActionFormBean.java	13 Jan 2002 00:25:35 -0000	1.4
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionFormBean.java,v 1.3 2001/02/21 00:35:43 craigmcc Exp $
  - * $Revision: 1.3 $
  - * $Date: 2001/02/21 00:35:43 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionFormBean.java,v 1.4 2002/01/13 00:25:35 craigmcc Exp $
  + * $Revision: 1.4 $
  + * $Date: 2002/01/13 00:25:35 $
    *
    * ====================================================================
    *
  @@ -63,7 +63,7 @@
   package org.apache.struts.action;
   
   
  -import java.io.Serializable;
  +import org.apache.struts.config.FormBeanConfig;
   
   
   /**
  @@ -73,88 +73,15 @@
    * properties.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.3 $ $Date: 2001/02/21 00:35:43 $
  + * @version $Revision: 1.4 $ $Date: 2002/01/13 00:25:35 $
  + *
  + * <p><strong>NOTE</strong> - This class would have been deprecated and
  + * replaced by <code>org.apache.struts.config.FormBeanConfig</code> except
  + * for the fact that it is part of the public API that existing applications
  + * are using.</p>
    */
   
  -public class ActionFormBean implements Serializable {
  -
  -
  -    // ----------------------------------------------------- Instance Variables
  -
  -
  -    /**
  -     * The bean name of this action form bean.
  -     */
  -    private String name = null;
  -
  -
  -    /**
  -     * The Java class name of this action form bean.
  -     */
  -    private String type = null;
  -
  -
  -    // ------------------------------------------------------------- Properties
  -
  -
  -    /**
  -     * Return the bean name of this action form bean.
  -     */
  -    public String getName() {
  -
  -	return (this.name);
  -
  -    }
  -
  -
  -    /**
  -     * Set the bean name of this action form bean.
  -     *
  -     * @param name The new bean name
  -     */
  -    public void setName(String name) {
  -
  -	this.name = name;
  -
  -    }
  -
  -
  -    /**
  -     * Return the Java class name of this action form bean.
  -     */
  -    public String getType() {
  -
  -	return (this.type);
  -
  -    }
  -
  -
  -    /**
  -     * Set the Java class name of this action form bean.
  -     *
  -     * @param type The new Java class name
  -     */
  -    public void setType(String type) {
  -
  -	this.type = type;
  -
  -    }
  -
  -
  -    // --------------------------------------------------------- Public Methods
  -
  -
  -    /**
  -     * Return a string representation of this object.
  -     */
  -    public String toString() {
  -
  -        StringBuffer sb = new StringBuffer("ActionFormBean[");
  -        sb.append(this.name);
  -        sb.append(']');
  -        return (sb.toString());
  -
  -    }
  +public class ActionFormBean extends FormBeanConfig {
   
   
   }
  
  
  
  1.5       +7 -4      jakarta-struts/src/share/org/apache/struts/action/ActionFormBeans.java
  
  Index: ActionFormBeans.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionFormBeans.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ActionFormBeans.java	16 Jul 2001 00:44:52 -0000	1.4
  +++ ActionFormBeans.java	13 Jan 2002 00:25:35 -0000	1.5
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionFormBeans.java,v 1.4 2001/07/16 00:44:52 craigmcc Exp $
  - * $Revision: 1.4 $
  - * $Date: 2001/07/16 00:44:52 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionFormBeans.java,v 1.5 2002/01/13 00:25:35 craigmcc Exp $
  + * $Revision: 1.5 $
  + * $Date: 2002/01/13 00:25:35 $
    *
    * ====================================================================
    *
  @@ -72,7 +72,10 @@
    * administered and searched, while hiding the internal implementation.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.4 $ $Date: 2001/07/16 00:44:52 $
  + * @version $Revision: 1.5 $ $Date: 2002/01/13 00:25:35 $
  + *
  + * @deprecated Replaced by collection of FormBeanConfig instances
  + *  in ApplicationConfig
    */
   
   public class ActionFormBeans implements Serializable {
  
  
  
  1.5       +19 -116   jakarta-struts/src/share/org/apache/struts/action/ActionForward.java
  
  Index: ActionForward.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionForward.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ActionForward.java	21 Feb 2001 00:35:44 -0000	1.4
  +++ ActionForward.java	13 Jan 2002 00:25:35 -0000	1.5
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionForward.java,v 1.4 2001/02/21 00:35:44 craigmcc Exp $
  - * $Revision: 1.4 $
  - * $Date: 2001/02/21 00:35:44 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionForward.java,v 1.5 2002/01/13 00:25:35 craigmcc Exp $
  + * $Revision: 1.5 $
  + * $Date: 2002/01/13 00:25:35 $
    *
    * ====================================================================
    *
  @@ -63,7 +63,7 @@
   package org.apache.struts.action;
   
   
  -import java.io.Serializable;
  +import org.apache.struts.config.ForwardConfig;
   
   
   /**
  @@ -79,24 +79,30 @@
    * An <code>ActionForward</code> has the following minimal set of properties.
    * Additional properties can be provided as needed by subclassses.
    * <ul>
  + * <li><strong>contextRelative</strong> - Should the <code>path</code>
  + *     value be interpreted as context-relative (instead of
  + *     application-relative, if it starts with a '/' character? [false]</li>
    * <li><strong>name</strong> - Logical name by which this instance may be
    *     looked up in relationship to a particular <code>ActionMapping</code>.
  - * <li><strong>path</strong> - Context-relative URI to which control should
  - *     be forwarded, or an absolute or relative URI to which control should
  - *     be redirected.
  + *     </li>
  + * <li><strong>path</strong> - Application-relative or context-relative URI to
  + *     which control should be forwarded, or an absolute or relative URI to
  + *     which control should be redirected.</li>
    * <li><strong>redirect</strong> - Set to <code>true</code> if the controller
    *     servlet should call <code>HttpServletResponse.sendRedirect()</code>
  - *     on the associated path; otherwise <code>false</code>.  [false]
  + *     on the associated path; otherwise <code>false</code>.  [false]</li>
    * </ul>
    *
  + * <p><strong>NOTE</strong> - This class would have been deprecated and
  + * replaced by <code>org.apache.struts.config.ForwardConfig</code> except
  + * for the fact that it is part of the public API that existing applications
  + * are using.</p>
  + *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.4 $ $Date: 2001/02/21 00:35:44 $
  + * @version $Revision: 1.5 $ $Date: 2002/01/13 00:25:35 $
    */
   
  -public class ActionForward implements Serializable {
  -
  -
  -    // ----------------------------------------------------------- Constructors
  +public class ActionForward extends ForwardConfig {
   
   
       /**
  @@ -133,109 +139,6 @@
   	setName(null);
   	setPath(path);
   	setRedirect(redirect);
  -
  -    }
  -
  -
  -    // ----------------------------------------------------- Instance Variables
  -
  -
  -    /**
  -     * The logical name of this forward.
  -     */
  -    protected String name = null;
  -
  -
  -    /**
  -     * The context-relative (for a forward) or relative or absolute (for a
  -     * redirect) URI path to be forwarded to.
  -     */
  -    protected String path = null;
  -
  -
  -    /**
  -     * Should this be a redirect instead of a forward?
  -     */
  -    protected boolean redirect = false;
  -
  -
  -    // ------------------------------------------------------------- Properties
  -
  -
  -    /**
  -     * Return the name.
  -     */
  -    public String getName() {
  -
  -	return (this.name);
  -
  -    }
  -
  -
  -    /**
  -     * Set the name.
  -     *
  -     * @param name The new name
  -     */
  -    public void setName(String name) {
  -
  -	this.name = name;
  -
  -    }
  -
  -
  -    /**
  -     * Return the path.
  -     */
  -    public String getPath() {
  -
  -	return (this.path);
  -
  -    }
  -
  -
  -    /**
  -     * Set the path.
  -     *
  -     * @param path The new path
  -     */
  -    public void setPath(String path) {
  -
  -	this.path = path;
  -
  -    }
  -
  -
  -    /**
  -     * Return the redirect flag.
  -     */
  -    public boolean getRedirect() {
  -
  -	return (this.redirect);
  -
  -    }
  -
  -
  -    /**
  -     * Set the redirect flag.
  -     *
  -     * @param redirect The new redirect flag
  -     */
  -    public void setRedirect(boolean redirect) {
  -
  -	this.redirect = redirect;
  -
  -    }
  -
  -
  -    // --------------------------------------------------------- Public Methods
  -
  -    /**
  -     * Return a String version of this mapping.
  -     */
  -    public String toString() {
  -
  -	return ("ActionForward[" + name + "]");
   
       }
   
  
  
  
  1.6       +7 -4      jakarta-struts/src/share/org/apache/struts/action/ActionForwards.java
  
  Index: ActionForwards.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionForwards.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- ActionForwards.java	16 Jul 2001 00:44:52 -0000	1.5
  +++ ActionForwards.java	13 Jan 2002 00:25:35 -0000	1.6
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionForwards.java,v 1.5 2001/07/16 00:44:52 craigmcc Exp $
  - * $Revision: 1.5 $
  - * $Date: 2001/07/16 00:44:52 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionForwards.java,v 1.6 2002/01/13 00:25:35 craigmcc Exp $
  + * $Revision: 1.6 $
  + * $Date: 2002/01/13 00:25:35 $
    *
    * ====================================================================
    *
  @@ -72,7 +72,10 @@
    * administered and searched, while hiding the internal implementation.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.5 $ $Date: 2001/07/16 00:44:52 $
  + * @version $Revision: 1.6 $ $Date: 2002/01/13 00:25:35 $
  + *
  + * @deprecated Replaced by collection of ForwardConfig instances in
  + *  ApplicationConfig and ActionConfig
    */
   
   public class ActionForwards implements Serializable {
  
  
  
  1.22      +57 -635   jakarta-struts/src/share/org/apache/struts/action/ActionMapping.java
  
  Index: ActionMapping.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMapping.java,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- ActionMapping.java	31 Dec 2001 01:14:36 -0000	1.21
  +++ ActionMapping.java	13 Jan 2002 00:25:35 -0000	1.22
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMapping.java,v 1.21 2001/12/31 01:14:36 craigmcc Exp $
  - * $Revision: 1.21 $
  - * $Date: 2001/12/31 01:14:36 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMapping.java,v 1.22 2002/01/13 00:25:35 craigmcc Exp $
  + * $Revision: 1.22 $
  + * $Date: 2002/01/13 00:25:35 $
    *
    * ====================================================================
    *
  @@ -63,666 +63,88 @@
   package org.apache.struts.action;
   
   
  -import java.io.Serializable;
  +import org.apache.struts.config.ActionConfig;
  +import org.apache.struts.config.ExceptionConfig;
  +import org.apache.struts.config.ForwardConfig;
   
   
   /**
  - * An <strong>ActionMapping</strong> represents the information that the
  + * <p>An <strong>ActionMapping</strong> represents the information that the
    * controller servlet, <code>ActionServlet</code>, knows about the mapping
    * of a particular request to an instance of a particular action class.
  - * The mapping is passed to the <code>perform()</code> method of the action
  - * class itself, enabling access to this information directly.
  - * <p>
  - * An <code>ActionMapping</code> has the following minimal set of properties.
  - * Additional properties can be added by a subclass, simply by
  - * providing appropriate public "getter" and "setter" methods.
  - * <ul>
  - * <li><strong>attribute</strong> - Name of the request-scope or
  - *     session-scope attribute under which our form bean is accessed, if it
  - *     is other than the bean's specified name.</li>
  - * <li><strong>forward</strong> - Context-relative path of the resource that
  - *     should serve this request (via a call to
  - *     <code>RequestDispatcher.forward()</code>) instead of instantiating the
  - *     Action class specified by the <code>type</code> property.
  - *     Exactly one of the <code>forward</code>, <code>include</code>, or
  - *     <code>type</code> properties must be specified.</li>
  - * <li><strong>forwards</strong> - The set of ActionForwards locally
  - *     associated with this mapping.</li>
  - * <li><strong>include</strong> - Context-relative path of the resource that
  - *     should serve this request (via a call to
  - *     <code>RequestDispatcher.include()</code>) instead of instantiating the
  - *     Action class specified by the <code>type</code> property.
  - *     Exactly one of the <code>forward</code>, <code>include</code>, or
  - *     <code>type</code> properties must be specified.</li>
  - * <li><strong>input</strong> - Context-relative path of the input form
  - *     to which control should be returned if a validation error is
  - *     encountered.</li>
  - * <li><strong>mappings</strong> - The <code>ActionMappings</code>
  - *     collection of which we are a part.</li>
  - * <li><strong>name</strong> - Name of the form bean, if any, associated
  - *     with this action.</li>
  - * <li><strong>parameter</strong> - General purpose configuration parameter
  - *     that can be used to pass extra information to the <code>Action</code>
  - *     selected by this <code>ActionMapping</code>.</li>
  - * <li><strong>path</strong> - Request URI path used to select this mapping.
  - *     If extension mapping is used for the controller servlet, the extension
  - *     will be stripped before comparisons against this value are made.</li>
  - * <li><strong>prefix</strong> - Prefix used to match request parameter
  - *     names to form bean property names, if any.</li>
  - * <li><strong>scope</strong> - Identifier of the scope ("request" or
  - *     "session" within which the form bean, if any, associated with this
  - *     action will be created.</li>
  - * <li><strong>suffix</strong> - Suffix used to match request parameter
  - *     names when populating the properties of our <code>ActionForm</code>
  - *     bean (if any).</li>
  - * <li><strong>type</strong> - Fully qualified Java class name of the
  - *     <code>Action</code> implementation class used by this mapping.
  - *     Replaces the old <code>actionClass</code> property.  Exactly one of
  - *     the <code>forward</code>, <code>include</code>, or <code>type</code>
  - *     properties must be specified.</li>
  - * <li><strong>unknown</strong> - Set to <code>true</code> if this action
  - *     should be configured as the default for this application, to handle
  - *     all requests not handled by another action.  Only one action can be
  - *     defined as a default within a single application.</li>
  - * <li><strong>validate</strong> - Set to <code>true</code> if the
  - *     <code>validate()</code> method of the form bean (if any) associated
  - *     with this mapping should be called.</li>
  - * </ul>
  + * The ActionMapping instance used to select a particular Action is passed
  + * on to that Action, thereby providing access to any custom configuration
  + * information included with the ActionMapping object.</p>
  + *
  + * <p><strong>NOTE</strong> - This class would have been deprecated and
  + * replaced by <code>org.apache.struts.config.ActionConfig</code> except
  + * for the fact that it is part of the public API that existing applications
  + * are using.</p>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.21 $ $Date: 2001/12/31 01:14:36 $
  + * @version $Revision: 1.22 $ $Date: 2002/01/13 00:25:35 $
    */
   
  -public class ActionMapping implements Serializable {
  -
  -
  -    // ----------------------------------------------------- Instance Variables
  -
  -
  -    /**
  -     * The name of the request-scope or session-scope attribute under which
  -     * our form bean, if any, will be created.
  -     */
  -    protected String attribute = null;
  -
  -
  -    /**
  -     * The set of ActionException objects associated with this mapping.
  -     */
  -    protected ActionExceptions exceptions = new ActionExceptions();
  -
  -
  -    /**
  -     * The context relative path of the servlet or JSP resource (to be called
  -     * via <code>RequestDispatcher.forward()</code>) that will process this
  -     * request, rather than instantiating and calling the Action class that is
  -     * specified by the <code>type</code> attribute.
  -     */
  -    protected String forward = null;
  -
  -
  -    /**
  -     * The set of ActionForward objects associated with this mapping.
  -     */
  -    protected ActionForwards forwards = new ActionForwards();
  -
  -
  -    /**
  -     * The context relative path of the servlet or JSP resource (to be called
  -     * via <code>RequestDispatcher.include()</code>) that will process this
  -     * request, rather than instantiating and calling the Action class that is
  -     * specified by the <code>type</code> attribute.
  -     */
  -    protected String include = null;
  -
  -
  -    /**
  -     * The context-relative path of the input form to which control should
  -     * be returned if a validation error is encountered.
  -     */
  -    protected String input = null;
  -
  -
  -    /**
  -     * The initialized <code>Action</code> instance for this mapping.
  -     */
  -    protected Action instance = null;
  -
  -
  -    /**
  -     * The <code>ActionMappings</code> collection of which we are a part.
  -     */
  -    protected ActionMappings mappings = null;
  -    
  -    /**
  -     * The fully qualified class name of the <code>MultipartRequestHandler</code>
  -     * implementation class used to process multipart request data for this mapping
  -     */
  -    protected String multipartClass;
  -    
  -    /**
  -     * The name of the form bean, if any, associated with this action.
  -     */
  -    protected String name = null;
  -
  -
  -    /**
  -     * General purpose configuration parameter for this mapping.
  -     */
  -    protected String parameter = null;
  -
  -
  -    /**
  -     * The context-relative path of the submitted request, starting with a
  -     * "/" character, and without the filename extension (if any), that is
  -     * mapped to this action.
  -     */
  -    protected String path = null;
  -
  -
  -    /**
  -     * The parameter name prefix used to select parameters for this action.
  -     */
  -    protected String prefix = null;
  -
  -
  -    /**
  -     * The identifier of the scope ("request" or "session") under which the
  -     * form bean associated with this mapping, if any, should be created.
  -     */
  -    protected String scope = "session";
  -
  -
  -    /**
  -     * The parameter name suffix used to select parameters for this action.
  -     */
  -    protected String suffix = null;
  -
  -
  -    /**
  -     * The fully qualified Java class name of the <code>Action</code>
  -     * implementation class to be used to process requests for this mapping.
  -     */
  -    protected String type = null;
  -
  -
  -    /**
  -     * Should this action be the default for this application?
  -     */
  -    protected boolean unknown = false;
  -
  -
  -    /**
  -     * Should the validate() method of our form bean be called?
  -     */
  -    protected boolean validate = true;
  -
  -
  -    // ------------------------------------------------------------- Properties
  -
  -
  -    /**
  -     * Return the attribute name for our form bean.
  -     */
  -    public String getAttribute() {
  -
  -        if (this.attribute == null)
  -            return (getName());
  -        else
  -            return (this.attribute);
  -
  -    }
  -
  -
  -    /**
  -     * Set the attribute name for our form bean.
  -     *
  -     * @param attribute The new attribute name
  -     */
  -    public void setAttribute(String attribute) {
  -
  -        this.attribute = attribute;
  -
  -    }
  -
  -
  -    /**
  -     * Return the forward path for this mapping.
  -     */
  -    public String getForward() {
  -
  -        return (this.forward);
  -
  -    }
  -
  -
  -    /**
  -     * Set the forward path for this mapping.
  -     *
  -     * @param forward The forward path for this mapping
  -     */
  -    public void setForward(String forward) {
  -
  -        this.forward = forward;
  -
  -    }
  -
  -
  -    /**
  -     * Return the include path for this mapping.
  -     */
  -    public String getInclude() {
  -
  -        return (this.include);
  -
  -    }
  -
  -
  -    /**
  -     * Set the include path for this mapping.
  -     *
  -     * @param include The include path for this mapping
  -     */
  -    public void setInclude(String include) {
  -
  -        this.include = include;
  -
  -    }
  -
  -
  -    /**
  -     * Return the input form path for this mapping.
  -     */
  -    public String getInput() {
  -
  -        return (this.input);
  -
  -    }
  -
  -
  -    /**
  -     * Set the input form path for this mapping.
  -     *
  -     * @param input The new input form path
  -     */
  -    public void setInput(String input) {
  -
  -        this.input = input;
  -
  -    }
  -
  -
  -    /**
  -     * Return the <code>ActionMappings</code> collection of which
  -     * we are a part.
  -     */
  -    public ActionMappings getMappings() {
  -
  -        return (this.mappings);
  -
  -    }
  -    
  -    /**
  -     * Get the name of the class used to handle multipart request data
  -     *
  -     * @return A fully qualified java class name representing the implementation of
  -     *         MultipartRequestHandler to use.
  -     */
  -    public String getMultipartClass() {
  -        return multipartClass;
  -    }
  -
  -
  -
  -    /**
  -     * Set the <code>ActionMappings</code> collection of which
  -     * we are a part.
  -     *
  -     * @param mappings The new ActionMappings collection
  -     */
  -    public void setMappings(ActionMappings mappings) {
  -
  -        this.mappings = mappings;
  -
  -    }
  -    
  -    /** 
  -     * Set the name of the class used to handle multipart request data
  -     *
  -     * @param multipartClass The fully qualified class name representing the
  -     *        MultipartRequestHandler class to use.  If <code>null</code>, 
  -     *        the global class specified in "web.xml" will be used.
  -     */
  -    public void setMultipartClass(String multipartClass) {
  -        this.multipartClass = multipartClass;
  -    }
  -
  -
  -
  -    /**
  -     * Return the name of the form bean for this mapping.
  -     */
  -    public String getName() {
  -
  -        return (this.name);
  -
  -    }
  -
  -
  -    /**
  -     * Set the name of the form bean for this mapping.
  -     *
  -     * @param name The new name
  -     */
  -    public void setName(String name) {
  -
  -        this.name = name;
  -
  -    }
  -
  -
  -    /**
  -     * Return the general purpose configuation parameter for this mapping.
  -     */
  -    public String getParameter() {
  -
  -        return (this.parameter);
  -
  -    }
  -
  -
  -    /**
  -     * Set the general purpose configuration parameter for this mapping.
  -     *
  -     * @param parameter The new configuration parameter
  -     */
  -    public void setParameter(String parameter) {
  -
  -        this.parameter = parameter;
  -
  -    }
  -
  -
  -    /**
  -     * Return the request URI path used to select this mapping.
  -     */
  -    public String getPath() {
  -
  -        return (this.path);
  -
  -    }
  -
  -
  -    /**
  -     * Set the request URI path used to select this mapping.
  -     *
  -     * @param path The new request URI path
  -     */
  -    public void setPath(String path) {
  -
  -        this.path = path;
  -
  -    }
  -
  -
  -    /**
  -     * Return the parameter name prefix for this mapping.
  -     */
  -    public String getPrefix() {
  -
  -        return (this.prefix);
  -
  -    }
  -
  -
  -    /**
  -     * Set the parameter name prefix for this mapping.
  -     *
  -     * @param prefix The new parameter name prefix
  -     */
  -    public void setPrefix(String prefix) {
  -
  -        this.prefix = prefix;
  -
  -    }
  -
  -
  -    /**
  -     * Return the attribute scope for this mapping.
  -     */
  -    public String getScope() {
  -
  -        return (this.scope);
  -
  -    }
  -
  -
  -    /**
  -     * Set the attribute scope for this mapping.
  -     *
  -     * @param scope The new attribute scope
  -     */
  -    public void setScope(String scope) {
  -
  -        this.scope = scope;
  -
  -    }
  +public class ActionMapping extends ActionConfig {
   
   
       /**
  -     * Return the parameter name suffix for this mapping.
  -     */
  -    public String getSuffix() {
  -
  -        return (this.suffix);
  -
  -    }
  -
  -
  -    /**
  -     * Set the parameter name suffix for this mapping.
  -     *
  -     * @param suffix The new parameter name suffix
  -     */
  -    public void setSuffix(String suffix) {
  -
  -        this.suffix = suffix;
  -
  -    }
  -
  -
  -    /**
  -     * Return the fully qualified Action class name.
  -     */
  -    public String getType() {
  -
  -        return (this.type);
  -
  -    }
  -
  -
  -    /**
  -     * Set the fully qualified Action class name.
  -     *
  -     * @param type The new class name
  -     */
  -    public void setType(String type) {
  -
  -        this.type = type;
  -
  -    }
  -
  -
  -    /**
  -     * Return the unknown flag for this mapping.
  -     */
  -    public boolean getUnknown() {
  -
  -        return (this.unknown);
  -
  -    }
  -
  -
  -    /**
  -     * Set the unknown flag for this mapping.
  -     *
  -     * @param unknown The new unknown flag
  -     */
  -    public void setUnknown(boolean unknown) {
  -
  -        this.unknown = unknown;
  -
  -    }
  -
  -
  -    /**
  -     * Return the validate flag for this mapping.
  -     */
  -    public boolean getValidate() {
  -
  -        return (this.validate);
  -
  -    }
  -
  -
  -    /**
  -     * Set the validate flag for this mapping.
  -     *
  -     * @param validate The new validate flag
  -     */
  -    public void setValidate(boolean validate) {
  -
  -        this.validate = validate;
  -
  -    }
  -
  -
  -    // --------------------------------------------------------- Public Methods
  -
  -
  -    /**
  -     * Add a new <code>ActionException</code> associated with this mapping.
  -     *
  -     * @param exception The ActionException to be added
  -     */
  -    public void addException(ActionException exception) {
  -
  -        exceptions.addException(exception);
  -
  -    }
  -
  -
  -    /**
  -     * Add a new <code>ActionForward</code> associated with this mapping.
  -     *
  -     * @param forward The ActionForward to be added
  -     */
  -    public void addForward(ActionForward forward) {
  -
  -        forwards.addForward(forward);
  -
  -    }
  -
  -
  -    /**
  -     * Return the <code>ActionException</code> handler for exceptions of the
  -     * specified type.
  +     * <p>Find and return the <code>ExceptionConfig</code> instance defining
  +     * how exceptions of the specified type should be handled.  This is
  +     * performed by checking local and then global configurations for the
  +     * specified exception's class, and then looking up the superclass chain
  +     * (again checking local and then global configurations).  If no handler
  +     * configuration can be found, return <code>null</code>.</p>
        *
        * @param type Exception class for which to find a handler
        */
  -    public ActionException findException(Class type) {
  +    public ExceptionConfig findException(Class type) {
   
  -        // First, check our locally defined exceptions
  -        ActionException ex = exceptions.findException(type);
  -        if (ex != null) {
  -            return (ex);
  -        }
  +        // Check through the entire superclass hierarchy as needed
  +        ExceptionConfig config = null;
  +        while (true) {
  +
  +            // Check for a locally defined handler
  +            String name = type.getName();
  +            config = findExceptionConfig(name);
  +            if (config != null) {
  +                return (config);
  +            }
  +
  +            // Check for a globally defined handler
  +            config = getApplicationConfig().findExceptionConfig(name);
  +            if (config != null) {
  +                return (config);
  +            }
  +
  +            // Loop again for our superclass (if any)
  +            type = type.getSuperclass();
  +            if (type == null) {
  +                break;
  +            }
   
  -        // Second, check the globally defined exceptions
  -        ActionMappings mappings = getMappings();
  -        if (mappings == null) {
  -            return (null);
  -        }
  -        ActionServlet servlet = mappings.getServlet();
  -        if (servlet == null) {
  -            return (null);
  -        } else {
  -            return (servlet.findException(type));
           }
  +        return (null); // No handler has been configured
   
       }
   
   
       /**
  -     * Return the <code>ActionForward</code> with the specified name,
  -     * if any; otherwise return <code>null</code>.  If there is no locally
  -     * defined forwarding for the specified name, but a global forwards
  -     * collection has been associated with this mapping, the global
  -     * collection will also be searched before returning.
  +     * <p>Find and return the <code>ForwardConfig</code> instance defining
  +     * how forwarding to the specified logical name should be handled.  This is
  +     * performed by checking local and then global configurations for the
  +     * specified forwarding configuration.  If no forwarding configuration
  +     * can be found, return <code>null</code>.</p>
        *
  -     * @param name Name of the forward entry to be returned
  +     * @param name Logical name of the forwarding instance to be returned
        */
       public ActionForward findForward(String name) {
   
  -        // First, check our locally defined forwards
  -        ActionForward forward = forwards.findForward(name);
  -        if (forward != null)
  -            return (forward);
  -
  -        // Second, check the globally defined forwards
  -        ActionMappings mappings = getMappings();
  -        if (mappings == null)
  -            return (null);
  -        ActionServlet servlet = mappings.getServlet();
  -        if (servlet == null)
  -            return (null);
  -        else
  -            return (servlet.findForward(name));
  -
  -    }
  -
  -
  -    /**
  -     * Return the logical names of all locally defined forwards for this
  -     * mapping.  If there are no such forwards, a zero-length array
  -     * is returned.
  -     */
  -    public String[] findForwards() {
  -
  -        return (forwards.findForwards());
  -
  -    }
  -
  -
  -    /**
  -     * Remove a <code>ActionForward</code> associated with this mapping.
  -     *
  -     * @param forward The ActionForward to be removed
  -     */
  -    public void removeForward(ActionForward forward) {
  -
  -        forwards.removeForward(forward);
  -
  -    }
  -
  -
  -    /**
  -     * Return a String version of this mapping.
  -     */
  -    public String toString() {
  -
  -        StringBuffer sb = new StringBuffer("ActionMapping[path=");
  -        sb.append(path);
  -        if (include != null) {
  -            sb.append(", include=");
  -            sb.append(include);
  -        }
  -        if (type != null) {
  -            sb.append(", type=");
  -            sb.append(type);
  +        ForwardConfig config = findForwardConfig(name);
  +        if (config == null) {
  +            config = getApplicationConfig().findForwardConfig(name);
           }
  -        sb.append("]");
  -        return (sb.toString());
  +        return ((ActionForward) config);
   
       }
   
  
  
  
  1.8       +9 -6      jakarta-struts/src/share/org/apache/struts/action/ActionMappings.java
  
  Index: ActionMappings.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMappings.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ActionMappings.java	16 Jul 2001 00:44:52 -0000	1.7
  +++ ActionMappings.java	13 Jan 2002 00:25:35 -0000	1.8
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMappings.java,v 1.7 2001/07/16 00:44:52 craigmcc Exp $
  - * $Revision: 1.7 $
  - * $Date: 2001/07/16 00:44:52 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMappings.java,v 1.8 2002/01/13 00:25:35 craigmcc Exp $
  + * $Revision: 1.8 $
  + * $Date: 2002/01/13 00:25:35 $
    *
    * ====================================================================
    *
  @@ -76,7 +76,10 @@
    * administered and searched, while hiding the internal implementation.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.7 $ $Date: 2001/07/16 00:44:52 $
  + * @version $Revision: 1.8 $ $Date: 2002/01/13 00:25:35 $
  + *
  + * @deprecated Replaced by collection of ActionConfig instances in
  + *  ApplicationConfig
    */
   
   public class ActionMappings implements Serializable {
  @@ -201,7 +204,7 @@
       public void addMapping(ActionMapping mapping) {
   
   	mappings.put(mapping.getPath(), mapping);
  -        mapping.setMappings(this);
  +        //        mapping.setMappings(this);
   
       }
   
  @@ -239,7 +242,7 @@
       public void removeMapping(ActionMapping mapping) {
   
   	mappings.remove(mapping.getPath());
  -        mapping.setMappings(null);
  +        //        mapping.setMappings(null);
   
       }
   
  
  
  
  1.3       +6 -6      jakarta-struts/src/share/org/apache/struts/action/ActionMessage.java
  
  Index: ActionMessage.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMessage.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ActionMessage.java	17 Sep 2001 19:58:57 -0000	1.2
  +++ ActionMessage.java	13 Jan 2002 00:25:35 -0000	1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMessage.java,v 1.2 2001/09/17 19:58:57 husted Exp $
  - * $Revision: 1.2 $
  - * $Date: 2001/09/17 19:58:57 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionMessage.java,v 1.3 2002/01/13 00:25:35 craigmcc Exp $
  + * $Revision: 1.3 $
  + * $Date: 2002/01/13 00:25:35 $
    *
    * ====================================================================
    *
  @@ -67,16 +67,16 @@
   
   
   /**
  - * An encapsulation of an individual message returned by the
  + * <p>An encapsulation of an individual message returned by the
    * <code>validate()</code> method of an <code>ActionForm</code>, consisting
    * of a message key (to be used to look up message text in an appropriate
    * message resources database) plus up to four placeholder objects that can
  - * be used for parametric replacement in the message text.
  + * be used for parametric replacement in the message text.</p>
    *
    * @since 1.1
    * @author Craig R. McClanahan
    * @author David Winterfeldt
  - * @version $Revision: 1.2 $ $Date: 2001/09/17 19:58:57 $
  + * @version $Revision: 1.3 $ $Date: 2002/01/13 00:25:35 $
    */
   
   public class ActionMessage implements Serializable {
  
  
  
  1.9       +4 -1      jakarta-struts/src/share/org/apache/struts/action/ActionResources.properties
  
  Index: ActionResources.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionResources.properties,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ActionResources.properties	13 Mar 2001 22:31:49 -0000	1.8
  +++ ActionResources.properties	13 Jan 2002 00:25:35 -0000	1.9
  @@ -10,11 +10,14 @@
   dataSource.init=Initializing application data source {0}
   destroyDataSource=Exception destroying application data source {0}
   finalizing=Finalizing this controller servlet
  +formBean=Error creating form bean of class {0}
   initDataSource=Exception initializing application data source {0}
  +initProcessor=Exception initializing RequestProcessor
   mappingType=Must specify one of "forward", "include" or "type" for path {0}
  +notAuthorized=User is not authorized to access action {0}
   noInput=No input attribute for mapping path {0}
   processInvalid=Invalid path {0} was requested
  -processPath=No process path included in this request
  +processPath=No process path found in request URI {0}
   reloading=Reloading from configuration files
   requestDispatcher=Cannot get request dispatcher for path {0}
   sessionCreate=No user session could be created
  
  
  
  1.83      +389 -2080 jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java
  
  Index: ActionServlet.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java,v
  retrieving revision 1.82
  retrieving revision 1.83
  diff -u -r1.82 -r1.83
  --- ActionServlet.java	31 Dec 2001 01:14:36 -0000	1.82
  +++ ActionServlet.java	13 Jan 2002 00:25:35 -0000	1.83
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java,v 1.82 2001/12/31 01:14:36 craigmcc Exp $
  - * $Revision: 1.82 $
  - * $Date: 2001/12/31 01:14:36 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java,v 1.83 2002/01/13 00:25:35 craigmcc Exp $
  + * $Revision: 1.83 $
  + * $Date: 2002/01/13 00:25:35 $
    *
    * ====================================================================
    *
  @@ -163,26 +163,39 @@
    * define additional initialization parameters.</p>
    * <ul>
    * <li><strong>application</strong> - Java class name of the application
  - *     resources bundle base class.  [NONE]</li>
  + *     resources bundle base class.  [NONE]
  + *     <em>DEPRECATED - Configure this using the "parameter" attribute
  + *     of the &lt;message-resources&gt; element.</em></li>
    * <li><strong>bufferSize</strong> - The size of the input buffer used when
  - *     processing file uploads.  [4096]</li>
  + *     processing file uploads.  [4096]
  + *     <em>DEPRECATED - Configure this using the "bufferSize" attribute
  + *     of the &lt;controller&gt; element.</em></li>
    * <li><strong>config</strong> - Context-relative path to the XML resource
  - *     containing our configuration information.
  + *     containing the configuration information for the default application.
    *     [/WEB-INF/struts-config.xml]</li>
  + * <li><strong>config/foo</strong> - Context-relative path to the XML resource
  + *     containing the configuration information for the sub-application that
  + *     will be at prefix "/foo".  This can be repeated as many times as
  + *     required for multiple sub-applications.</li>
    * <li><strong>content</strong> - Default content type and character encoding
    *     to be set on each response; may be overridden by a forwarded-to
  - *     servlet or JSP page.  [text/html]</li>
  + *     servlet or JSP page.  [text/html]
  + *     <em>DEPRECATED - Configure this using the "contentType" attribute
  + *     of the &lt;controller&gt; element.</em></li>
    * <li><strong>debug</strong> - The debugging detail level for this
  - *     servlet, which controls how much information is logged.  [0]</li>
  + *     servlet, which controls how much information is logged.  [0]
    * <li><strong>detail</strong> - The debugging detail level for the Digester
  - *     we utilize in <code>initMapping()</code>, which logs to System.out
  - *     instead of the servlet log.  [0]</li>
  + *     we utilize to process the application configuration files.</li>
    * <li><strong>factory</strong> - The Java class name of the
    *     <code>MessageResourcesFactory</code> used to create the application
    *     <code>MessageResources</code> object.
  - *     [org.apache.struts.util.PropertyMessageResourcesFactory]</li>
  + *     [org.apache.struts.util.PropertyMessageResourcesFactory]
  + *     <em>DEPRECATED - Configure this using the "factory" attribute
  + *     of the &lt;message-resources&gt; element.</em></li>
    * <li><strong>formBean</strong> - The Java class name of the ActionFormBean
    *     implementation to use [org.apache.struts.action.ActionFormBean].
  + *     <em>DEPRECATED - Configure this using the "className" attribute
  + *     of each &lt;form-bean&gt; element.</em></li>
    * <li><strong>forward</strong> - The Java class name of the ActionForward
    *     implementation to use [org.apache.struts.action.ActionForward].
    *     Two convenient classes you may wish to use are:
  @@ -195,12 +208,16 @@
    *         Subclass of <code>org.apache.struts.action.ActionForward</code>
    *         that defaults the <code>redirect</code> property to
    *         <code>true</code>.
  - *     </ul></li>
  + *     </ul>
  + *     <em>DEPRECATED - Configure this using the "className" attribute of
  + *     each &lt;forward&gt; element.</em></li>
    * <li><strong>locale</strong> - If set to <code>true</code>, and there is a
    *     user session, identify and store an appropriate
    *     <code>java.util.Locale</code> object (under the standard key
    *     identified by <code>Action.LOCALE_KEY</code>) in the user's session
  - *     if there is not a Locale object there already. [true]</li>
  + *     if there is not a Locale object there already. [true]
  + *     <em>DEPRECATED - Configure this using the "locale" attribute of
  + *     the &lt;controller&gt; element.</em></li>
    * <li><strong>mapping</strong> - The Java class name of the ActionMapping
    *     implementation to use [org.apache.struts.action.ActionMapping].
    *     Two convenient classes you may wish to use are:
  @@ -212,33 +229,46 @@
    *         of <code>org.apache.struts.action.ActionMapping</code> that
    *         defaults the <code>scope</code> property to "session".  (Same
    *         as the ActionMapping default value).
  - *     </ul></li>
  + *     </ul>
  + *     <em>DEPRECATED - Configure this using the "className" attribute of
  + *     each &lt;action&gt; element.</em></li>
    * <li><strong>maxFileSize</strong> - The maximum size (in bytes) of a file
    *     to be accepted as a file upload.  Can be expressed as a number followed
    *     by a "K" "M", or "G", which are interpreted to mean kilobytes,
  - *     megabytes, or gigabytes, respectively.  [250M]</li>
  + *     megabytes, or gigabytes, respectively.  [250M]
  + *     <em>DEPRECATED - Configure this using the "maxFileSize" attribute of
  + *     the &lt;controller&gt; element.</em></li>
    * <li><strong>multipartClass</strong> - The fully qualified name of the
    *     MultiplartRequestHandler implementation class to be used for processing
    *     file uploads. If set to <code>none</code>, disables Struts multipart
    *     request handling.  [org.apache.struts.upload.DiskMultipartRequestHandler]
  - *     </li>
  + *     FIXME - check this</li>
    * <li><strong>nocache</strong> - If set to <code>true</code>, add HTTP headers
    *     to every response intended to defeat browser caching of any response we
  - *     generate or forward to.  [false]</li>
  + *     generate or forward to.  [false]
  + *     <em>DEPRECATED - Configure this using the "nocache" attribute of
  + *     the &lt;controller&gt; element.</em></li>
    * <li><strong>null</strong> - If set to <code>true</code>, set our application
    *     resources to return <code>null</code> if an unknown message key is used.
    *     Otherwise, an error message including the offending message key will
  - *     be returned.  [true]</li>
  + *     be returned.  [true]
  + *     <em>DEPRECATED - Configure this using the "null" attribute of
  + *     the &lt;message-resources&gt; element.</em></li>
  + * <li><strong>processor</strong> - The fully qualified Java class name of the
  + *     <code>RequestProcessor</code> implementation class to be used.
  + *     [org.apache.struts.action.RequestProcessor]</li>
    * <li><strong>tempDir</strong> - The temporary working directory to use when
    *     processing file uploads.  [The working directory provided to this web
  - *     application as a servlet context attribute]</li>
  + *     application as a servlet context attribute]
  + *     <em>DEPRECATED - Configure this using the "tempDir" attribute of
  + *     the &lt;controller&gt; element.</em></li>
    * <li><strong>validating</strong> - Should we use a validating XML parse to
    *     process the configuration file (strongly recommended)? [true]</li>
    * </ul>
    *
    * @author Craig R. McClanahan
    * @author Ted Husted
  - * @version $Revision: 1.82 $ $Date: 2001/12/31 01:14:36 $
  + * @version $Revision: 1.83 $ $Date: 2002/01/13 00:25:35 $
    */
   
   public class ActionServlet
  @@ -249,20 +279,8 @@
   
   
       /**
  -     * The set of Action instances that have been created and initialized,
  -     * keyed by the fully qualified Java class name.
  -     */
  -    protected FastHashMap actions = new FastHashMap();
  -
  -
  -    /**
  -     * The resources object for our application resources (if any).
  -     */
  -    protected MessageResources application = null;
  -
  -
  -    /**
  -     * The context-relative path to our configuration resource.
  +     * The context-relative path to our configuration resource for the
  +     * default sub-application.
        */
       protected String config = "/WEB-INF/struts-config.xml";
   
  @@ -275,13 +293,6 @@
   
   
       /**
  -     * The default content type and character encoding to be set on each
  -     * response (may be overridden by forwarded-to resources).
  -     */
  -    protected String content = "text/html";
  -
  -
  -    /**
        * The JDBC data sources that has been configured for this application,
        * if any, keyed by the servlet context attribute under which they are
        * stored.
  @@ -302,59 +313,6 @@
   
   
       /**
  -     * The default Locale for this server.
  -     */
  -    protected final Locale defaultLocale = Locale.getDefault();
  -
  -
  -    /**
  -     * The Java class name of the <code>ActionException</code> implementation
  -     * class to use.
  -     */
  -    protected String exceptionClass =
  -        "org.apache.struts.action.ActionException";
  -
  -
  -    /**
  -     * The global exceptions registered with this handler.
  -     */
  -    protected ActionExceptions exceptions = new ActionExceptions();
  -
  -
  -    /**
  -     * The Java class name of the <code>MessageResourcesFactory</code>
  -     * class for the application message resources bundle.
  -     */
  -    protected String factoryClass = null;
  -
  -
  -    /**
  -     * The Java class name of the ActionFormBean implementation class to use.
  -     */
  -    protected String formBeanClass =
  -        "org.apache.struts.action.ActionFormBean";
  -
  -
  -    /**
  -     * The global ActionFormBean collection for this controller.
  -     */
  -    protected ActionFormBeans formBeans = new ActionFormBeans();
  -
  -
  -    /**
  -     * The Java class name of the ActionForward implementation class to use.
  -     */
  -    protected String forwardClass =
  -    "org.apache.struts.action.ActionForward";
  -
  -
  -    /**
  -     * The global ActionForward collection for this controller.
  -     */
  -    protected ActionForwards forwards = new ActionForwards();
  -
  -
  -    /**
        * The resources object for our internal resources.
        */
       protected MessageResources internal = null;
  @@ -367,29 +325,17 @@
   
   
       /**
  -     * Should we create a <code>java.util.Locale</code> for this user,
  -     * based on the HTTP headers of the request, if one is not present?
  -     */
  -    protected boolean locale = true;
  -
  -
  -    /**
  -     * The Java class name of our ActionMapping implementation class.
  -     */
  -    protected String mappingClass =
  -    "org.apache.struts.action.ActionMapping";
  -
  -
  -    /**
  -     * The configured mappings for this web application, keyed by path.
  +     * The <code>RequestProcessor</code> instance we will use to process
  +     * all incoming requests.
        */
  -    protected ActionMappings mappings = new ActionMappings();
  +    protected RequestProcessor processor = null;
   
   
       /**
  -     * Include the no-caching headers in our response?
  +     * The Java class name of the RequestProcessor implementation to use.
        */
  -    protected boolean nocache = false;
  +    protected String processorClass =
  +        "org.apache.struts.action.RequestProcessor";
   
   
       /**
  @@ -411,7 +357,7 @@
   
       /**
        * The URL pattern to which we are mapped in our web application
  -     * deployment descriptor.
  +     * deployment descriptor.  FIXME - multiples???
        */
       protected String servletMapping = null;
   
  @@ -429,35 +375,6 @@
       protected boolean validating = true;
   
   
  -    /**
  -     * The size in bytes of the buffer used to read files from a client upload
  -     */
  -    protected int bufferSize = 4096;
  -
  -    /**
  -     * The maximum size allowed for a client upload.  A suffix of "K"
  -     * represents Kilobytes, a suffix of "M" represents "Megabytes",
  -     * a suffix of "G" represents Gigabytes, and no suffix is taken
  -     * as bytes.
  -     */
  -    protected String maxFileSize = "250M";
  -
  -    /**
  -     * The MultipartRequestHandler class name used for handling
  -     * multipart form requests.  This is the global default value,
  -     * the handler can also be set in individual mapping entries
  -     */
  -    protected String multipartClass = "org.apache.struts.upload.DiskMultipartRequestHandler";
  -
  -    /**
  -     * The directory used to store temporary files for the DiskMultipartRequestHandler
  -     * multipart implementation
  -     */
  -    protected String tempDir;
  -
  -
  -
  -
   
       // ---------------------------------------------------- HttpServlet Methods
   
  @@ -471,11 +388,12 @@
       if (debug >= 1)
           log(internal.getMessage("finalizing"));
   
  -        destroyActions();
  -        destroyApplication();
           destroyDataSources();
  +        destroyProcessor();
           destroyInternal();
   
  +        // FIXME - destroy ApplicationConfig and message resource instances
  +
       }
   
   
  @@ -488,25 +406,15 @@
        */
       public void init() throws ServletException {
   
  -        initActions();
           initInternal();
  -        initDebug();
  -        //        initApplication(); // Replaced by new-style initialization
  -        try {
  -            initMapping();
  -        } catch (IOException e) {
  -            throw new UnavailableException
  -                (internal.getMessage("configIO", config));
  -        }
  -        initUpload();
  -        initDataSources(); // Will be replaced by new-style initialization
           initOther();
           initServlet();
  +        initProcessor();
   
           // Initialize sub-applications as needed
           ApplicationConfig ac = initApplicationConfig("", config);
           initApplicationMessageResources(ac);
  -        //        initApplicationDataSources(ac); // Uncomment when initDataSources() is removed
  +        initApplicationDataSources(ac);
           Enumeration names = getServletConfig().getInitParameterNames();
           while (names.hasMoreElements()) {
               String name = (String) names.nextElement();
  @@ -537,7 +445,7 @@
                 HttpServletResponse response)
           throws IOException, ServletException {
   
  -        process(request, response);
  +        processor.process(request, response);
   
       }
   
  @@ -555,7 +463,7 @@
                  HttpServletResponse response)
           throws IOException, ServletException {
   
  -        process(request, response);
  +        processor.process(request, response);
   
       }
   
  @@ -564,96 +472,6 @@
   
   
       /**
  -     * Add a data source object to be used by this application.
  -     *
  -     * @param key The servlet context attribute key under which to store
  -     *  this data source, or <code>null</code> for the default
  -     * @param dataSource The data source to be used
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public void addDataSource(String key, DataSource dataSource) {
  -
  -        if (key == null)
  -            key = Action.DATA_SOURCE_KEY;
  -        dataSources.put(key, dataSource);
  -
  -    }
  -
  -
  -    /**
  -     * Add a global exception to the set configured for this servlet.
  -     *
  -     * @param exception The exception to be added
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public void addException(ActionException exception) {
  -
  -        exceptions.addException(exception);
  -
  -    }
  -
  -
  -    /**
  -     * Register a form bean definition to the set configured for this servlet.
  -     *
  -     * @param formBean The form bean definition to be added
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public void addFormBean(ActionFormBean formBean) {
  -
  -        formBeans.addFormBean(formBean);
  -
  -    }
  -
  -
  -    /**
  -     * Register a logical forwarding to the set configured for this servlet.
  -     *
  -     * @param forward The forwarding to be added
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public void addForward(ActionForward forward) {
  -
  -        forwards.addForward(forward);
  -
  -    }
  -
  -
  -    /**
  -     * Register a mapping to the set configured for this servlet.
  -     *
  -     * @param mapping The mapping to be added
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public void addMapping(ActionMapping mapping) {
  -
  -        // Validate that exactly one of "include" or "type" is included
  -        int n = 0;
  -        if (mapping.getForward() != null)
  -            n++;
  -        if (mapping.getInclude() != null)
  -            n++;
  -        if (mapping.getType() != null)
  -            n++;
  -        if (n != 1) {
  -            String message =
  -                internal.getMessage("mappingType", mapping.getPath());
  -            log(message);
  -            throw new IllegalArgumentException(message);
  -        }
  -
  -        // Add this mapping to our global collection
  -        mappings.addMapping(mapping);
  -
  -    }
  -
  -
  -    /**
        * Remember a servlet mapping from our web application deployment
        * descriptor, if it is for this servlet.
        *
  @@ -692,78 +510,38 @@
   
   
       /**
  -     * Return the form bean definition associated with the specified
  -     * logical name, if any; otherwise return <code>null</code>.
  -     *
  -     * @param name Logical name of the requested form bean definition
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public ActionFormBean findFormBean(String name) {
  -
  -        return (formBeans.findFormBean(name));
  -
  -    }
  -
  -
  -    /**
  -     * Return the exception handler for an exception of the specified
  -     * class, if any; otherwise return <code>null</code>.
  -     *
  -     * @param ex Exception class for which to find a handler
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public ActionException findException(Class ex) {
  -
  -        return (exceptions.findException(ex));
  -
  -    }
  -
  -
  -    /**
  -     * Return the forwarding associated with the specified logical name,
  -     * if any; otherwise return <code>null</code>.
  +     * Return the global ActionForward for the specified logical name, for
  +     * the default sub-application.
        *
        * @param name Logical name of the requested forwarding
        *
  -     * @deprecated Will no longer be required with multi-application support
  +     * @deprecated Call ActionMapping.findForward() to get the forwarding
  +     *  that is local to the current sub-application
        */
       public ActionForward findForward(String name) {
   
  -        return (forwards.findForward(name));
  +        ApplicationConfig appConfig = (ApplicationConfig)
  +            getServletContext().getAttribute(Action.APPLICATION_KEY);
  +        return ((ActionForward) appConfig.findForwardConfig(name));
   
       }
   
   
       /**
  -     * Return the mapping associated with the specified request path, if any;
  -     * otherwise return <code>null</code>.
  +     * Return the ActionMapping for the specified path, for the default
  +     * sub-application.
        *
        * @param path Request path for which a mapping is requested
        *
  -     * @deprecated Will no longer be required with multi-application support
  +     * @deprecated Get the ApplicationConfig object from request attribute
  +     *  key Action.APPLIATION_KEY and call findActionConfig() to get
  +     *  mappings for the current sub-application
        */
       public ActionMapping findMapping(String path) {
   
  -        return (mappings.findMapping(path));
  -
  -    }
  -
  -
  -    /**
  -     * Get the buffer size (how large of a chunk of data is
  -     * recieved by the input stream at once) used for file
  -     * uploading.
  -     *
  -     * @return The size in bytes of the buffer
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public int getBufferSize() {
  -
  -        return bufferSize;
  -
  +        ApplicationConfig appConfig = (ApplicationConfig)
  +            getServletContext().getAttribute(Action.APPLICATION_KEY);
  +        return ((ActionMapping) appConfig.findActionConfig(path));
       }
   
   
  @@ -778,535 +556,118 @@
   
   
       /**
  -     * Return the Java class name of the class used to instantiate
  -     * <code>ActionFormBean</code> objects.
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public String getFormBeanClass() {
  -
  -        return (this.formBeanClass);
  -
  -    }
  -
  -
  -    /**
  -     * Return the Java class name of the class used to instantiate
  -     * <code>ActionForward</code> objects.
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  +     * Return the <code>MessageResources</code> instance containing our
  +     * internal message strings.
        */
  -    public String getForwardClass() {
  +    public MessageResources getInternal() {
   
  -        return (this.forwardClass);
  +        return (this.internal);
   
       }
   
   
       /**
  -     * Return the Java class name of the class used to instantiate
  -     * <code>ActionMapping</code> objects.
  +     * Log the specified message if the current debugging detail level for
  +     * this servlet has been set to an equal or higher value.  Otherwise,
  +     * ignore this message.
        *
  -     * @deprecated Will no longer be required with multi-application support
  +     * @param message Message to be logged
  +     * @param level Debugging detail level of this message
        */
  -    public String getMappingClass() {
  +    public void log(String message, int level) {
   
  -        return (this.mappingClass);
  +        if (debug >= level)
  +            log(message);
   
       }
   
   
  -    /**
  -     * Get the maximum file size.  See
  -     * {@link #setMaxFileSize(java.lang.String) setMaxFileSize}
  -     * for information on the number format used.
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public String getMaxFileSize() {
  -
  -        return maxFileSize;
  +    // ------------------------------------------------------ Protected Methods
   
  -    }
   
       /**
  -     * Get the class name of the MultipartRequestHandler implementation
  -     *
  -     * @return A qualified classname of the MultipartRequestHandler
  -     * implementation
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  +     * Gracefully release any configDigester instance that we have created.
        */
  -     public String getMultipartClass() {
  +    protected void destroyConfigDigester() {
   
  -        return multipartClass;
  +        configDigester = null;
   
       }
   
   
       /**
  -     * Return the application resources for this web application, if any.
  +     * Gracefully terminate use of the data source associated with this
  +     * application (if any).
        *
        * @deprecated Will no longer be required with multi-application support
        */
  -    public MessageResources getResources() {
  +    protected void destroyDataSources() {
   
  -        return (application);
  +        synchronized (dataSources) {
  +            Iterator keys = dataSources.keySet().iterator();
  +            while (keys.hasNext()) {
  +                String key = (String) keys.next();
  +                getServletContext().removeAttribute(key);
  +                DataSource dataSource = findDataSource(key);
  +                if (dataSource instanceof GenericDataSource) {
  +                    if (debug >= 1)
  +                        log(internal.getMessage("dataSource.destroy", key));
  +                    try {
  +                        ((GenericDataSource) dataSource).close();
  +                    } catch (SQLException e) {
  +                        log(internal.getMessage("destroyDataSource", key), e);
  +                    }
  +                }
  +            }
  +            dataSources.clear();
  +        }
   
       }
   
   
       /**
  -     * Get the directory used to temporarily store form files
  -     *
  -     * @return A platform-dependant String representing the path to
  -     *  the temporary directory
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  +     * Gracefully terminate use of the internal MessageResources.
        */
  -    public String getTempDir() {
  +    protected void destroyInternal() {
   
  -        return tempDir;
  +        internal = null;
   
       }
   
   
       /**
  -     * Log the specified message if the current debugging detail level for
  -     * this servlet has been set to an equal or higher value.  Otherwise,
  -     * ignore this message.
  -     *
  -     * @param message Message to be logged
  -     * @param level Debugging detail level of this message
  +     * <p>Gracefully terminate the RequestProcessor instance we were using.
        */
  -    public void log(String message, int level) {
  +    protected void destroyProcessor() {
   
  -        if (debug >= level)
  -            log(message);
  +        processor.destroy();
  +        processor = null;
   
       }
   
   
       /**
  -     * Reload the configuration of this controller servlet from our
  -     * underlying configuration files.
  +     * <p>Initialize the application configuration information for the
  +     * specified sub-application.</p>
        *
  -     * @exception IOException if an input/output error occurs
  -     * @exception ServletException if a servlet exception occurs
  +     * @param prefix Application prefix for this application
  +     * @param path Context-relative resource path for this application's
  +     *  configuration resource
        *
  -     * @deprecated Use your container's application reload facility
  +     * @exception ServletException if initialization cannot be performed
        */
  -    public void reload() throws IOException, ServletException {
  -
  -        if (debug >= 1)
  -            log(internal.getMessage("reloading"));
  -
  -        // Shut down our existing environment
  -        destroyActions();
  -        destroyApplication();
  -        destroyDataSources();
  -        destroyInternal();
  -
  -        // Restart from our confirmation files
  -        initActions();
  -        initInternal();
  -        initDebug();
  -        initApplication();
  -        initMapping();
  -        initUpload();
  -        initDataSources();
  -        initOther();
  -
  -    }
  +    protected ApplicationConfig initApplicationConfig
  +        (String prefix, String path) throws ServletException {
   
  -
  -    /**
  -     * Deregister a form bean definition from the set configured for
  -     * this servlet.
  -     *
  -     * @param formBean The form bean definition to be deregistered
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public void removeFormBean(ActionFormBean formBean) {
  -
  -        formBeans.removeFormBean(formBean);
  -
  -    }
  -
  -
  -    /**
  -     * Deregister a forwarding from the set configured for this servlet.
  -     *
  -     * @param forward The forwarding to be deregistered
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public void removeForward(ActionForward forward) {
  -
  -        forwards.removeForward(forward);
  -
  -    }
  -
  -
  -    /**
  -     * Deregister a mapping from the set configured for this servlet.
  -     *
  -     * @param mapping The mapping to be deregistered
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public void removeMapping(ActionMapping mapping) {
  -
  -        mappings.removeMapping(mapping);
  -
  -    }
  -
  -
  -    /**
  -     * Set the buffer size (how large of a chunk of data is
  -     * recieved by the input stream at once) used for file
  -     * uploading.
  -     *
  -     * @param bufferSize The size in bytes of the buffer
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public void setBufferSize(int bufferSize) {
  -
  -        this.bufferSize = bufferSize;
  -
  -    }
  -
  -
  -    /**
  -     * Set the Java class name of the class used to instantiate
  -     * <code>ActionFormBean</code> objects.
  -     *
  -     * @param formBeanClass The new class name
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public void setFormBeanClass(String formBeanClass) {
  -
  -        this.formBeanClass = formBeanClass;
  -
  -    }
  -
  -
  -    /**
  -     * Set the Java class name of the class used to instantiate
  -     * <code>ActionForward</code> objects.
  -     *
  -     * @param forwardClass The new class name
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public void setForwardClass(String forwardClass) {
  -
  -        this.forwardClass = forwardClass;
  -
  -    }
  -
  -
  -    /**
  -     * Set the Java class name of the class used to instantiate
  -     * <code>ActionMapping</code> objects.
  -     *
  -     * @param mappingClass The new class name
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public void setMappingClass(String mappingClass) {
  -
  -        this.mappingClass = mappingClass;
  -
  -    }
  -
  -
  -    /**
  -     * Set the maximum file size that a client can upload,  number String with
  -     * a trailing letter indicating the size.  "K" indicates "kilobytes", "M"
  -     * indicates "megabytes", "G" indicates "gigabytes".  If there's no
  -     * trailing letter the suffix is assumed to indicate the number is in
  -     * bytes.  For example, to set a maximum file size of
  -     * 500 megabytes, you'd call <code>setMaxFileSize</code>("<i>500M</i>").
  -     *
  -     * @param maxFileSize A String representing the maximum file size.
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public void setMaxFileSize(String maxFileSize) {
  -
  -        this.maxFileSize = maxFileSize;
  -
  -    }
  -
  -
  -    /**
  -     * Set the class name of the MultipartRequestHandler implementation
  -     *
  -     * @param multipartClass A qualified classname of the MultipartRequestHandler implementation
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public void setMultipartClass(String multipartClass) {
  -
  -        this.multipartClass = multipartClass;
  -
  -    }
  -
  -
  -    /**
  -     * Set the directory used to temporarily store files for
  -     * MultipartRequestHandler implementations that write to the disk
  -     *
  -     * @param tempDir A platform-dependant String representing the path to
  -     *  the temporary directory
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    public void setTempDir(String tempDir) {
  -
  -        this.tempDir = tempDir;
  -
  -    }
  -
  -
  -    /**
  -     * Return an instance of the ActionForm associated with the specified
  -     * path, if any; otherwise return <code>null</code>.
  -     * May be used to create an ActionForm for InvokeAction.
  -     *
  -     * @param name path of the Action using the ActionForm bean
  -     * @since 1.1
  -     */
  -    public ActionForm createActionForm(String path) {
  -
  -        ActionMapping mapping = findMapping(path);
  -        String name = mapping.getName();
  -
  -        ActionForm form = null;
  -
  -        ActionFormBean formBean = findFormBean(name);
  -        if (formBean != null) {
  -            String className = null;
  -            className = formBean.getType();
  -            try {
  -                Class clazz = Class.forName(className);
  -                form = (ActionForm) clazz.newInstance();
  -            } catch (Throwable t) {
  -                form = null;
  -            }
  -        }
  -
  -        return form;
  -
  -    }
  -
  -
  -    /**
  -     * Directly process the Action perform associated with the
  -     * given path.
  -     * Return the <code>ActionForward</code> instance (if any)
  -     * returned by the called <code>Action</code>.
  -     * <code>createActionForm</code> may be used to create an
  -     * ActionForm instance to pass to the Action invoked.
  -     *
  -     * @param action The path to the Action to invoke
  -     * @param form The ActionForm we are processing
  -     * @param request The servlet request we are processing
  -     * @param response The servlet response we are creating
  -     *
  -     * @exception IOException if an input/output error occurs
  -     * @exception ServletException if a servlet exception occurs
  -     * @since 1.1
  -     */
  -    public ActionForward invokeAction(
  -            String path,
  -            ActionForm form,
  -            HttpServletRequest request,
  -            HttpServletResponse response)
  -        throws IOException, ServletException {
  -
  -        ActionMapping mapping =
  -            processMapping(path,request);
  -
  -        Action action =
  -            processActionCreate(mapping,request);
  -
  -        ActionForward forward = processActionPerform(
  -            action,mapping,form,request,response);
  -
  -        return forward;
  -
  -    }
  -
  -
  -    // ------------------------------------------------------ Protected Methods
  -
  -
  -    /**
  -     * Gracefully shut down any action instances we have created.
  -     */
  -    protected void destroyActions() {
  -
  -        synchronized (this.actions) {
  -            Iterator actions = this.actions.values().iterator();
  -            while (actions.hasNext()) {
  -                Action action = (Action) actions.next();
  -                action.setServlet(null);
  -            }
  -            this.actions.clear();
  -        }
  -
  -    }
  -
  -
  -    /**
  -     * Gracefully terminate use of the application MessageResources (if any).
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    protected void destroyApplication() {
  -
  -    if (application != null)
  -        getServletContext().removeAttribute(Action.MESSAGES_KEY);
  -    application = null;
  -
  -    }
  -
  -
  -    /**
  -     * Gracefully release any configDigester instance that we have created.
  -     */
  -    protected void destroyConfigDigester() {
  -
  -        configDigester = null;
  -
  -    }
  -
  -
  -    /**
  -     * Gracefully terminate use of the data source associated with this
  -     * application (if any).
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    protected void destroyDataSources() {
  -
  -        synchronized (dataSources) {
  -            Iterator keys = dataSources.keySet().iterator();
  -            while (keys.hasNext()) {
  -                String key = (String) keys.next();
  -                getServletContext().removeAttribute(key);
  -                DataSource dataSource = findDataSource(key);
  -                if (dataSource instanceof GenericDataSource) {
  -                    if (debug >= 1)
  -                        log(internal.getMessage("dataSource.destroy", key));
  -                    try {
  -                        ((GenericDataSource) dataSource).close();
  -                    } catch (SQLException e) {
  -                        log(internal.getMessage("destroyDataSource", key), e);
  -                    }
  -                }
  -            }
  -            dataSources.setFast(false);
  -        }
  -
  -    }
  -
  -
  -    /**
  -     * Gracefully terminate use of the internal MessageResources.
  -     */
  -    protected void destroyInternal() {
  -
  -        internal = null;
  -
  -    }
  -
  -
  -    /**
  -     * Initialize the collection of previously instantiated Action instances.
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    protected void initActions() {
  -
  -        synchronized (actions) {
  -            actions.setFast(false);
  -            actions.clear();
  -            actions.setFast(true);
  -        }
  -
  -    }
  -
  -
  -    /**
  -     * Initialize the MessageResources bundle for this application, if any.
  -     *
  -     * @exception ServletException if we cannot initialize these resources
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    protected void initApplication() throws ServletException {
  -
  -        String value = getServletConfig().getInitParameter("application");
  -        if (value == null)
  -            return;
  -        String factory =
  -            getServletConfig().getInitParameter("factory");
  -        if (debug >= 1)
  -            log(internal.getMessage("applicationLoading", value));
  -        try {
  -            String oldFactory =
  -                MessageResourcesFactory.getFactoryClass();
  -            if (factory != null)
  -                MessageResourcesFactory.setFactoryClass(factory);
  -            MessageResourcesFactory factoryObject =
  -                MessageResourcesFactory.createFactory();
  -            application = factoryObject.createResources(value);
  -            MessageResourcesFactory.setFactoryClass(oldFactory);
  -            value = getServletConfig().getInitParameter("null");
  -            if (value == null)
  -                value = "true";
  -            if (value.equalsIgnoreCase("true") ||
  -                value.equalsIgnoreCase("yes"))
  -                application.setReturnNull(true);
  -            else
  -                application.setReturnNull(false);
  -        } catch (Throwable e) {
  -            log(internal.getMessage("applicationResources", value), e);
  -            throw new UnavailableException
  -                (internal.getMessage("applicationResources", value));
  -        }
  -        getServletContext().setAttribute(Action.MESSAGES_KEY, application);
  -
  -    }
  -
  -
  -    /**
  -     * <p>Initialize the application configuration information for the
  -     * specified sub-application.</p>
  -     *
  -     * @param prefix Application prefix for this application
  -     * @param path Context-relative resource path for this application's
  -     *  configuration resource
  -     *
  -     * @exception ServletException if initialization cannot be performed
  -     */
  -    protected ApplicationConfig initApplicationConfig
  -        (String prefix, String path) throws ServletException {
  -
  -        if (debug >= 1) {
  -            log("Initializing application path '" + prefix +
  -                "' configuration from '" + path + "'");
  -        }
  +        if (debug >= 1) {
  +            log("Initializing application path '" + prefix +
  +                "' configuration from '" + path + "'");
  +        }
   
           // Parse the application configuration for this application
           ApplicationConfig config = null;
           InputStream input = null;
  +        String value = null;
           try {
               config = new ApplicationConfig(prefix, this);
               Digester digester = initConfigDigester();
  @@ -1330,1379 +691,327 @@
               }
           }
   
  -        // Special handling for the default application - override any
  -        // configuration parameters that were set as servlet initialization
  -        // parameters using the old syntax
  +        // Is this the configuration for the default sub-application?
           if (prefix.length() > 0) {
               config.freeze();
               return (config);
           }
  +
  +        // Special handling for the default app's ControllerConfig
           ControllerConfig cc = config.getControllerConfig();
  -        if (getServletConfig().getInitParameter("bufferSize") != null) {
  -            cc.setBufferSize(bufferSize);
  -        }
  -        if (getServletConfig().getInitParameter("content") != null) {
  -            cc.setContentType(content);
  -        }
  -        if (getServletConfig().getInitParameter("locale") != null) {
  -            cc.setLocale(locale);
  -        }
  -        if (getServletConfig().getInitParameter("maxFileSize") != null) {
  -            cc.setMaxFileSize(maxFileSize);
  +        value = getServletConfig().getInitParameter("bufferSize");
  +        if (value != null) {
  +            cc.setBufferSize(Integer.parseInt(value));
           }
  -        if (getServletConfig().getInitParameter("nocache") != null) {
  -            cc.setNocache(nocache);
  +        value = getServletConfig().getInitParameter("content");
  +        if (value != null) {
  +            cc.setContentType(value);
           }
  -        if (getServletConfig().getInitParameter("tempDir") != null) {
  -            cc.setTempDir(tempDir);
  -        }
  -        MessageResourcesConfig mrc = config.getMessageResourcesConfig();
  -        String value = null;
  -        value = getServletConfig().getInitParameter("application");
  -        if (value != null) {
  -            mrc.setParameter(value);
  -        }
  -        if (getServletConfig().getInitParameter("factory") != null) {
  -            mrc.setFactory(factoryClass);
  -        }
  -        value = getServletConfig().getInitParameter("null");
  +        value = getServletConfig().getInitParameter("locale");
           if (value != null) {
               if (value.equalsIgnoreCase("true") ||
                   value.equalsIgnoreCase("yes")) {
  -                mrc.setNull(true);
  +                cc.setLocale(true);
               } else {
  -                mrc.setNull(false);
  -            }
  -        }
  -        config.freeze();
  -        return (config);
  -
  -    }
  -
  -
  -    /**
  -     * <p>Initialize the application data sources for the specified
  -     * sub-application.</p>
  -     *
  -     * @param config ApplicationConfig information for this application
  -     *
  -     * @exception ServletException if initialization cannot be performed
  -     */
  -    protected void initApplicationDataSources
  -        (ApplicationConfig config) throws ServletException {
  -
  -        if (debug >= 1) {
  -            log("Initializing application path '" + config.getPrefix() +
  -                "' data sources");
  -        }
  -
  -        ServletContextWriter scw =
  -            new ServletContextWriter(getServletContext());
  -        DataSourceConfig dscs[] = config.findDataSourceConfigs();
  -        if (dscs == null) {
  -            return;
  -        }
  -        for (int i = 0; i < dscs.length; i++) {
  -            if (debug >= 1) {
  -                log("Initializing application path '" + config.getPrefix() +
  -                    "' data source '" + dscs[i].getKey() + "'");
  -            }
  -            DataSource ds = null;
  -            try {
  -                // FIXME - Support user-specified data source classes again
  -                ds = new GenericDataSource();
  -                PropertyUtils.copyProperties(ds, dscs[i]);
  -                if (ds instanceof GenericDataSource) {
  -                    ((GenericDataSource) ds).open();
  -                }
  -            } catch (Throwable t) {
  -                log(internal.getMessage
  -                    ("dataSource.init", dscs[i].getKey()), t);
  -                throw new UnavailableException
  -                    (internal.getMessage("dataSource.init", dscs[i].getKey()));
  -            }
  -            getServletContext().setAttribute(dscs[i].getKey(), ds);
  -        }
  -
  -    }
  -
  -
  -    /**
  -     * <p>Initialize the application MessageResources for the specified
  -     * sub-application.</p>
  -     *
  -     * @param config ApplicationConfig information for this application
  -     *
  -     * @exception ServletException if initialization cannot be performed
  -     */
  -    protected void initApplicationMessageResources
  -        (ApplicationConfig config) throws ServletException {
  -
  -        MessageResourcesConfig mrc = config.getMessageResourcesConfig();
  -        if ((mrc.getFactory() == null) || (mrc.getParameter() == null)) {
  -            return;
  -        }
  -        if (debug >= 1) {
  -            log("Initializing application path '" + config.getPrefix() +
  -                "' message resources from '" + mrc.getParameter() + "'");
  -        }
  -
  -        try {
  -            String factory = mrc.getFactory();
  -            MessageResourcesFactory.setFactoryClass(factory);
  -            MessageResourcesFactory factoryObject =
  -                MessageResourcesFactory.createFactory();
  -            MessageResources resources =
  -                factoryObject.createResources(mrc.getParameter());
  -            resources.setReturnNull(mrc.getNull());
  -            getServletContext().setAttribute
  -                (Action.MESSAGES_KEY + config.getPrefix(), resources);
  -        } catch (Throwable t) {
  -            log(internal.getMessage
  -                ("applicationResources", mrc.getParameter()), t);
  -            throw new UnavailableException
  -                (internal.getMessage
  -                 ("applicationResources", mrc.getParameter()));
  -        }
  -
  -    }
  -
  -
  -    /**
  -     * <p>Create (if needed) and return a new Digester instance that has been
  -     * initialized to process Struts application configuraiton files and
  -     * configure a corresponding ApplicationConfig object (which must be
  -     * pushed on to the evaluation stack before parsing begins).</p>
  -     */
  -    protected Digester initConfigDigester() {
  -
  -        // Do we have an existing instance?
  -        if (configDigester != null) {
  -            return (configDigester);
  -        }
  -
  -        // Create and return a new Digester instance
  -        configDigester = new Digester();
  -        configDigester.setDebug(detail);
  -        configDigester.setNamespaceAware(true);
  -        configDigester.setValidating(validating);
  -        configDigester.addRuleSet(new ConfigRuleSet());
  -        for (int i = 0; i < registrations.length; i += 2) {
  -            URL url = this.getClass().getResource(registrations[i+1]);
  -            if (url != null)
  -                configDigester.register(registrations[i], url.toString());
  -        }
  -        return (configDigester);
  -    }
  -
  -
  -    /**
  -     * Initialize use of the data sources associated with this
  -     * application (if any).
  -     *
  -     * @exception ServletException if a fatal initialization error occurs
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    protected void initDataSources() throws ServletException {
  -
  -        ServletContextWriter scw =
  -            new ServletContextWriter(getServletContext());
  -
  -        synchronized (dataSources) {
  -            Iterator keys = dataSources.keySet().iterator();
  -            while (keys.hasNext()) {
  -                String key = (String) keys.next();
  -                DataSource dataSource = findDataSource(key);
  -                try {
  -                    dataSource.setLogWriter(scw);
  -                } catch (SQLException e) {
  -                    log(internal.getMessage("initDataSource", key), e);
  -                    throw new ServletException
  -                        (internal.getMessage("initDataSource", key), e);
  -                }
  -                if (dataSource instanceof GenericDataSource) {
  -                    if (debug >= 1)
  -                        log(internal.getMessage("dataSource.init", key));
  -                    try {
  -                        ((GenericDataSource) dataSource).open();
  -                    } catch (SQLException e) {
  -                        log(internal.getMessage("initDataSource", key), e);
  -                        throw new ServletException
  -                            (internal.getMessage("initDataSource", key), e);
  -                    }
  -                }
  -                getServletContext().setAttribute(key, dataSource);
  +                cc.setLocale(false);
               }
  -            dataSources.setFast(true);
  -        }
  -
  -    }
  -
  -
  -    /**
  -     * Initialize the debugging detail levels for this application.
  -     *
  -     * @exception ServletException if we cannot initialize these resources
  -     */
  -    protected void initDebug() throws ServletException {
  -
  -        String value = null;
  -        try {
  -            value = getServletConfig().getInitParameter("debug");
  -            debug = Integer.parseInt(value);
  -        } catch (Throwable t) {
  -            debug = 0;
  -        }
  -        try {
  -            value = getServletConfig().getInitParameter("detail");
  -            detail = Integer.parseInt(value);
  -        } catch (Throwable t) {
  -            detail = 0;
  -        }
  -
  -    }
  -
  -
  -    /**
  -     * Construct and return a digester that uses the standard configuration
  -     * file format.
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    protected Digester initDigester(int detail) {
  -
  -        // Initialize a new Digester instance
  -        Digester digester = new Digester();
  -        digester.push(this);
  -        digester.setDebug(detail);
  -        digester.setNamespaceAware(true);
  -        digester.setValidating(validating);
  -
  -        // Register our local copy of the DTDs that we can find
  -        for (int i = 0; i < registrations.length; i += 2) {
  -            URL url = this.getClass().getResource(registrations[i+1]);
  -            if (url != null)
  -                digester.register(registrations[i], url.toString());
  -        }
  -
  -        // Configure the processing rules
  -
  -        digester.addObjectCreate("struts-config/data-sources/data-source",
  -                                 "org.apache.struts.util.GenericDataSource",
  -                                 "type");
  -        digester.addSetProperties("struts-config/data-sources/data-source");
  -        digester.addRule("struts-config/data-sources/data-source",
  -                         new AddDataSourceRule(digester));
  -        digester.addSetProperty
  -            ("struts-config/data-sources/data-source/set-property",
  -             "property", "value");
  -
  -        digester.addObjectCreate("struts-config/action-mappings/action",
  -                                 mappingClass, "className");
  -        digester.addSetProperties("struts-config/action-mappings/action");
  -        digester.addSetNext("struts-config/action-mappings/action",
  -                            "addMapping",
  -                            "org.apache.struts.action.ActionMapping");
  -
  -        digester.addSetProperty
  -            ("struts-config/action-mappings/action/set-property",
  -             "property", "value");
  -
  -        digester.addObjectCreate
  -            ("struts-config/action-mappings/action/forward",
  -             forwardClass, "className");
  -        digester.addSetProperties
  -            ("struts-config/action-mappings/action/forward");
  -        digester.addSetNext("struts-config/action-mappings/action/forward",
  -                            "addForward",
  -                            "org.apache.struts.action.ActionForward");
  -
  -        digester.addObjectCreate
  -            ("struts-config/action-mappings/action/exception",
  -             exceptionClass, "className");
  -        digester.addSetProperties
  -            ("struts-config/action-mappings/action/exception");
  -        digester.addSetNext
  -            ("struts-config/action-mappings/action/exception",
  -             "addException",
  -             "org.apache.struts.action.ActionException");
  -
  -        digester.addSetProperty
  -            ("struts-config/action-mappings/action/forward/set-property",
  -             "property", "value");
  -
  -        digester.addObjectCreate("struts-config/form-beans/form-bean",
  -                                 formBeanClass, "className");
  -        digester.addSetProperties("struts-config/form-beans/form-bean");
  -        digester.addSetNext("struts-config/form-beans/form-bean",
  -                            "addFormBean",
  -                            "org.apache.struts.action.ActionFormBean");
  -
  -        digester.addSetProperty
  -            ("struts-config/form-beans/form-bean/set-property",
  -             "property", "value");
  -
  -        digester.addObjectCreate("struts-config/global-exceptions/exception",
  -                                 exceptionClass, "className");
  -        digester.addSetProperties("struts-config/global-exceptions/exception");
  -        digester.addSetNext("struts-config/global-exceptions/exception",
  -                            "addException",
  -                            "org.apache.struts.action.ActionException");
  -
  -        digester.addSetProperty
  -            ("struts-config/global-exceptions/exception/set-property",
  -             "property", "value");
  -
  -        digester.addObjectCreate("struts-config/global-forwards/forward",
  -                                 forwardClass, "className");
  -        digester.addSetProperties("struts-config/global-forwards/forward");
  -        digester.addSetNext("struts-config/global-forwards/forward",
  -                            "addForward",
  -                            "org.apache.struts.action.ActionForward");
  -
  -        digester.addSetProperty
  -            ("struts-config/global-forwards/forward/set-property",
  -             "property", "value");
  -
  -        return (digester);
  -
  -    }
  -
  -
  -    /**
  -     * Initialize our internal MessageResources bundle.
  -     *
  -     * @exception ServletException if we cannot initialize these resources
  -     */
  -    protected void initInternal() throws ServletException {
  -
  -        try {
  -            internal = MessageResources.getMessageResources(internalName);
  -        } catch (MissingResourceException e) {
  -            log("Cannot load internal resources from '" + internalName + "'",
  -                e);
  -            throw new UnavailableException
  -                ("Cannot load internal resources from '" + internalName + "'");
  -        }
  -
  -    }
  -
  -
  -    /**
  -     * Initialize the mapping information for this application.
  -     *
  -     * @exception IOException if an input/output error is encountered
  -     * @exception ServletException if we cannot initialize these resources
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    protected void initMapping() throws IOException, ServletException {
  -
  -        String value = null;
  -
  -        // Link our mappings collection to this servlet instance
  -        mappings.setServlet(this);
  -
  -        // Initialize the debugging detail level we will use
  -        int detail;
  -        try {
  -            value = getServletConfig().getInitParameter("detail");
  -            detail = Integer.parseInt(value);
  -        } catch (Throwable t) {
  -            detail = 0;
           }
  -
  -        // Initialize the validating XML parser flag
  -        value = getServletConfig().getInitParameter("validating");
  +        value = getServletConfig().getInitParameter("maxFileSize");
           if (value != null) {
  -            if (value.equalsIgnoreCase("true") ||
  -                value.equalsIgnoreCase("yes"))
  -                validating = true;
  -            else
  -                validating = false;
  +            cc.setMaxFileSize(value);
           }
  -
  -        // Initialize the name of our ActionFormBean implementation class
  -        value = getServletConfig().getInitParameter("formBean");
  -        if (value != null)
  -            formBeanClass = value;
  -
  -        // Initialize the name of our ActionForward implementation class
  -        value = getServletConfig().getInitParameter("forward");
  -        if (value != null)
  -            forwardClass = value;
  -
  -        // Initialize the name of our ActionMapping implementation class
  -        value = getServletConfig().getInitParameter("mapping");
  -        if (value != null)
  -            mappingClass = value;
  -
  -        // Initialize the context-relative path to our configuration resources
  -        value = getServletConfig().getInitParameter("config");
  -        if (value != null)
  -            config = value;
  -        if (debug >= 1)
  -            log(internal.getMessage("configInit", config));
  -
  -        // Acquire an input stream to our configuration resource
  -        InputStream input = getServletContext().getResourceAsStream(config);
  -        if (input == null)
  -            throw new UnavailableException
  -                (internal.getMessage("configMissing", config));
  -
  -        // Build a digester to process our configuration resource
  -        Digester digester = initDigester(detail);
  -
  -        // Parse the input stream to configure our mappings
  -        try {
  -            formBeans.setFast(false);
  -            forwards.setFast(false);
  -            mappings.setFast(false);
  -            digester.parse(input);
  -            mappings.setFast(true);
  -            forwards.setFast(true);
  -            formBeans.setFast(true);
  -        } catch (SAXException e) {
  -            throw new ServletException
  -                (internal.getMessage("configParse", config), e);
  -        } finally {
  -            input.close();
  -        }
  -
  -    }
  -
  -
  -    /**
  -     * Initialize other configuration parameters that have not yet
  -     * been processed.
  -     *
  -     * @exception ServletException if we cannot initialize these resources
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    protected void initOther() throws ServletException {
  -
  -        // Process the "content", "locale", and "nocache" parameters
  -        String value = null;
  -        value = getServletConfig().getInitParameter("content");
  -        if (value != null)
  -            content = value;
  -
  -        value = getServletConfig().getInitParameter("locale");
  -        if (value != null) {
  -            if ("true".equalsIgnoreCase(value) ||
  -                "yes".equalsIgnoreCase(value))
  -                locale = true;
  -            else
  -                locale = false;
  -        }
  -
           value = getServletConfig().getInitParameter("nocache");
           if (value != null) {
  -            if ("true".equalsIgnoreCase(value) ||
  -                "yes".equalsIgnoreCase(value))
  -                nocache = true;
  -        }
  -
  -        // Publish our internal collections as necessary
  -        getServletContext().setAttribute(Action.FORM_BEANS_KEY, formBeans);
  -        getServletContext().setAttribute(Action.FORWARDS_KEY, forwards);
  -        getServletContext().setAttribute(Action.MAPPINGS_KEY, mappings);
  -
  -    }
  -
  -
  -    /**
  -     * Initialize the servlet mapping under which our controller servlet
  -     * is being accessed.  This will be used in the <code>&html:form&gt;</code>
  -     * tag to generate correct destination URLs for form submissions.
  -     */
  -    protected void initServlet() throws ServletException {
  -
  -        // Remember our servlet name
  -        this.servletName = getServletConfig().getServletName();
  -
  -        // Prepare a Digester to scan the web application deployment descriptor
  -        Digester digester = new Digester();
  -        digester.push(this);
  -        digester.setDebug(this.debug);
  -        digester.setNamespaceAware(true);
  -        digester.setValidating(false);
  -
  -        // Register our local copy of the DTDs that we can find
  -        for (int i = 0; i < registrations.length; i += 2) {
  -            URL url = this.getClass().getResource(registrations[i+1]);
  -            if (url != null)
  -                digester.register(registrations[i], url.toString());
  -        }
  -
  -        // Configure the processing rules that we need
  -        digester.addCallMethod("web-app/servlet-mapping",
  -                               "addServletMapping", 2);
  -        digester.addCallParam("web-app/servlet-mapping/servlet-name", 0);
  -        digester.addCallParam("web-app/servlet-mapping/url-pattern", 1);
  -
  -        // Process the web application deployment descriptor
  -        if (debug >= 1)
  -            log("Scanning web.xml for controller servlet mapping");
  -        InputStream input= null;
  -        try {
  -            input =
  -                getServletContext().getResourceAsStream("/WEB-INF/web.xml");
  -            digester.parse(input);
  -        } catch (Throwable e) {
  -            log(internal.getMessage("configWebXml"), e);
  -        } finally {
  -            if (input != null)
  -                input = null;
  -        }
  -
  -        // Record a servlet context attribute (if appropriate)
  -        if (debug >= 1)
  -            log("Mapping for servlet '" + servletName + "' = '" +
  -                servletMapping + "'");
  -        if (servletMapping != null)
  -            getServletContext().setAttribute(Action.SERVLET_KEY,
  -                                             servletMapping);
  -
  -    }
  -
  -
  -    /**
  -     * Initialize upload parameters and "bufferSize", "multipartClass",
  -     * "maxFileSize", "tempDir"
  -     *
  -     * @exception ServletException if there are invalid parameters
  -     *
  -     * @deprecated Will no longer be required with multi-application support
  -     */
  -    protected void initUpload() throws ServletException {
  -
  -        //buffer size
  -        String bufferValue = getServletConfig().getInitParameter("bufferSize");
  -
  -        if ((bufferValue != null) && (bufferValue.length() > 0)) {
  -            int oldBufferSize = bufferSize;
  -            try {
  -                bufferSize = Integer.parseInt(bufferValue, 10);
  -            }
  -            catch (NumberFormatException nfe) {
  -                if (debug > 0) {
  -                    log("initUpload(): invalid value \"" + bufferSize + "\" for " +
  -                        "init-parameter \"buffer size\"" +
  -                        ", defaulting to \"" + oldBufferSize + "\"");
  -                }
  -                bufferSize = oldBufferSize;
  -            }
  -        }
  -
  -        //multipart class
  -        String classValue = getServletConfig().getInitParameter("multipartClass");
  -
  -        if ((classValue != null) && (classValue.length() > 0)) {
  -            if (classValue.equals("none"))
  -                multipartClass = null;
  -            else
  -                multipartClass = classValue;
  -        }
  -
  -        //maximum file size
  -        String maxsizeValue = getServletConfig().getInitParameter("maxFileSize");
  -
  -        if ((maxsizeValue != null) && (maxsizeValue.length() > 0)) {
  -            maxFileSize = maxsizeValue;
  -        }
  -
  -        //temp directory
  -        String tempDirValue = getServletConfig().getInitParameter("tempDir");
  -
  -        if ((tempDirValue != null) && (tempDirValue.length() > 0)) {
  -            tempDir = tempDirValue;
  -        }
  -    }
  -
  -
  -
  -    /**
  -     * Process an HTTP request.
  -     *
  -     * @param request The servlet request we are processing
  -     * @param response The servlet response we are creating
  -     *
  -     * @exception IOException if an input/output error occurs
  -     * @exception ServletException if a servlet exception occurs
  -     */
  -    protected void process(HttpServletRequest request,
  -               HttpServletResponse response)
  -        throws IOException, ServletException {
  -
  -        String contentType = request.getContentType();
  -        String method = request.getMethod();
  -
  -        //if this is a multipart request, wrap the HttpServletRequest object
  -        //with a MultipartRequestWrapper to keep the process sub-methods
  -        //from failing when checking for certain request parameters
  -        //for command tokens and cancel button detection
  -        if ((contentType != null) && (contentType.startsWith("multipart/form-data"))
  -            && (method.equals("POST"))) {
  -            request = new MultipartRequestWrapper(request);
  -        }
  -
  -        // Automatically select the sub-application for this request
  -        processApplication(request);
  -
  -        // Identify the path component we will use to select a mapping
  -        String path = processPath(request);
  -        if (path == null) {
  -            if (debug >= 1)
  -                log(" No path available for request URI " +
  -                    request.getRequestURI());
  -            response.sendError(HttpServletResponse.SC_BAD_REQUEST,
  -                               internal.getMessage("processPath"));
  -            return;
  -        }
  -        if (debug >= 1)
  -            log("Processing a " + request.getMethod() + " for " + path);
  -
  -        // Automatically select a locale for this user if requested
  -        processLocale(request);
  -
  -        // Set the content type and no-caching headers if requested
  -        processContent(response);
  -        processNoCache(response);
  -
  -        // General purpose preprocessing hook
  -        if (!processPreprocess(request, response))
  -            return;
  -
  -        // Look up the corresponding mapping
  -        ActionMapping mapping = processMapping(path, request);
  -        if (mapping == null) {
  -            if (debug >= 1)
  -                log(" No mapping available for path " + path);
  -            response.sendError(HttpServletResponse.SC_BAD_REQUEST,
  -                               internal.getMessage("processInvalid", path));
  -            return;
  -        }
  -
  -        // Process any ActionForm bean related to this request
  -        ActionForm formInstance = processActionForm(mapping, request);
  -        processPopulate(formInstance, mapping, request);
  -        if (!processValidate(mapping, formInstance, request, response))
  -            return;
  -
  -        // Execute a forward if specified by this mapping
  -        if (!processForward(mapping, request, response))
  -            return;
  -
  -        // Execute an include if specified by this mapping
  -        if (!processInclude(mapping, request, response))
  -            return;
  -
  -        // Acquire the Action instance to process this request
  -        Action actionInstance = processActionCreate(mapping, request);
  -        if (actionInstance == null) {
  -            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
  -                               internal.getMessage("actionCreate",
  -                                                   mapping.getPath()));
  -            return;
  -        }
  -
  -        // Call the Action instance itself
  -        ActionForward forward =
  -            processActionPerform(actionInstance, mapping, formInstance,
  -                                 request, response);
  -        //set the request back to it's normal state if it's currently wrapped,
  -        //to avoid ClassCastExceptions from ServletContainers if forwarding
  -        if (request instanceof MultipartRequestWrapper) {
  -            request = ((MultipartRequestWrapper) request).getRequest();
  -        }
  -
  -        // Process the returned ActionForward (if any)
  -        processActionForward(forward, mapping, formInstance,
  -                             request, response);
  -
  -    }
  -
  -
  -    /**
  -     * Create or retrieve the Action instance that will process this request,
  -     * or <code>null</code> if no such Action instance can be created.
  -     *
  -     * @param mapping The ActionMapping we are processing
  -     * @param request The servlet request we are processing
  -     */
  -    protected Action processActionCreate(ActionMapping mapping,
  -                                         HttpServletRequest request) {
  -
  -        // Acquire the Action instance we will be using
  -        String actionClass = mapping.getType();
  -        if (debug >= 1)
  -            log(" Looking for Action instance for class " + actionClass);
  -        Action actionInstance = (Action) actions.get(actionClass);
  -        if (actionInstance == null) {
  -            synchronized (actions) {
  -                if (debug >= 1)
  -                    log("  Double checking for Action instance already there");
  -                // Double check to avoid a race condition
  -                actionInstance = (Action) actions.get(actionClass);
  -                if (actionInstance != null)
  -                    return (actionInstance);
  -                // Go ahead and create the new Action instance
  -                // ASSERT:  This will never ever happen more than once
  -                //  for a particular action class name
  -                try {
  -                    if (debug >= 1)
  -                        log("  Creating new Action instance");
  -                    Class clazz = Class.forName(actionClass);
  -                    actionInstance = (Action) clazz.newInstance();
  -                    actionInstance.setServlet(this);
  -                    actions.put(actionClass, actionInstance);
  -                } catch (Throwable t) {
  -                    log("Error creating Action instance for path '" +
  -                        mapping.getPath() + "', class name '" +
  -                        actionClass + "'", t);
  -                    return (null);
  -                }
  -            }
  -        }
  -        return (actionInstance);
  -
  -    }
  -
  -
  -    /**
  -     * Retrieve and return the <code>ActionForm</code> bean associated with
  -     * this mapping, creating and stashing one if necessary.  If there is no
  -     * form bean associated with this mapping, return <code>null</code>.
  -     *
  -     * @param mapping The ActionMapping we are processing
  -     * @param request The servlet request we are processing
  -     */
  -    protected ActionForm processActionForm(ActionMapping mapping,
  -                           HttpServletRequest request) {
  -
  -        // Is there a form bean associated with this mapping?
  -        String attribute = mapping.getAttribute();
  -        if (attribute == null)
  -            return (null);
  -
  -        // Look up the existing form bean, if any
  -        if (debug >= 1)
  -            log(" Looking for ActionForm bean under attribute '" +
  -                attribute + "'");
  -        ActionForm instance = null;
  -        HttpSession session = null;
  -        if ("request".equals(mapping.getScope())) {
  -            instance = (ActionForm) request.getAttribute(attribute);
  -        } else {
  -            session = request.getSession();
  -            instance = (ActionForm) session.getAttribute(attribute);
  -        }
  -
  -        // Determine the form bean class that we expect to use
  -        String name = mapping.getName();
  -        String className = null;
  -        ActionFormBean formBean = findFormBean(name);
  -        if (formBean != null)
  -            className = formBean.getType();
  -        else
  -            return (null);
  -
  -        // Can we recycle the existing form bean instance?
  -        if ((instance != null) &&
  -            className.equals(instance.getClass().getName())) {
  -            if (debug >= 1)
  -                log(" Recycling existing ActionForm bean instance of class '"
  -                    + className + "'");
  -            return (instance);
  -        }
  -
  -        // Create a new form bean if we need to
  -        if (debug >= 1)
  -            log(" Creating new ActionForm instance of class '"
  -                + className + "'");
  -        try {
  -            instance = null;
  -            Class clazz = Class.forName(className);
  -            instance = (ActionForm) clazz.newInstance();
  -        } catch (Throwable t) {
  -            log("Error creating ActionForm instance of class '" +
  -                className + "'", t);
  -        }
  -        if (instance == null)
  -            return (null);
  -
  -        // Store the newly created bean in the appropriate scope
  -        if (debug >= 1)
  -            log(" Storing instance under attribute '" +
  -                attribute + "' in scope '" + mapping.getScope() + "'");
  -        if ("request".equals(mapping.getScope()))
  -            request.setAttribute(attribute, instance);
  -        else
  -            session.setAttribute(attribute, instance);
  -        return (instance);
  -
  -    }
  -
  -
  -    /**
  -     * Identify and record the sub-application that is responsible for
  -     * processing this request.
  -     *
  -     * @param request The servlet request we are processing
  -     */
  -    protected void processApplication(HttpServletRequest request) {
  -
  -        RequestUtils.selectApplication(request, getServletContext());
  -
  -    }
  -
  -
  -    /**
  -     * Forward to the specified destination, by the specified mechanism,
  -     * if an <code>ActionForward</code> instance was returned by the
  -     * <code>Action</code>.
  -     *
  -     * @param forward The ActionForward returned by our action
  -     * @param mapping The ActionMapping we are processing
  -     * @param formInstance The ActionForm we are processing
  -     * @param request The servlet request we are processing
  -     * @param response The servlet response we are creating
  -     *
  -     * @exception IOException if an input/output error occurs
  -     * @exception ServletException if a servlet exception occurs
  -     */
  -    protected void processActionForward(ActionForward forward,
  -                                        ActionMapping mapping,
  -                                        ActionForm formInstance,
  -                                        HttpServletRequest request,
  -                                        HttpServletResponse response)
  -        throws IOException, ServletException {
  -
  -        if (forward != null) {
  -            String path = forward.getPath();
  -            if (forward.getRedirect()) {
  -                if (path.startsWith("/"))
  -                    path = request.getContextPath() + path;
  -                response.sendRedirect(response.encodeRedirectURL(path));
  +            if (value.equalsIgnoreCase("true") ||
  +                value.equalsIgnoreCase("yes")) {
  +                cc.setNocache(true);
               } else {
  -                RequestDispatcher rd =
  -                    getServletContext().getRequestDispatcher(path);
  -                if (rd == null) {
  -                    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
  -                                       internal.getMessage("requestDispatcher",
  -                                                           path));
  -                    return;
  -                }
  -                rd.forward(request, response);
  +                cc.setNocache(false);
               }
           }
  -
  -    }
  -
  -
  -    /**
  -     * Ask the specified Action instance to handle this request.  Return
  -     * the <code>ActionForward</code> instance (if any) returned by
  -     * the called <code>Action</code>.
  -     *
  -     * @param action The Action to process this request
  -     * @param mapping The ActionMapping we are processing
  -     * @param formInstance The ActionForm we are processing
  -     * @param request The servlet request we are processing
  -     * @param response The servlet response we are creating
  -     *
  -     * @exception IOException if an input/output error occurs
  -     * @exception ServletException if a servlet exception occurs
  -     */
  -    protected ActionForward processActionPerform(Action action,
  -                                        ActionMapping mapping,
  -                                        ActionForm formInstance,
  -                                        HttpServletRequest request,
  -                                        HttpServletResponse response)
  -        throws IOException, ServletException {
  -
  -        //        ActionForward forward =
  -        //            action.perform(mapping, formInstance, request, response);
  -        //        return (forward);
  -
  -        ActionError error = null;
  -        Throwable cause = null;
  -        try {
  -            ActionForward forward =
  -                action.execute(mapping, formInstance, request, response);
  -            return (forward);
  -        } catch (Exception ex) {
  -            if (debug >= 1) {
  -                log("Exception occurred", ex);
  -            }
  -            return (processException(ex, mapping, formInstance,
  -                                     request, response));
  +        value = getServletConfig().getInitParameter("tempDir");
  +        if (value != null) {
  +            cc.setTempDir(value);
           }
   
  -
  -    }
  -
  -
  -    /**
  -     * Set the default content type (with optional character encoding) for
  -     * all responses.  This value may be overridden by forwarded-to servlets
  -     * or JSP pages.
  -     *
  -     * @param response The response we are processing
  -     */
  -    protected void processContent(HttpServletResponse response) {
  -
  -        if (content != null)
  -            response.setContentType(content);
  -
  -    }
  -
  -
  -    /**
  -     * Ask our exception handler to handle the exception.  Return the
  -     * <code>ActionForward</code> instance (if any) returned by the called
  -     * <code>ExceptionHandler</code>.
  -     *
  -     * @param ex The exception to handle
  -     * @param maping The ActionMapping we are processing
  -     * @param form The ActionForm we are processing (if any)
  -     * @param request The servlet request we are processing
  -     * @param response The servlet response we are processing
  -     *
  -     * @exception ServletException if a servlet exception occurs
  -     */
  -    protected ActionForward processException(Exception ex,
  -                                             ActionMapping mapping,
  -                                             ActionForm form,
  -                                             HttpServletRequest request,
  -                                             HttpServletResponse response)
  -        throws ServletException {
  -
  -        // Look for an exception mapping
  -        ActionException ae = mapping.findException(ex.getClass());
  -
  -        // If one is found, place it in the scope defined
  -        if (ae != null) {
  -            Class handlerClass = ae.getHandlerClass();
  -            try {
  -                // Ask handler to handle the exception
  -                ExceptionHandler handler = (ExceptionHandler)
  -                    handlerClass.newInstance();
  -                return (handler.execute(ex, ae, mapping, form,
  -                                        request, response));
  -            } catch (Exception e) {
  -                // Yuck - the exception handler thew an exception
  -                throw new ServletException(e);
  -            }
  -        } else {
  -            if (debug >= 1) {
  -                log(internal.getMessage("unhandledException", ex.getClass()));
  -            }
  -            if (ex instanceof ServletException) {
  -                throw (ServletException) ex;
  +        // Special handling for the default app's MessageResourcesConfig
  +        MessageResourcesConfig mrc = config.getMessageResourcesConfig();
  +        value = getServletConfig().getInitParameter("application");
  +        if (value != null) {
  +            mrc.setParameter(value);
  +        }
  +        value= getServletConfig().getInitParameter("factory");
  +        if (value != null) {
  +            mrc.setFactory(value);
  +        }
  +        value = getServletConfig().getInitParameter("null");
  +        if (value != null) {
  +            if (value.equalsIgnoreCase("true") ||
  +                value.equalsIgnoreCase("yes")) {
  +                mrc.setNull(true);
  +            } else {
  +                mrc.setNull(false);
               }
  -            throw new ServletException(ex);
           }
  +        config.freeze();
  +        return (config);
   
       }
  -                                             
   
   
       /**
  -     * Process a forward requested by this mapping, if any.  Return
  -     * <code>true</code> if processing of this request should continue (i.e.
  -     * be processed by an Action class), or <code>false</code> if we have
  -     * already handled this request.
  +     * <p>Initialize the application data sources for the specified
  +     * sub-application.</p>
        *
  -     * @param mapping The ActionMapping we are processing
  -     * @param request The request we are processing
  -     * @param response The response we are processing
  +     * @param config ApplicationConfig information for this application
        *
  -     * @exception IOException if the included resource throws an exception
  -     * @exception ServletException if the included resource throws an
  -     *  exception
  +     * @exception ServletException if initialization cannot be performed
        */
  -    protected boolean processForward(ActionMapping mapping,
  -                                     HttpServletRequest request,
  -                                     HttpServletResponse response)
  -        throws IOException, ServletException {
  -
  -        // Are we going to process this request?
  -        String forward = mapping.getForward();
  -        if (forward == null)
  -            return (true);
  +    protected void initApplicationDataSources
  +        (ApplicationConfig config) throws ServletException {
   
  -        //unwrap the multipart request if there is one
  -        if (request instanceof MultipartRequestWrapper) {
  -            request = ((MultipartRequestWrapper) request).getRequest();
  +        if (debug >= 1) {
  +            log("Initializing application path '" + config.getPrefix() +
  +                "' data sources");
           }
   
  -        // Construct a request dispatcher for the specified path
  -        RequestDispatcher rd =
  -            getServletContext().getRequestDispatcher(forward);
  -        if (rd == null) {
  -            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
  -                               internal.getMessage("requestDispatcher",
  -                                                   forward));
  -            return (false);
  +        ServletContextWriter scw =
  +            new ServletContextWriter(getServletContext());
  +        DataSourceConfig dscs[] = config.findDataSourceConfigs();
  +        if (dscs == null) {
  +            return;
           }
  -
  -        // Delegate the processing of this request
  -        rd.forward(request, response);
  -        return (false);
  +        dataSources.setFast(false);
  +        for (int i = 0; i < dscs.length; i++) {
  +            if (debug >= 1) {
  +                log("Initializing application path '" + config.getPrefix() +
  +                    "' data source '" + dscs[i].getKey() + "'");
  +            }
  +            DataSource ds = null;
  +            try {
  +                // FIXME - Support user-specified data source classes again
  +                ds = new GenericDataSource();
  +                PropertyUtils.copyProperties(ds, dscs[i]);
  +                ds.setLogWriter(scw);
  +                if (ds instanceof GenericDataSource) {
  +                    ((GenericDataSource) ds).open();
  +                }
  +            } catch (Throwable t) {
  +                log(internal.getMessage
  +                    ("dataSource.init", dscs[i].getKey()), t);
  +                throw new UnavailableException
  +                    (internal.getMessage("dataSource.init", dscs[i].getKey()));
  +            }
  +            getServletContext().setAttribute(dscs[i].getKey(), ds);
  +            dataSources.put(dscs[i].getKey(), ds);
  +        }
  +        dataSources.setFast(true);
   
       }
   
   
       /**
  -     * Process an include requested by this mapping, if any.  Return
  -     * <code>true</code> if processing of this request should continue (i.e.
  -     * be processed by an Action class), or <code>false</code> if we have
  -     * already handled this request.
  +     * <p>Initialize the application MessageResources for the specified
  +     * sub-application.</p>
        *
  -     * @param mapping The ActionMapping we are processing
  -     * @param request The request we are processing
  -     * @param response The response we are processing
  +     * @param config ApplicationConfig information for this application
        *
  -     * @exception IOException if the included resource throws an exception
  -     * @exception ServletException if the included resource throws an
  -     *  exception
  +     * @exception ServletException if initialization cannot be performed
        */
  -    protected boolean processInclude(ActionMapping mapping,
  -                                     HttpServletRequest request,
  -                                     HttpServletResponse response)
  -        throws IOException, ServletException {
  -
  -        // Are we going to process this request?
  -        String include = mapping.getInclude();
  -        if (include == null)
  -            return (true);
  +    protected void initApplicationMessageResources
  +        (ApplicationConfig config) throws ServletException {
   
  -        //unwrap the multipart request if there is one
  -        if (request instanceof MultipartRequestWrapper) {
  -            request = ((MultipartRequestWrapper) request).getRequest();
  +        MessageResourcesConfig mrc = config.getMessageResourcesConfig();
  +        if ((mrc.getFactory() == null) || (mrc.getParameter() == null)) {
  +            return;
           }
  -
  -        // Construct a request dispatcher for the specified path
  -        RequestDispatcher rd =
  -            getServletContext().getRequestDispatcher(include);
  -        if (rd == null) {
  -            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
  -                               internal.getMessage("requestDispatcher",
  -                                                   include));
  -            return (false);
  +        if (debug >= 1) {
  +            log("Initializing application path '" + config.getPrefix() +
  +                "' message resources from '" + mrc.getParameter() + "'");
           }
   
  -        // Delegate the processing of this request
  -        rd.include(request, response);
  -        return (false);
  -
  -    }
  -
  -
  -    /**
  -     * Automatically calculate an appropriate <code>java.util.Locale</code>
  -     * for this user, and store it in their session, if there is no such
  -     * Locale object present already.
  -     *
  -     * @param request The request we are processing
  -     */
  -    protected void processLocale(HttpServletRequest request) {
  -
  -        // Validate that we need to create a Locale
  -        if (!locale)
  -            return;             // Service not requested
  -        HttpSession session = request.getSession();
  -        if (session.getAttribute(Action.LOCALE_KEY) != null)
  -            return;             // Locale object is already present
  -
  -        // Use the Locale returned by the servlet container (if any)
  -        Locale locale = request.getLocale();
  -        if (locale != null) {
  -            if (debug >= 1)
  -                log("Setting locale '" + locale + "'");
  -            session.setAttribute(Action.LOCALE_KEY, locale);
  +        try {
  +            String factory = mrc.getFactory();
  +            MessageResourcesFactory.setFactoryClass(factory);
  +            MessageResourcesFactory factoryObject =
  +                MessageResourcesFactory.createFactory();
  +            MessageResources resources =
  +                factoryObject.createResources(mrc.getParameter());
  +            resources.setReturnNull(mrc.getNull());
  +            getServletContext().setAttribute
  +                (Action.MESSAGES_KEY + config.getPrefix(), resources);
  +        } catch (Throwable t) {
  +            log(internal.getMessage
  +                ("applicationResources", mrc.getParameter()), t);
  +            throw new UnavailableException
  +                (internal.getMessage
  +                 ("applicationResources", mrc.getParameter()));
           }
   
       }
   
   
       /**
  -     * Identify and return an appropriate ActionMapping for the specified
  -     * path.  If no such mapping can be identified, return <code>null</code>.
  -     * The <code>request</code> parameter is available if you need to make
  -     * decisions on available mappings (such as checking permissions) based
  -     * on request parameters or other properties, but it is not used in the
  -     * default implementation.
  -     *
  -     * @param path Path component used to select a mapping
  -     * @param request The request we are processing
  +     * <p>Create (if needed) and return a new Digester instance that has been
  +     * initialized to process Struts application configuraiton files and
  +     * configure a corresponding ApplicationConfig object (which must be
  +     * pushed on to the evaluation stack before parsing begins).</p>
        */
  -    protected ActionMapping processMapping(String path,
  -                                           HttpServletRequest request) {
  +    protected Digester initConfigDigester() {
   
  -        ActionMapping mapping = findMapping(path);
  -        if (mapping == null)
  -            mapping = mappings.getUnknown(request);
  -        if (mapping != null)
  -            request.setAttribute(Action.MAPPING_KEY, mapping);
  -        return (mapping);
  +        // Do we have an existing instance?
  +        if (configDigester != null) {
  +            return (configDigester);
  +        }
   
  +        // Create and return a new Digester instance
  +        configDigester = new Digester();
  +        configDigester.setDebug(detail);
  +        configDigester.setNamespaceAware(true);
  +        configDigester.setValidating(validating);
  +        configDigester.addRuleSet(new ConfigRuleSet());
  +        for (int i = 0; i < registrations.length; i += 2) {
  +            URL url = this.getClass().getResource(registrations[i+1]);
  +            if (url != null)
  +                configDigester.register(registrations[i], url.toString());
  +        }
  +        return (configDigester);
       }
   
   
       /**
  -     * Render the HTTP headers to defeat browser caching if requested.
  -     *
  -     * @param response The servlet response we are creating
  +     * Initialize our internal MessageResources bundle.
        *
  -     * @exception IOException if an input/output error occurs
  -     * @exception ServletException if a servlet exception occurs
  +     * @exception ServletException if we cannot initialize these resources
        */
  -    protected void processNoCache(HttpServletResponse response)
  -        throws IOException, ServletException {
  -
  -        if (!nocache)
  -            return;
  +    protected void initInternal() throws ServletException {
   
  -        response.setHeader("Pragma", "No-cache");
  -        response.setHeader("Cache-Control", "no-cache");
  -        response.setDateHeader("Expires", 1);
  +        try {
  +            internal = MessageResources.getMessageResources(internalName);
  +        } catch (MissingResourceException e) {
  +            log("Cannot load internal resources from '" + internalName + "'",
  +                e);
  +            throw new UnavailableException
  +                ("Cannot load internal resources from '" + internalName + "'");
  +        }
   
       }
   
   
       /**
  -     * Identify and return the path component (from the request URI) that
  -     * we will use to select an ActionMapping to dispatch with.  If no such
  -     * path can be identified, return <code>null</code>.
  +     * Initialize other global characteristics of the controller servlet.
        *
  -     * @param request The servlet request we are processing
  +     * @exception ServletException if we cannot initialize these resources
        */
  -    protected String processPath(HttpServletRequest request) {
  -
  -        String path = null;
  +    protected void initOther() throws ServletException {
   
  -        // For prefix matching, we want to match on the path info (if any)
  -        path =
  -            (String) request.getAttribute("javax.servlet.include.path_info");
  -        if (path == null)
  -            path = request.getPathInfo();
  -        if ((path != null) && (path.length() > 0))
  -            return (path);
  -
  -        // For extension matching, we want to strip the extension (if any)
  -        path =
  -            (String) request.getAttribute("javax.servlet.include.servlet_path");
  -        if (path == null)
  -            path = request.getServletPath();
  -        int slash = path.lastIndexOf("/");
  -        int period = path.lastIndexOf(".");
  -        if ((period >= 0) && (period > slash))
  -            path = path.substring(0, period);
  -        return (path);
  +        String value = null;
  +        value = getServletConfig().getInitParameter("config");
  +        if (value != null) {
  +            config = value;
  +        }
  +        try {
  +            value = getServletConfig().getInitParameter("debug");
  +            debug = Integer.parseInt(value);
  +        } catch (Throwable t) {
  +            debug = 0;
  +        }
  +        try {
  +            value = getServletConfig().getInitParameter("detail");
  +            detail = Integer.parseInt(value);
  +        } catch (Throwable t) {
  +            detail = 0;
  +        }
  +        value = getServletConfig().getInitParameter("processor");
  +        if (value != null) {
  +            processorClass = value;
  +        }
  +        value = getServletConfig().getInitParameter("validating");
  +        if (value != null) {
  +            if (value.equalsIgnoreCase("true") ||
  +                value.equalsIgnoreCase("yes"))
  +                validating = true;
  +            else
  +                validating = false;
  +        }
   
       }
   
   
       /**
  -     * General purpose preprocessing hook that can be overridden to support
  -     * application specific preprocessing activity.  This hook can examine
  -     * and/or modify the properties of the request and response objects, and
  -     * optionally complete the response if it wishes.
  -     * <p>
  -     * The default implementation does nothing.
  -     *
  -     * @param request The servlet request we are processing
  -     * @param response The servlet response we are generating
  +     * Initialize the RequestProcessor instance we will be using.
        *
  -     * @return <code>true</code> if the remainder of the standard processing
  -     *  should be performed, or <code>false</code> if the response has already
  -     *  been created so the calling method should immediately exit
  -     *
  -     * @exception IOException if an input/output error occurs
  -     * @exception ServletException if a servlet exception occurs
  +     * @exception ServletException if we cannot initialize a request processor
        */
  -    protected boolean processPreprocess(HttpServletRequest request,
  -                                        HttpServletResponse response)
  -        throws IOException, ServletException {
  +    protected void initProcessor() throws ServletException {
   
  -        return (true);  // Default implementation does nothing
  +        try {
  +            Class clazz = Class.forName(processorClass);
  +            processor = (RequestProcessor) clazz.newInstance();
  +            processor.init(this);
  +        } catch (Throwable t) {
  +            log(internal.getMessage("initProcessor"), t);
  +            throw new UnavailableException
  +                (internal.getMessage("initProcessor"));
  +        }
   
       }
   
   
       /**
  -     * Populate the properties of the specified ActionForm from the request
  -     * parameters included with this request.
  -     *
  -     * @param formInstance The ActionForm we are processing
  -     * @param mapping The ActionMapping we are processing
  -     * @param request The servlet request we are processing
  -     *
  -     * @exception ServletException if thrown by RequestUtils.populate()
  +     * Initialize the servlet mapping under which our controller servlet
  +     * is being accessed.  This will be used in the <code>&html:form&gt;</code>
  +     * tag to generate correct destination URLs for form submissions.
        */
  -    protected void processPopulate(ActionForm formInstance,
  -                                   ActionMapping mapping,
  -                                   HttpServletRequest request)
  -        throws ServletException {
  -
  -        if (formInstance == null)
  -            return;
  -        //set the servlet of the ActionForm
  -        formInstance.setServlet(this);
  -
  -        // Populate the bean properties of this ActionForm instance
  -        if (debug >= 1)
  -            log(" Populating bean properties from this request");
  -        formInstance.reset(mapping, request);
  -        //place the mapping's multipart request handler class
  -        //into the request to be read by the RequestUtils.populate
  -        //method in the event of a multipart request
  -        if (mapping.getMultipartClass() != null)
  -            request.setAttribute(Action.MULTIPART_KEY,
  -                                 mapping.getMultipartClass());
  -        RequestUtils.populate(formInstance, mapping.getPrefix(),
  -                              mapping.getSuffix(), request);
  -
  -    }
  -
  +    protected void initServlet() throws ServletException {
   
  -    /**
  -     * Call the <code>validate()</code> method of the specified ActionForm,
  -     * and forward back to the input form if there are any errors.  Return
  -     * <code>true</code> if we should continue processing (and call the
  -     * <code>Action</code> class <code>perform()</code> method), or return
  -     * <code>false</code> if we have already forwarded control back to the
  -     * input form.
  -     *
  -     * @param mapping The ActionMapping we are processing
  -     * @param formInstance The ActionForm we are processing
  -     * @param request The servlet request we are processing
  -     * @param response The servlet response we are processing
  -     *
  -     * @exception IOException if an input/output error occurs
  -     * @exception ServletException if a servlet exception occurs
  -     */
  -    protected boolean processValidate(ActionMapping mapping,
  -        ActionForm formInstance, HttpServletRequest request,
  -        HttpServletResponse response)
  -        throws IOException, ServletException {
  +        // Remember our servlet name
  +        this.servletName = getServletConfig().getServletName();
   
  -        if (formInstance == null)
  -            return (true);
  -        if (debug >= 1)
  -            log(" Validating input form properties");
  +        // Prepare a Digester to scan the web application deployment descriptor
  +        Digester digester = new Digester();
  +        digester.push(this);
  +        digester.setDebug(this.debug);
  +        digester.setNamespaceAware(true);
  +        digester.setValidating(false);
   
  -        // Was this submit cancelled?
  -        if ((request.getParameter(Constants.CANCEL_PROPERTY) != null) ||
  -            (request.getParameter(Constants.CANCEL_PROPERTY_X) != null)) {
  -            if (debug >= 1)
  -                log("  Cancelled transaction, no validation");
  -            return (true);
  -        }
  -
  -        // Has validation been turned off on this mapping?
  -        if (!mapping.getValidate())
  -            return (true);
  -
  -        // Call the validate() method of our ActionForm bean
  -        ActionErrors errors = formInstance.validate(mapping, request);
  -        if ((errors == null) || errors.empty()) {
  -            if (debug >= 1)
  -                log("  No errors detected, accepting input");
  -            return (true);
  -        }
  -
  -        //does our form have a multipart request?
  -        if (formInstance.getMultipartRequestHandler() != null) {
  -            //rollback the request
  -            if (debug > 1) {
  -                log("  Rolling back the multipart request");
  -            }
  -            formInstance.getMultipartRequestHandler().rollback();
  +        // Register our local copy of the DTDs that we can find
  +        for (int i = 0; i < registrations.length; i += 2) {
  +            URL url = this.getClass().getResource(registrations[i+1]);
  +            if (url != null)
  +                digester.register(registrations[i], url.toString());
           }
   
  -        // Has an input form been specified for this mapping?
  -        String uri = mapping.getInput();
  -        if (uri == null) {
  -            if (debug >= 1)
  -                log("  No input form, but validation returned errors");
  -            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
  -                               internal.getMessage("noInput",
  -                                                   mapping.getPath()));
  -            return (false);
  -        }
  +        // Configure the processing rules that we need
  +        digester.addCallMethod("web-app/servlet-mapping",
  +                               "addServletMapping", 2);
  +        digester.addCallParam("web-app/servlet-mapping/servlet-name", 0);
  +        digester.addCallParam("web-app/servlet-mapping/url-pattern", 1);
   
  -        // Save our error messages and return to the input form if possible
  +        // Process the web application deployment descriptor
           if (debug >= 1)
  -            log("  Validation error(s), redirecting to: " + uri);
  -        request.setAttribute(Action.ERROR_KEY, errors);
  -        //unwrap the multipart request if there is one
  -        if (request instanceof MultipartRequestWrapper) {
  -            request = ((MultipartRequestWrapper) request).getRequest();
  -        }
  -        RequestDispatcher rd = getServletContext().getRequestDispatcher(uri);
  -        if (rd == null) {
  -            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
  -                               internal.getMessage("requestDispatcher",
  -                                                   uri));
  -            return (false);
  +            log("Scanning web.xml for controller servlet mapping");
  +        InputStream input= null;
  +        try {
  +            input =
  +                getServletContext().getResourceAsStream("/WEB-INF/web.xml");
  +            digester.parse(input);
  +        } catch (Throwable e) {
  +            log(internal.getMessage("configWebXml"), e);
  +        } finally {
  +            if (input != null)
  +                input = null;
           }
  -        rd.forward(request, response);
  -        return (false);
  -
  -    }
  -
  -
  -}
  -
  -
  -// ------------------------------------------------------------ Private Classes
  -
  -
  -/**
  - * Private digester <code>Rule</code> that adds a data source to the underlying
  - * <code>ActionServlet</code> instance.  The servlet context attributes key
  - * is specified by the "key" attribute on the data source element, and defaults
  - * to the value of <code>Action.DATA_SOURCE_KEY</code> if not specified.
  - */
  -
  -final class AddDataSourceRule extends Rule {
  -
   
  -    public AddDataSourceRule(Digester digester) {
  -
  -        super(digester);
  +        // Record a servlet context attribute (if appropriate)
  +        if (debug >= 1)
  +            log("Mapping for servlet '" + servletName + "' = '" +
  +                servletMapping + "'");
  +        if (servletMapping != null)
  +            getServletContext().setAttribute(Action.SERVLET_KEY,
  +                                             servletMapping);
   
       }
   
  -
  -    public void begin(Attributes attributes) throws Exception {
  -
  -        // Acquire the key under which this data source will be stored
  -        String key = null;
  -        for (int i = 0; i < attributes.getLength(); i++) {
  -            if ("key".equals(attributes.getQName(i))) {
  -                key = attributes.getValue(i);
  -                break;
  -            }
  -        }
  -        if (key == null)
  -            key = Action.DATA_SOURCE_KEY;
  -
  -        // Pass the data source at the top of the stack to the action servlet
  -        // at the next-to-top position
  -        DataSource child = (DataSource) digester.peek(0);
  -        ActionServlet parent = (ActionServlet) digester.peek(1);
  -        if (digester.getDebug() >= 1)
  -            digester.log("Call " + parent.getClass().getName() +
  -                         ".addDataSource(" + key + ", " + child + ")");
  -        parent.addDataSource(key, child);
  -
  -    }
   
   }
  
  
  
  1.3       +4 -14     jakarta-struts/src/share/org/apache/struts/action/ActionServletWrapper.java
  
  Index: ActionServletWrapper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServletWrapper.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ActionServletWrapper.java	21 Nov 2001 13:59:28 -0000	1.2
  +++ ActionServletWrapper.java	13 Jan 2002 00:25:35 -0000	1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServletWrapper.java,v 1.2 2001/11/21 13:59:28 husted Exp $
  - * $Revision: 1.2 $
  - * $Date: 2001/11/21 13:59:28 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServletWrapper.java,v 1.3 2002/01/13 00:25:35 craigmcc Exp $
  + * $Revision: 1.3 $
  + * $Date: 2002/01/13 00:25:35 $
    *
    * ====================================================================
    *
  @@ -74,7 +74,7 @@
    * could be exploited by automatic population of properties.
    * @author Craig R. McClanahan
    * @author Ted Husted
  - * @version $Revision: 1.2 $ $Date: 2001/11/21 13:59:28 $
  + * @version $Revision: 1.3 $ $Date: 2002/01/13 00:25:35 $
    */
   public class ActionServletWrapper {
   
  @@ -106,16 +106,6 @@
               servlet.log(message);
   
       }
  -
  -    /**
  -     * Get the class name of the MultipartRequestHandler implementation
  -     *
  -     * @return A qualified classname of the MultipartRequestHandler implementation
  -     */
  -     public String getMultipartClass() {
  -        return servlet.multipartClass;
  -    }
  -
   
       /**
        * Set servlet to a MultipartRequestHandler.
  
  
  
  1.2       +8 -8      jakarta-struts/src/share/org/apache/struts/action/ExceptionHandler.java
  
  Index: ExceptionHandler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/ExceptionHandler.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ExceptionHandler.java	31 Dec 2001 01:14:36 -0000	1.1
  +++ ExceptionHandler.java	13 Jan 2002 00:25:35 -0000	1.2
  @@ -63,10 +63,10 @@
   import org.apache.struts.action.Action;
   import org.apache.struts.action.ActionError;
   import org.apache.struts.action.ActionErrors;
  -import org.apache.struts.action.ActionException;
   import org.apache.struts.action.ActionForm;
   import org.apache.struts.action.ActionForward;
   import org.apache.struts.action.ActionMapping;
  +import org.apache.struts.config.ExceptionConfig;
   import org.apache.struts.util.AppException;
   
   
  @@ -86,11 +86,11 @@
        * @exception ServletException if a servlet exception occurs
        */
       protected ActionForward execute(Exception ex,
  -                                ActionException ae,
  -                                ActionMapping mapping,
  -                                ActionForm formInstance,
  -                                HttpServletRequest request,
  -                                HttpServletResponse response)
  +                                    ExceptionConfig ae,
  +                                    ActionMapping mapping,
  +                                    ActionForm formInstance,
  +                                    HttpServletRequest request,
  +                                    HttpServletResponse response)
           throws ServletException {
   
   	ActionForward forward = null;
  @@ -112,10 +112,10 @@
   
           // Figure out the error
           if (ex instanceof AppException) {
  -            error = ((AppException) ex).getError();
  +            error = new ActionError(ae.getKey());
               property = ((AppException) ex).getProperty();
           } else {
  -            error = ae.getError();
  +            error = new ActionError(ae.getKey());
               property = error.getKey();
           }
   
  
  
  
  1.2       +3 -2      jakarta-struts/src/share/org/apache/struts/actions/LookupDispatchAction.java
  
  Index: LookupDispatchAction.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/actions/LookupDispatchAction.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- LookupDispatchAction.java	28 Nov 2001 17:22:58 -0000	1.1
  +++ LookupDispatchAction.java	13 Jan 2002 00:25:36 -0000	1.2
  @@ -206,7 +206,8 @@
           if (lookupMap == null) {
               // Build the key lookup map
               lookupMap = new HashMap();
  -            MessageResources resources = servlet.getResources();
  +            MessageResources resources = (MessageResources)
  +                request.getAttribute(Action.MESSAGES_KEY);
   
               keyMethodMap = getKeyMethodMap();
   
  @@ -236,4 +237,4 @@
        */
       protected abstract Map getKeyMethodMap();
   
  -}
  \ No newline at end of file
  +}
  
  
  
  1.4       +27 -22    jakarta-struts/src/share/org/apache/struts/config/ActionConfig.java
  
  Index: ActionConfig.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/ActionConfig.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ActionConfig.java	31 Dec 2001 01:58:26 -0000	1.3
  +++ ActionConfig.java	13 Jan 2002 00:25:36 -0000	1.4
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/ActionConfig.java,v 1.3 2001/12/31 01:58:26 craigmcc Exp $
  - * $Revision: 1.3 $
  - * $Date: 2001/12/31 01:58:26 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/ActionConfig.java,v 1.4 2002/01/13 00:25:36 craigmcc Exp $
  + * $Revision: 1.4 $
  + * $Date: 2002/01/13 00:25:36 $
    *
    * ====================================================================
    *
  @@ -63,6 +63,7 @@
   package org.apache.struts.config;
   
   
  +import java.io.Serializable;
   import java.util.ArrayList;
   import javax.servlet.http.HttpServletRequest;
   import org.apache.commons.collections.FastHashMap;
  @@ -74,11 +75,11 @@
    * configuration file.</p>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.3 $ $Date: 2001/12/31 01:58:26 $
  + * @version $Revision: 1.4 $ $Date: 2002/01/13 00:25:36 $
    * @since Struts 1.1
    */
   
  -public class ActionConfig {
  +public class ActionConfig implements Serializable {
   
   
       // ----------------------------------------------------- Instance Variables
  @@ -123,7 +124,11 @@
       protected String attribute = null;
   
       public String getAttribute() {
  -        return (this.attribute);
  +        if (this.attribute == null) {
  +            return (this.name);
  +        } else {
  +            return (this.attribute);
  +        }
       }
   
       public void setAttribute(String attribute) {
  @@ -214,22 +219,6 @@
   
   
       /**
  -     * Context-relative path of the submitted request, starting with a
  -     * slash ("/") character, and omitting any filename extension if
  -     * extension mapping is being used.
  -     */
  -    protected String path = null;
  -
  -    public String getPath() {
  -        return (this.path);
  -    }
  -
  -    public void setPath(String path) {
  -        this.path = path;
  -    }
  -
  -
  -    /**
        * General purpose configuration parameter that can be used to pass
        * extra iunformation to the Action instance selected by this Action.
        * Struts does not itself use this value in any way.
  @@ -242,6 +231,22 @@
   
       public void setParameter(String parameter) {
           this.parameter = parameter;
  +    }
  +
  +
  +    /**
  +     * Context-relative path of the submitted request, starting with a
  +     * slash ("/") character, and omitting any filename extension if
  +     * extension mapping is being used.
  +     */
  +    protected String path = null;
  +
  +    public String getPath() {
  +        return (this.path);
  +    }
  +
  +    public void setPath(String path) {
  +        this.path = path;
       }
   
   
  
  
  
  1.5       +6 -5      jakarta-struts/src/share/org/apache/struts/config/ApplicationConfig.java
  
  Index: ApplicationConfig.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/ApplicationConfig.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ApplicationConfig.java	31 Dec 2001 01:58:26 -0000	1.4
  +++ ApplicationConfig.java	13 Jan 2002 00:25:36 -0000	1.5
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/ApplicationConfig.java,v 1.4 2001/12/31 01:58:26 craigmcc Exp $
  - * $Revision: 1.4 $
  - * $Date: 2001/12/31 01:58:26 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/ApplicationConfig.java,v 1.5 2002/01/13 00:25:36 craigmcc Exp $
  + * $Revision: 1.5 $
  + * $Date: 2002/01/13 00:25:36 $
    *
    * ====================================================================
    *
  @@ -63,6 +63,7 @@
   package org.apache.struts.config;
   
   
  +import java.io.Serializable;
   import org.apache.commons.collections.FastHashMap;
   import org.apache.struts.action.ActionServlet;
    
  @@ -78,11 +79,11 @@
    * previous Struts behavior that only supported one application.</p>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.4 $ $Date: 2001/12/31 01:58:26 $
  + * @version $Revision: 1.5 $ $Date: 2002/01/13 00:25:36 $
    * @since Struts 1.1
    */
   
  -public class ApplicationConfig {
  +public class ApplicationConfig implements Serializable {
   
   
       // ----------------------------------------------------------- Constructors
  
  
  
  1.3       +12 -8     jakarta-struts/src/share/org/apache/struts/config/ConfigRuleSet.java
  
  Index: ConfigRuleSet.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/ConfigRuleSet.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ConfigRuleSet.java	31 Dec 2001 01:42:13 -0000	1.2
  +++ ConfigRuleSet.java	13 Jan 2002 00:25:36 -0000	1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/ConfigRuleSet.java,v 1.2 2001/12/31 01:42:13 craigmcc Exp $
  - * $Revision: 1.2 $
  - * $Date: 2001/12/31 01:42:13 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/ConfigRuleSet.java,v 1.3 2002/01/13 00:25:36 craigmcc Exp $
  + * $Revision: 1.3 $
  + * $Date: 2002/01/13 00:25:36 $
    *
    * ====================================================================
    *
  @@ -72,7 +72,7 @@
    * configuration file (<code>struts-config.xml</code>).</p>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.2 $ $Date: 2001/12/31 01:42:13 $
  + * @version $Revision: 1.3 $ $Date: 2002/01/13 00:25:36 $
    * @since Struts 1.1
    */
   
  @@ -112,7 +112,8 @@
   
           digester.addObjectCreate
               ("struts-config/action-mappings/action",
  -             "org.apache.struts.config.ActionConfig",
  +             //             "org.apache.struts.config.ActionConfig",
  +             "org.apache.struts.action.ActionMapping",
                "className");
           digester.addSetProperties
               ("struts-config/action-mappings/action");
  @@ -142,7 +143,8 @@
   
           digester.addObjectCreate
               ("struts-config/action-mappings/action/forward",
  -             "org.apache.struts.config.ForwardConfig",
  +             //             "org.apache.struts.config.ForwardConfig",
  +             "org.apache.struts.action.ActionForward",
                "className");
           digester.addSetProperties
               ("struts-config/action-mappings/action/forward");
  @@ -172,7 +174,8 @@
   
           digester.addObjectCreate
               ("struts-config/form-beans/form-bean",
  -             "org.apache.struts.config.FormBeanConfig",
  +             //             "org.apache.struts.config.FormBeanConfig",
  +             "org.apache.struts.action.ActionFormBean",
                "className");
           digester.addSetProperties
               ("struts-config/form-beans/form-bean");
  @@ -202,7 +205,8 @@
   
           digester.addObjectCreate
               ("struts-config/global-forwards/forward",
  -             "org.apache.struts.config.ForwardConfig",
  +             //             "org.apache.struts.config.ForwardConfig",
  +             "org.apache.struts.action.ActionForward",
                "className");
           digester.addSetProperties
               ("struts-config/global-forwards/forward");
  
  
  
  1.2       +37 -4     jakarta-struts/src/share/org/apache/struts/config/ControllerConfig.java
  
  Index: ControllerConfig.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/ControllerConfig.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ControllerConfig.java	26 Dec 2001 23:14:50 -0000	1.1
  +++ ControllerConfig.java	13 Jan 2002 00:25:36 -0000	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/ControllerConfig.java,v 1.1 2001/12/26 23:14:50 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2001/12/26 23:14:50 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/ControllerConfig.java,v 1.2 2002/01/13 00:25:36 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2002/01/13 00:25:36 $
    *
    * ====================================================================
    *
  @@ -63,17 +63,20 @@
   package org.apache.struts.config;
   
   
  +import java.io.Serializable;
  +
  +
   /**
    * <p>A JavaBean representing the configuration information of a
    * <code>&lt;controller&gt;</code> element in a Struts application
    * configuration file.</p>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2001/12/26 23:14:50 $
  + * @version $Revision: 1.2 $ $Date: 2002/01/13 00:25:36 $
    * @since Struts 1.1
    */
   
  -public class ControllerConfig {
  +public class ControllerConfig implements Serializable {
   
   
       // ------------------------------------------------------------- Properties
  @@ -108,6 +111,20 @@
   
   
       /**
  +     * The debugging detail level that determines logging verbosity.
  +     */
  +    protected int debug = 0;
  +
  +    public int getDebug() {
  +        return (this.debug);
  +    }
  +
  +    public void setDebug(int debug) {
  +        this.debug = debug;
  +    }
  +
  +
  +    /**
        * Should we store a Locale object in the user's session if needed?
        */
       protected boolean locale = false;
  @@ -132,6 +149,22 @@
   
       public void setMaxFileSize(String maxFileSize) {
           this.maxFileSize = maxFileSize;
  +    }
  +
  +
  +    /**
  +     * The fully qualified Java class name of the MultipartRequestHandler
  +     * class to be used.
  +     */
  +    protected String multipartClass =
  +        "org.apache.struts.upload.DiskMultipartRequestHandler";
  +
  +    public String getMultipartClass() {
  +        return (this.multipartClass);
  +    }
  +
  +    public void setMultipartClass(String multipartClass) {
  +        this.multipartClass = multipartClass;
       }
   
   
  
  
  
  1.2       +6 -5      jakarta-struts/src/share/org/apache/struts/config/DataSourceConfig.java
  
  Index: DataSourceConfig.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/DataSourceConfig.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DataSourceConfig.java	26 Dec 2001 19:16:25 -0000	1.1
  +++ DataSourceConfig.java	13 Jan 2002 00:25:36 -0000	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/DataSourceConfig.java,v 1.1 2001/12/26 19:16:25 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2001/12/26 19:16:25 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/DataSourceConfig.java,v 1.2 2002/01/13 00:25:36 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2002/01/13 00:25:36 $
    *
    * ====================================================================
    *
  @@ -63,6 +63,7 @@
   package org.apache.struts.config;
   
   
  +import java.io.Serializable;
   import org.apache.struts.action.Action;
   
   
  @@ -76,11 +77,11 @@
    * of them may be ignored by custom data source implementations.</p>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2001/12/26 19:16:25 $
  + * @version $Revision: 1.2 $ $Date: 2002/01/13 00:25:36 $
    * @since Struts 1.1
    */
   
  -public class DataSourceConfig {
  +public class DataSourceConfig implements Serializable {
   
   
   
  
  
  
  1.2       +7 -19     jakarta-struts/src/share/org/apache/struts/config/ExceptionConfig.java
  
  Index: ExceptionConfig.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/ExceptionConfig.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ExceptionConfig.java	31 Dec 2001 01:42:13 -0000	1.1
  +++ ExceptionConfig.java	13 Jan 2002 00:25:36 -0000	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/ExceptionConfig.java,v 1.1 2001/12/31 01:42:13 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2001/12/31 01:42:13 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/ExceptionConfig.java,v 1.2 2002/01/13 00:25:36 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2002/01/13 00:25:36 $
    *
    * ====================================================================
    *
  @@ -63,17 +63,20 @@
   package org.apache.struts.config;
   
   
  +import java.io.Serializable;
  +
  +
   /**
    * <p>A JavaBean representing the configuration information of an
    * <code>&lt;exception&gt;</code> element from a Struts application
    * configuration file.</p>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2001/12/31 01:42:13 $
  + * @version $Revision: 1.2 $ $Date: 2002/01/13 00:25:36 $
    * @since Struts 1.1
    */
   
  -public class ExceptionConfig {
  +public class ExceptionConfig implements Serializable {
   
   
       // ------------------------------------------------------------- Properties
  @@ -91,21 +94,6 @@
   
       public void setHandler(String handler) {
           this.handler = handler;
  -    }
  -
  -
  -    /**
  -     * Should we use the inheritance hierarchy of this exception class to
  -     * find an appropriate handler?
  -     */
  -    protected boolean hierarchical = true;
  -
  -    public boolean getHierarchical() {
  -        return (this.hierarchical);
  -    }
  -
  -    public void setHierarchical(boolean hierarchical) {
  -        this.hierarchical = hierarchical;
       }
   
   
  
  
  
  1.2       +27 -7     jakarta-struts/src/share/org/apache/struts/config/ForwardConfig.java
  
  Index: ForwardConfig.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/ForwardConfig.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ForwardConfig.java	26 Dec 2001 19:16:25 -0000	1.1
  +++ ForwardConfig.java	13 Jan 2002 00:25:36 -0000	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/ForwardConfig.java,v 1.1 2001/12/26 19:16:25 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2001/12/26 19:16:25 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/ForwardConfig.java,v 1.2 2002/01/13 00:25:36 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2002/01/13 00:25:36 $
    *
    * ====================================================================
    *
  @@ -63,23 +63,42 @@
   package org.apache.struts.config;
   
   
  +import java.io.Serializable;
  +
  +
   /**
    * <p>A JavaBean representing the configuration information of a
    * <code>&lt;forward&gt;</code> element from a Struts application
    * configuration file.</p>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2001/12/26 19:16:25 $
  + * @version $Revision: 1.2 $ $Date: 2002/01/13 00:25:36 $
    * @since Struts 1.1
    */
   
  -public class ForwardConfig {
  +public class ForwardConfig implements Serializable {
   
   
       // ------------------------------------------------------------- Properties
   
   
       /**
  +     * Should the value of the <code>path</code> property be considered
  +     * context-relative if it starts with a slash (and therefore not
  +     * prefixed with the application prefix?
  +     */
  +    protected boolean contextRelative = false;
  +
  +    public boolean getContextRelative() {
  +        return (this.contextRelative);
  +    }
  +
  +    public void setContextRelative(boolean contextRelative) {
  +        this.contextRelative = contextRelative;
  +    }
  +
  +
  +    /**
        * The unique identifier of this forward, which is used to reference it
        * in <code>Action</code> classes.
        */
  @@ -95,8 +114,9 @@
   
   
       /**
  -     * The context-relative path (starting with a "/") of the resource that
  -     * is mapped by this forward.
  +     * The application-relative (if contextRelative is <code>false</code>) or
  +     * context-relative (if contextRelative is <code>true</code>) path,
  +     * starting with a "/", of the resource that is mapped by this forward.
        */
       protected String path = null;
   
  
  
  
  1.2       +7 -4      jakarta-struts/src/share/org/apache/struts/config/MessageResourcesConfig.java
  
  Index: MessageResourcesConfig.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/MessageResourcesConfig.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- MessageResourcesConfig.java	26 Dec 2001 23:14:50 -0000	1.1
  +++ MessageResourcesConfig.java	13 Jan 2002 00:25:36 -0000	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/MessageResourcesConfig.java,v 1.1 2001/12/26 23:14:50 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2001/12/26 23:14:50 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/config/MessageResourcesConfig.java,v 1.2 2002/01/13 00:25:36 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2002/01/13 00:25:36 $
    *
    * ====================================================================
    *
  @@ -63,17 +63,20 @@
   package org.apache.struts.config;
   
   
  +import java.io.Serializable;
  +
  +
   /**
    * <p>A JavaBean representing the configuration information of a
    * <code>&lt;message-resources&gt;</code> element in a Struts application
    * configuration file.</p>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2001/12/26 23:14:50 $
  + * @version $Revision: 1.2 $ $Date: 2002/01/13 00:25:36 $
    * @since Struts 1.1
    */
   
  -public class MessageResourcesConfig {
  +public class MessageResourcesConfig implements Serializable {
   
   
       // ------------------------------------------------------------- Properties
  
  
  
  1.17      +4 -4      jakarta-struts/src/share/org/apache/struts/taglib/bean/IncludeTag.java
  
  Index: IncludeTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/bean/IncludeTag.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- IncludeTag.java	13 Jun 2001 21:32:54 -0000	1.16
  +++ IncludeTag.java	13 Jan 2002 00:25:36 -0000	1.17
  @@ -1,5 +1,5 @@
   /*
  - * $Id: IncludeTag.java,v 1.16 2001/06/13 21:32:54 craigmcc Exp $
  + * $Id: IncludeTag.java,v 1.17 2002/01/13 00:25:36 craigmcc Exp $
    * ====================================================================
    *
    * The Apache Software License, Version 1.1
  @@ -77,7 +77,6 @@
   import javax.servlet.jsp.tagext.TagSupport;
   import org.apache.struts.action.Action;
   import org.apache.struts.action.ActionForward;
  -import org.apache.struts.action.ActionForwards;
   import org.apache.struts.util.MessageResources;
   import org.apache.struts.util.RequestUtils;
   
  @@ -93,7 +92,7 @@
    * wrapped response passed to RequestDispatcher.include().
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.16 $ $Date: 2001/06/13 21:32:54 $
  + * @version $Revision: 1.17 $ $Date: 2002/01/13 00:25:36 $
    */
   
   public class IncludeTag extends TagSupport {
  @@ -237,8 +236,9 @@
                   HttpServletRequest request = (HttpServletRequest)
                       pageContext.getRequest();
                   url = new URL(RequestUtils.requestURL(request), urlString);
  -            } else
  +            } else {
                   url = new URL(urlString);
  +            }
           } catch (MalformedURLException e) {
               RequestUtils.saveException(pageContext, e);
               throw new JspException
  
  
  
  1.6       +5 -5      jakarta-struts/src/share/org/apache/struts/taglib/bean/MessageTag.java
  
  Index: MessageTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/bean/MessageTag.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- MessageTag.java	26 Jun 2001 05:18:25 -0000	1.5
  +++ MessageTag.java	13 Jan 2002 00:25:36 -0000	1.6
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/bean/MessageTag.java,v 1.5 2001/06/26 05:18:25 martinc Exp $
  - * $Revision: 1.5 $
  - * $Date: 2001/06/26 05:18:25 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/bean/MessageTag.java,v 1.6 2002/01/13 00:25:36 craigmcc Exp $
  + * $Revision: 1.6 $
  + * $Date: 2002/01/13 00:25:36 $
    *
    * ====================================================================
    *
  @@ -82,7 +82,7 @@
    * <code>ActionServlet</code> implementation.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.5 $ $Date: 2001/06/26 05:18:25 $
  + * @version $Revision: 1.6 $ $Date: 2002/01/13 00:25:36 $
    */
   
   public class MessageTag extends TagSupport {
  @@ -164,7 +164,7 @@
       /**
        * The servlet context attribute key for our resources.
        */
  -    protected String bundle = Action.MESSAGES_KEY;
  +    protected String bundle = null;
   
       public String getBundle() {
   	return (this.bundle);
  
  
  
  1.9       +6 -5      jakarta-struts/src/share/org/apache/struts/taglib/bean/ResourceTag.java
  
  Index: ResourceTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/bean/ResourceTag.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ResourceTag.java	16 Jul 2001 00:44:53 -0000	1.8
  +++ ResourceTag.java	13 Jan 2002 00:25:36 -0000	1.9
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/bean/ResourceTag.java,v 1.8 2001/07/16 00:44:53 craigmcc Exp $
  - * $Revision: 1.8 $
  - * $Date: 2001/07/16 00:44:53 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/bean/ResourceTag.java,v 1.9 2002/01/13 00:25:36 craigmcc Exp $
  + * $Revision: 1.9 $
  + * $Date: 2002/01/13 00:25:36 $
    *
    * ====================================================================
    *
  @@ -81,7 +81,7 @@
    * web application resource.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.8 $ $Date: 2001/07/16 00:44:53 $
  + * @version $Revision: 1.9 $ $Date: 2002/01/13 00:25:36 $
    */
   
   public class ResourceTag extends TagSupport {
  @@ -134,7 +134,8 @@
   
   
       /**
  -     * The name of the resource whose contents are to be exposed.
  +     * The application-relative URI of the resource whose contents are to
  +     * be exposed.
        */
       protected String name = null;
   
  
  
  
  1.8       +17 -22    jakarta-struts/src/share/org/apache/struts/taglib/bean/StrutsTag.java
  
  Index: StrutsTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/bean/StrutsTag.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- StrutsTag.java	23 Apr 2001 22:52:21 -0000	1.7
  +++ StrutsTag.java	13 Jan 2002 00:25:36 -0000	1.8
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/bean/StrutsTag.java,v 1.7 2001/04/23 22:52:21 craigmcc Exp $
  - * $Revision: 1.7 $
  - * $Date: 2001/04/23 22:52:21 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/bean/StrutsTag.java,v 1.8 2002/01/13 00:25:36 craigmcc Exp $
  + * $Revision: 1.8 $
  + * $Date: 2002/01/13 00:25:36 $
    *
    * ====================================================================
    *
  @@ -68,9 +68,7 @@
   import javax.servlet.jsp.PageContext;
   import javax.servlet.jsp.tagext.TagSupport;
   import org.apache.struts.action.Action;
  -import org.apache.struts.action.ActionFormBeans;
  -import org.apache.struts.action.ActionForwards;
  -import org.apache.struts.action.ActionMappings;
  +import org.apache.struts.config.ApplicationConfig;
   import org.apache.struts.util.MessageResources;
   import org.apache.struts.util.RequestUtils;
   
  @@ -80,7 +78,7 @@
    * internal configuraton object.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.7 $ $Date: 2001/04/23 22:52:21 $
  + * @version $Revision: 1.8 $ $Date: 2002/01/13 00:25:36 $
    */
   
   public class StrutsTag extends TagSupport {
  @@ -180,30 +178,27 @@
               throw e;
           }
   
  +        // Retrieve our application configuration information
  +        ApplicationConfig config = (ApplicationConfig)
  +            pageContext.getRequest().getAttribute(Action.APPLICATION_KEY);
  +        if (config == null) { // Backwards compatibility hack
  +            config = (ApplicationConfig)
  +                pageContext.getServletContext().getAttribute
  +                (Action.APPLICATION_KEY);
  +        }
  +
           // Retrieve the requested object to be exposed
           Object object = null;
           String selector = null;
           if (formBean != null) {
               selector = formBean;
  -            ActionFormBeans collection = (ActionFormBeans)
  -                pageContext.getAttribute(Action.FORM_BEANS_KEY,
  -                                         PageContext.APPLICATION_SCOPE);
  -            if (collection != null)
  -                object = collection.findFormBean(formBean);
  +            object = config.findFormBeanConfig(formBean);
           } else if (forward != null) {
               selector = forward;
  -            ActionForwards collection = (ActionForwards)
  -                pageContext.getAttribute(Action.FORWARDS_KEY,
  -                                         PageContext.APPLICATION_SCOPE);
  -            if (collection != null)
  -                object = collection.findForward(forward);
  +            object = config.findForwardConfig(forward);
           } else if (mapping != null) {
               selector = mapping;
  -            ActionMappings collection = (ActionMappings)
  -                pageContext.getAttribute(Action.MAPPINGS_KEY,
  -                                         PageContext.APPLICATION_SCOPE);
  -            if (collection != null)
  -                object = collection.findMapping(mapping);
  +            object = config.findActionConfig(mapping);
           }
           if (object == null) {
               JspException e = new JspException
  
  
  
  1.13      +6 -5      jakarta-struts/src/share/org/apache/struts/taglib/html/ErrorsTag.java
  
  Index: ErrorsTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/ErrorsTag.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- ErrorsTag.java	16 Oct 2001 15:43:58 -0000	1.12
  +++ ErrorsTag.java	13 Jan 2002 00:25:37 -0000	1.13
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/ErrorsTag.java,v 1.12 2001/10/16 15:43:58 dwinterfeldt Exp $
  - * $Revision: 1.12 $
  - * $Date: 2001/10/16 15:43:58 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/ErrorsTag.java,v 1.13 2002/01/13 00:25:37 craigmcc Exp $
  + * $Revision: 1.13 $
  + * $Date: 2002/01/13 00:25:37 $
    *
    * ====================================================================
    *
  @@ -74,6 +74,7 @@
   import org.apache.struts.action.Action;
   import org.apache.struts.action.ActionError;
   import org.apache.struts.action.ActionErrors;
  +import org.apache.struts.config.ApplicationConfig;
   import org.apache.struts.util.ErrorMessages;
   import org.apache.struts.util.MessageResources;
   import org.apache.struts.util.RequestUtils;
  @@ -98,7 +99,7 @@
    * </ul>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.12 $ $Date: 2001/10/16 15:43:58 $
  + * @version $Revision: 1.13 $ $Date: 2002/01/13 00:25:37 $
    */
   
   public class ErrorsTag extends TagSupport {
  @@ -110,7 +111,7 @@
       /**
        * The servlet context attribute key for our resources.
        */
  -    protected String bundle = Action.MESSAGES_KEY;
  +    protected String bundle = null;
   
       public String getBundle() {
           return (this.bundle);
  
  
  
  1.16      +39 -26    jakarta-struts/src/share/org/apache/struts/taglib/html/FormTag.java
  
  Index: FormTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/FormTag.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- FormTag.java	5 Nov 2001 04:51:40 -0000	1.15
  +++ FormTag.java	13 Jan 2002 00:25:37 -0000	1.16
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/FormTag.java,v 1.15 2001/11/05 04:51:40 martinc Exp $
  - * $Revision: 1.15 $
  - * $Date: 2001/11/05 04:51:40 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/FormTag.java,v 1.16 2002/01/13 00:25:37 craigmcc Exp $
  + * $Revision: 1.16 $
  + * $Date: 2002/01/13 00:25:37 $
    *
    * ====================================================================
    *
  @@ -75,10 +75,9 @@
   import org.apache.struts.action.Action;
   import org.apache.struts.action.ActionForm;
   import org.apache.struts.action.ActionFormBean;
  -import org.apache.struts.action.ActionFormBeans;
   import org.apache.struts.action.ActionMapping;
  -import org.apache.struts.action.ActionMappings;
   import org.apache.struts.action.ActionServlet;
  +import org.apache.struts.config.ApplicationConfig;
   import org.apache.struts.util.MessageResources;
   import org.apache.struts.util.ResponseUtils;
   
  @@ -88,7 +87,7 @@
    * properties correspond to the various fields of the form.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.15 $ $Date: 2001/11/05 04:51:40 $
  + * @version $Revision: 1.16 $ $Date: 2002/01/13 00:25:37 $
    */
   
   public class FormTag extends TagSupport {
  @@ -564,12 +563,17 @@
   		bean = clazz.newInstance();
                   if (bean instanceof ActionForm) {
                       ActionForm form = (ActionForm)bean;
  -                    ActionMappings mappings = (ActionMappings)
  -                        pageContext.getAttribute(Action.MAPPINGS_KEY,
  -                                                 PageContext.APPLICATION_SCOPE);
  -
  +                    ApplicationConfig config = (ApplicationConfig)
  +                        pageContext.getRequest().getAttribute
  +                          (Action.APPLICATION_KEY);
  +                    if (config == null) { // Backwards compatibility hack
  +                        config = (ApplicationConfig)
  +                            pageContext.getServletContext().getAttribute
  +                              (Action.APPLICATION_KEY);
  +                    }
                       form.setServlet(servlet);
  -                    form.reset(mappings.findMapping(getActionMappingName()),
  +                    form.reset((ActionMapping)
  +                               config.findActionConfig(getActionMappingName()),
                                  pageContext.getRequest());
                   }
   	    } catch (Exception e) {
  @@ -711,6 +715,11 @@
           HttpServletRequest request =
               (HttpServletRequest) pageContext.getRequest();
           StringBuffer value = new StringBuffer(request.getContextPath());
  +        ApplicationConfig config = (ApplicationConfig)
  +            pageContext.getRequest().getAttribute(Action.APPLICATION_KEY);
  +        if (config != null) {
  +            value.append(config.getPrefix());
  +        }
           
           // Use our servlet mapping, if one is specified
           String servletMapping = (String)
  @@ -719,8 +728,9 @@
           if (servletMapping != null) {
               String queryString = null;
               int question = action.indexOf("?");
  -            if (question >= 0)
  +            if (question >= 0) {
                   queryString = action.substring(question);
  +            }
               String actionMapping = getActionMappingName();
               if (servletMapping.startsWith("*.")) {
                   value.append(actionMapping);
  @@ -730,15 +740,17 @@
                                (0, servletMapping.length() - 2));
                   value.append(actionMapping);
               }
  -            if (queryString != null)
  +            if (queryString != null) {
                   value.append(queryString);
  +            }
           }
   
           // Otherwise, assume extension mapping is in use and extension is
           // already included in the action property
           else {
  -            if (!action.startsWith("/"))
  +            if (!action.startsWith("/")) {
                   value.append("/");
  +            }
               value.append(action);
           }
   
  @@ -770,14 +782,14 @@
               return;
           }
   
  -        // Look up the application scope collections that we need
  -        ActionMappings mappings = (ActionMappings)
  -            pageContext.getAttribute(Action.MAPPINGS_KEY,
  -                                     PageContext.APPLICATION_SCOPE);
  -        ActionFormBeans formBeans = (ActionFormBeans)
  -            pageContext.getAttribute(Action.FORM_BEANS_KEY,
  -                                     PageContext.APPLICATION_SCOPE);
  -        if ((mappings == null) || (formBeans == null)) {
  +        // Look up the application configuration information we need
  +        ApplicationConfig config = (ApplicationConfig)
  +            pageContext.getRequest().getAttribute(Action.APPLICATION_KEY);
  +        if (config == null) { // Backwards compatibility hack
  +            config = (ApplicationConfig)
  +                pageContext.getServletContext().getAttribute(Action.APPLICATION_KEY);
  +        }
  +        if (config == null) {
               JspException e = new JspException
                   (messages.getMessage("formTag.collections"));
               pageContext.setAttribute(Action.EXCEPTION_KEY, e,
  @@ -787,7 +799,8 @@
   
           // Look up the action mapping we will be submitting to
           String mappingName = getActionMappingName();
  -        ActionMapping mapping = mappings.findMapping(mappingName);
  +        ActionMapping mapping = (ActionMapping)
  +            config.findActionConfig(mappingName);
           if (mapping == null) {
               JspException e = new JspException
                   (messages.getMessage("formTag.mapping", mappingName));
  @@ -797,8 +810,8 @@
           }
   
           // Look up the form bean definition
  -        ActionFormBean formBean =
  -            formBeans.findFormBean(mapping.getName());
  +        ActionFormBean formBean = (ActionFormBean)
  +            config.findFormBeanConfig(mapping.getName());
           if (formBean == null) {
               JspException e = new JspException
                   (messages.getMessage("formTag.formBean", mapping.getName()));
  @@ -810,7 +823,7 @@
           // Calculate the required values
           name = mapping.getName();
           scope = mapping.getScope();
  -        servlet = mappings.getServlet();
  +        servlet = config.getServlet();
           type = formBean.getType();
   
       }
  
  
  
  1.14      +26 -10    jakarta-struts/src/share/org/apache/struts/taglib/html/ImageTag.java
  
  Index: ImageTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/ImageTag.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- ImageTag.java	11 Dec 2001 17:54:28 -0000	1.13
  +++ ImageTag.java	13 Jan 2002 00:25:37 -0000	1.14
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/ImageTag.java,v 1.13 2001/12/11 17:54:28 oalexeev Exp $
  - * $Revision: 1.13 $
  - * $Date: 2001/12/11 17:54:28 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/ImageTag.java,v 1.14 2002/01/13 00:25:37 craigmcc Exp $
  + * $Revision: 1.14 $
  + * $Date: 2002/01/13 00:25:37 $
    *
    * ====================================================================
    *
  @@ -72,6 +72,7 @@
   import javax.servlet.jsp.PageContext;
   import javax.servlet.jsp.JspWriter;
   import org.apache.struts.action.Action;
  +import org.apache.struts.config.ApplicationConfig;
   import org.apache.struts.util.MessageResources;
   import org.apache.struts.util.RequestUtils;
   import org.apache.struts.util.ResponseUtils;
  @@ -81,7 +82,7 @@
    * Tag for input fields of type "image".
    *
    * @author Oleg V Alexeev
  - * @version $Revision: 1.13 $ $Date: 2001/12/11 17:54:28 $
  + * @version $Revision: 1.14 $ $Date: 2002/01/13 00:25:37 $
    */
   
   public class ImageTag extends SubmitTag {
  @@ -184,7 +185,7 @@
   
   
       /**
  -     * The context-relative URI of the image.
  +     * The application-relative URI of the image.
        */
       protected String page = null;
   
  @@ -198,7 +199,7 @@
   
   
       /**
  -     * The message resources key of the context-relative URI of the image.
  +     * The message resources key of the application-relative URI of the image.
        */
       protected String pageKey = null;
   
  @@ -422,9 +423,16 @@
                   RequestUtils.saveException(pageContext, e);
                   throw e;
               }
  +            ApplicationConfig config = (ApplicationConfig)
  +                pageContext.getRequest().getAttribute(Action.APPLICATION_KEY);
               HttpServletRequest request =
                   (HttpServletRequest) pageContext.getRequest();
  -            return (request.getContextPath() + this.page);
  +            if (config == null) {
  +                return (request.getContextPath() + this.page);
  +            } else {
  +                return (request.getContextPath() + config.getPrefix() +
  +                        this.page);
  +            }
           }
   
           // Deal with an indirect context-relative page that has been specified
  @@ -435,11 +443,19 @@
                   RequestUtils.saveException(pageContext, e);
                   throw e;
               }
  +            ApplicationConfig config = (ApplicationConfig)
  +                pageContext.getRequest().getAttribute(Action.APPLICATION_KEY);
               HttpServletRequest request =
                   (HttpServletRequest) pageContext.getRequest();
  -            return (request.getContextPath() +
  -                    RequestUtils.message(pageContext, bundle,
  -                                         locale, this.pageKey));
  +            if (config == null) {
  +                return (request.getContextPath() +
  +                        RequestUtils.message(pageContext, bundle,
  +                                             locale, this.pageKey));
  +            } else {
  +                return (request.getContextPath() + config.getPrefix() +
  +                        RequestUtils.message(pageContext, bundle,
  +                                             locale, this.pageKey));
  +            }
           }
   
           // Deal with an absolute source that has been specified
  
  
  
  1.14      +25 -9     jakarta-struts/src/share/org/apache/struts/taglib/html/ImgTag.java
  
  Index: ImgTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/ImgTag.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- ImgTag.java	11 Dec 2001 17:54:28 -0000	1.13
  +++ ImgTag.java	13 Jan 2002 00:25:37 -0000	1.14
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/ImgTag.java,v 1.13 2001/12/11 17:54:28 oalexeev Exp $
  - * $Revision: 1.13 $
  - * $Date: 2001/12/11 17:54:28 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/ImgTag.java,v 1.14 2002/01/13 00:25:37 craigmcc Exp $
  + * $Revision: 1.14 $
  + * $Date: 2002/01/13 00:25:37 $
    *
    * ====================================================================
    *
  @@ -75,6 +75,7 @@
   import javax.servlet.jsp.JspWriter;
   import javax.servlet.jsp.PageContext;
   import org.apache.struts.action.Action;
  +import org.apache.struts.config.ApplicationConfig;
   import org.apache.struts.util.MessageResources;
   import org.apache.struts.util.RequestUtils;
   import org.apache.struts.util.ResponseUtils;
  @@ -95,7 +96,7 @@
    *
    * @author Michael Westbay
    * @author Craig McClanahan
  - * @version $Revision: 1.13 $
  + * @version $Revision: 1.14 $
    */
   
   public class ImgTag extends BaseHandlerTag {
  @@ -289,7 +290,7 @@
   
   
       /**
  -     * The context-relative path, starting with a slash character, of the
  +     * The application-relative path, starting with a slash character, of the
        * image to be displayed by this rendered tag.
        */
       protected String page = null;
  @@ -680,9 +681,16 @@
                   RequestUtils.saveException(pageContext, e);
                   throw e;
               }
  +            ApplicationConfig config = (ApplicationConfig)
  +                pageContext.getRequest().getAttribute(Action.APPLICATION_KEY);
               HttpServletRequest request =
                   (HttpServletRequest) pageContext.getRequest();
  -            return (request.getContextPath() + this.page);
  +            if (config == null) {
  +                return (request.getContextPath() + this.page);
  +            } else {
  +                return (request.getContextPath() + config.getPrefix() +
  +                        this.page);
  +            }
           }
   
           // Deal with an indirect context-relative page that has been specified
  @@ -693,11 +701,19 @@
                   RequestUtils.saveException(pageContext, e);
                   throw e;
               }
  +            ApplicationConfig config = (ApplicationConfig)
  +                pageContext.getRequest().getAttribute(Action.APPLICATION_KEY);
               HttpServletRequest request =
                   (HttpServletRequest) pageContext.getRequest();
  -            return (request.getContextPath() +
  -                    RequestUtils.message(pageContext, bundle,
  -                                         locale, this.pageKey));
  +            if (config == null) {
  +                return (request.getContextPath() +
  +                        RequestUtils.message(pageContext, bundle,
  +                                             locale, this.pageKey));
  +            } else {
  +                return (request.getContextPath() + config.getPrefix() +
  +                        RequestUtils.message(pageContext, bundle,
  +                                             locale, this.pageKey));
  +            }
           }
   
           // Deal with an absolute source that has been specified
  
  
  
  1.21      +5 -6      jakarta-struts/src/share/org/apache/struts/taglib/html/LinkTag.java
  
  Index: LinkTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/LinkTag.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- LinkTag.java	11 Dec 2001 17:54:28 -0000	1.20
  +++ LinkTag.java	13 Jan 2002 00:25:37 -0000	1.21
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/LinkTag.java,v 1.20 2001/12/11 17:54:28 oalexeev Exp $
  - * $Revision: 1.20 $
  - * $Date: 2001/12/11 17:54:28 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/LinkTag.java,v 1.21 2002/01/13 00:25:37 craigmcc Exp $
  + * $Revision: 1.21 $
  + * $Date: 2002/01/13 00:25:37 $
    *
    * ====================================================================
    *
  @@ -80,7 +80,6 @@
   import javax.servlet.jsp.PageContext;
   import org.apache.struts.action.Action;
   import org.apache.struts.action.ActionForward;
  -import org.apache.struts.action.ActionForwards;
   import org.apache.struts.util.MessageResources;
   import org.apache.struts.util.RequestUtils;
   import org.apache.struts.util.ResponseUtils;
  @@ -90,7 +89,7 @@
    * Generate a URL-encoded hyperlink to the specified URI.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.20 $ $Date: 2001/12/11 17:54:28 $
  + * @version $Revision: 1.21 $ $Date: 2002/01/13 00:25:37 $
    */
   
   public class LinkTag extends BaseHandlerTag {
  @@ -186,7 +185,7 @@
   
   
       /**
  -     * The context-relative page URL (beginning with a slash) to which
  +     * The application-relative page URL (beginning with a slash) to which
        * this hyperlink will be rendered.
        */
       protected String page = null;
  
  
  
  1.7       +4 -5      jakarta-struts/src/share/org/apache/struts/taglib/html/RewriteTag.java
  
  Index: RewriteTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/RewriteTag.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- RewriteTag.java	12 May 2001 20:34:01 -0000	1.6
  +++ RewriteTag.java	13 Jan 2002 00:25:37 -0000	1.7
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/RewriteTag.java,v 1.6 2001/05/12 20:34:01 craigmcc Exp $
  - * $Revision: 1.6 $
  - * $Date: 2001/05/12 20:34:01 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/RewriteTag.java,v 1.7 2002/01/13 00:25:37 craigmcc Exp $
  + * $Revision: 1.7 $
  + * $Date: 2002/01/13 00:25:37 $
    *
    * ====================================================================
    *
  @@ -78,7 +78,6 @@
   import javax.servlet.jsp.tagext.TagSupport;
   import org.apache.struts.action.Action;
   import org.apache.struts.action.ActionForward;
  -import org.apache.struts.action.ActionForwards;
   import org.apache.struts.util.MessageResources;
   import org.apache.struts.util.RequestUtils;
   import org.apache.struts.util.ResponseUtils;
  @@ -88,7 +87,7 @@
    * Generate a URL-encoded URI as a string.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.6 $ $Date: 2001/05/12 20:34:01 $
  + * @version $Revision: 1.7 $ $Date: 2002/01/13 00:25:37 $
    */
   
   public class RewriteTag extends LinkTag {
  
  
  
  1.8       +16 -12    jakarta-struts/src/share/org/apache/struts/taglib/logic/ForwardTag.java
  
  Index: ForwardTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/logic/ForwardTag.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ForwardTag.java	29 Apr 2001 03:51:01 -0000	1.7
  +++ ForwardTag.java	13 Jan 2002 00:25:37 -0000	1.8
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/logic/ForwardTag.java,v 1.7 2001/04/29 03:51:01 craigmcc Exp $
  - * $Revision: 1.7 $
  - * $Date: 2001/04/29 03:51:01 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/logic/ForwardTag.java,v 1.8 2002/01/13 00:25:37 craigmcc Exp $
  + * $Revision: 1.8 $
  + * $Date: 2002/01/13 00:25:37 $
    *
    * ====================================================================
    *
  @@ -72,17 +72,17 @@
   import javax.servlet.jsp.tagext.TagSupport;
   import org.apache.struts.action.Action;
   import org.apache.struts.action.ActionForward;
  -import org.apache.struts.action.ActionForwards;
  +import org.apache.struts.config.ApplicationConfig;
   import org.apache.struts.util.MessageResources;
   import org.apache.struts.util.RequestUtils;
   
   
   /**
  - * Perform a forward or redirect to a page that is looked up in the global
  - * ActionForwards collection associated with our application.
  + * Perform a forward or redirect to a page that is looked up in the
  + * configuration information associated with our application.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.7 $ $Date: 2001/04/29 03:51:01 $
  + * @version $Revision: 1.8 $ $Date: 2002/01/13 00:25:37 $
    */
   
   public class ForwardTag extends TagSupport {
  @@ -139,11 +139,15 @@
   
   	// Look up the desired ActionForward entry
   	ActionForward forward = null;
  -	ActionForwards forwards =
  -	    (ActionForwards) pageContext.getAttribute
  -	      (Action.FORWARDS_KEY, PageContext.APPLICATION_SCOPE);
  -	if (forwards != null)
  -	    forward = forwards.findForward(name);
  +        ApplicationConfig config = (ApplicationConfig)
  +            pageContext.getRequest().getAttribute(Action.APPLICATION_KEY);
  +        if (config == null) { // Backwards compatibility hack
  +            config = (ApplicationConfig)
  +                pageContext.getServletContext().getAttribute
  +                (Action.APPLICATION_KEY);
  +        }
  +	if (config != null)
  +	    forward = (ActionForward) config.findForwardConfig(name);
   	if (forward == null) {
               JspException e = new JspException
   		(messages.getMessage("forward.lookup", name));
  
  
  
  1.12      +5 -6      jakarta-struts/src/share/org/apache/struts/taglib/logic/RedirectTag.java
  
  Index: RedirectTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/logic/RedirectTag.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- RedirectTag.java	16 Jul 2001 00:44:57 -0000	1.11
  +++ RedirectTag.java	13 Jan 2002 00:25:37 -0000	1.12
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/logic/RedirectTag.java,v 1.11 2001/07/16 00:44:57 craigmcc Exp $
  - * $Revision: 1.11 $
  - * $Date: 2001/07/16 00:44:57 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/logic/RedirectTag.java,v 1.12 2002/01/13 00:25:37 craigmcc Exp $
  + * $Revision: 1.12 $
  + * $Date: 2002/01/13 00:25:37 $
    *
    * ====================================================================
    *
  @@ -79,7 +79,6 @@
   import org.apache.commons.beanutils.PropertyUtils;
   import org.apache.struts.action.Action;
   import org.apache.struts.action.ActionForward;
  -import org.apache.struts.action.ActionForwards;
   import org.apache.struts.util.MessageResources;
   import org.apache.struts.util.RequestUtils;
   import org.apache.struts.util.ResponseUtils;
  @@ -89,7 +88,7 @@
    * Generate a URL-encoded redirect to the specified URI.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.11 $ $Date: 2001/07/16 00:44:57 $
  + * @version $Revision: 1.12 $ $Date: 2002/01/13 00:25:37 $
    */
   
   public class RedirectTag extends TagSupport {
  @@ -163,7 +162,7 @@
   
   
       /**
  -     * The context-relative page URL (beginning with a slash) to which
  +     * The application-relative page URL (beginning with a slash) to which
        * this redirect will be rendered.
        */
       protected String page = null;
  
  
  
  1.9       +14 -6     jakarta-struts/src/share/org/apache/struts/taglib/template/InsertTag.java
  
  Index: InsertTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/template/InsertTag.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- InsertTag.java	29 Apr 2001 05:34:49 -0000	1.8
  +++ InsertTag.java	13 Jan 2002 00:25:37 -0000	1.9
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/template/InsertTag.java,v 1.8 2001/04/29 05:34:49 craigmcc Exp $
  - * $Revision: 1.8 $
  - * $Date: 2001/04/29 05:34:49 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/template/InsertTag.java,v 1.9 2002/01/13 00:25:37 craigmcc Exp $
  + * $Revision: 1.9 $
  + * $Date: 2002/01/13 00:25:37 $
    *
    * ====================================================================
    *
  @@ -66,6 +66,7 @@
   import javax.servlet.jsp.PageContext;
   import javax.servlet.jsp.tagext.TagSupport;
   import org.apache.struts.action.Action;
  +import org.apache.struts.config.ApplicationConfig;
   import org.apache.struts.taglib.template.util.*;
   
   /**
  @@ -74,7 +75,7 @@
    * tags, which are accessed by &lt;template:get&gt; in the template.
    *
    * @author David Geary
  - * @version $Revision: 1.8 $ $Date: 2001/04/29 05:34:49 $
  + * @version $Revision: 1.9 $ $Date: 2002/01/13 00:25:37 $
    */
   public class InsertTag extends TagSupport {
   
  @@ -89,10 +90,11 @@
   
   
      /**
  -     * The URI of the template. 
  +     * The application-relative URI of the template. 
        */
      private String template;
   
  +
   // --------------------------------------------------------- Public Methods
   
   
  @@ -141,8 +143,14 @@
        */
      public int doEndTag() throws JspException {
   
  +      String prefix = "";
  +      ApplicationConfig config = (ApplicationConfig)
  +          pageContext.getServletContext().getAttribute(Action.APPLICATION_KEY);
  +      if (config != null) {
  +          prefix = config.getPrefix();
  +      }
         try {
  -         pageContext.include(template);
  +         pageContext.include(prefix + template);
         }
         catch(Exception ex) { // IOException or ServletException
            saveException(ex);
  
  
  
  1.11      +22 -18    jakarta-struts/src/share/org/apache/struts/upload/DiskMultipartRequestHandler.java
  
  Index: DiskMultipartRequestHandler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/upload/DiskMultipartRequestHandler.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- DiskMultipartRequestHandler.java	11 May 2001 22:33:36 -0000	1.10
  +++ DiskMultipartRequestHandler.java	13 Jan 2002 00:25:37 -0000	1.11
  @@ -10,9 +10,10 @@
   import javax.servlet.ServletContext;
   import javax.servlet.ServletException;
   import javax.servlet.http.HttpServletRequest;
  -
  +import org.apache.struts.action.Action;
   import org.apache.struts.action.ActionServlet;
   import org.apache.struts.action.ActionMapping;
  +import org.apache.struts.config.ApplicationConfig;
   
   /**
    * This is a MultipartRequestHandler that writes file data directly to
  @@ -60,12 +61,15 @@
        */
       public void handleRequest(HttpServletRequest request) throws ServletException {
           
  -        retrieveTempDir();
  -        
  -        MultipartIterator iterator = new MultipartIterator(request,
  -                                                            servlet.getBufferSize(),
  -                                                            getMaxSizeFromServlet(),
  -                                                            tempDir);
  +        ApplicationConfig appConfig = (ApplicationConfig)
  +            request.getAttribute(Action.APPLICATION_KEY);
  +        retrieveTempDir(appConfig);
  +        
  +        MultipartIterator iterator =
  +            new MultipartIterator(request,
  +                                  appConfig.getControllerConfig().getBufferSize(),
  +                                  getMaxSize(appConfig.getControllerConfig().getMaxFileSize()),
  +                                  tempDir);
           MultipartElement element;
   
           textElements = new Hashtable();
  @@ -166,10 +170,9 @@
   
       /**
        * Gets the maximum post data size in bytes from the string
  -     * representation in ActionServlet
  +     * representation in the configuration file.
        */
  -    protected long getMaxSizeFromServlet() throws ServletException{
  -        String stringSize = servlet.getMaxFileSize();
  +    protected long getMaxSize(String stringSize) throws ServletException{
           long size = -1;
           int multiplier = 1;
           
  @@ -190,8 +193,7 @@
               size = Long.parseLong(stringSize);
           }
           catch (NumberFormatException nfe) {
  -            throw new ServletException("Invalid format for maximum file size: \"" +
  -                servlet.getMaxFileSize() + "\"");
  +            throw new ServletException("Invalid format for maximum file size");
           }
                   
           return (size * multiplier);
  @@ -201,13 +203,15 @@
        * Retrieves the temporary directory from either ActionServlet, a context
        * property, or a system property, in that order
        */
  -    protected void retrieveTempDir() { 
  +    protected void retrieveTempDir(ApplicationConfig appConfig) { 
           
           //attempt to retrieve the servlet container's temporary directory
  -        ServletContext context = servlet.getServletConfig().getServletContext();
  +        ServletContext context =
  +            appConfig.getServlet().getServletContext();
          
           try {
  -            tempDir = (String) context.getAttribute("javax.servlet.context.tempdir");
  +            tempDir =
  +                (String) context.getAttribute("javax.servlet.context.tempdir");
           }
           catch (ClassCastException cce) {
               tempDir = ((File) context.getAttribute("javax.servlet.context.tempdir")).getAbsolutePath();
  @@ -215,13 +219,13 @@
           
           if (tempDir == null) {            
               //attempt to retrieve the temporary directory from the controller
  -            tempDir = servlet.getTempDir();
  +            tempDir = appConfig.getControllerConfig().getTempDir();
   
               if (tempDir == null) {
                   //default to system-wide tempdir
                   tempDir = System.getProperty("java.io.tmpdir");
   
  -                if (servlet.getDebug() > 1) {
  +                if (appConfig.getServlet().getDebug() > 1) {
                       servlet.log("DiskMultipartRequestHandler.handleRequest(): " +
                       "defaulting to java.io.tmpdir directory \"" +
                       tempDir);
  @@ -229,4 +233,4 @@
               }
           }
       }
  -}
  \ No newline at end of file
  +}
  
  
  
  1.27      +86 -41    jakarta-struts/src/share/org/apache/struts/util/RequestUtils.java
  
  Index: RequestUtils.java
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/src/share/org/apache/struts/util/RequestUtils.java,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- RequestUtils.java	29 Dec 2001 19:35:33 -0000	1.26
  +++ RequestUtils.java	13 Jan 2002 00:25:37 -0000	1.27
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/util/RequestUtils.java,v 1.26 2001/12/29 19:35:33 craigmcc Exp $
  - * $Revision: 1.26 $
  - * $Date: 2001/12/29 19:35:33 $
  + * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/util/RequestUtils.java,v 1.27 2002/01/13 00:25:37 craigmcc Exp $
  + * $Revision: 1.27 $
  + * $Date: 2002/01/13 00:25:37 $
    *
    * ====================================================================
    *
  @@ -88,7 +88,6 @@
   import org.apache.struts.action.ActionErrors;
   import org.apache.struts.action.ActionForm;
   import org.apache.struts.action.ActionForward;
  -import org.apache.struts.action.ActionForwards;
   import org.apache.struts.action.ActionMapping;
   import org.apache.struts.action.ActionMessage;
   import org.apache.struts.action.ActionMessages;
  @@ -105,7 +104,7 @@
    *
    * @author Craig R. McClanahan
    * @author Ted Husted
  - * @version $Revision: 1.26 $ $Date: 2001/12/29 19:35:33 $
  + * @version $Revision: 1.27 $ $Date: 2002/01/13 00:25:37 $
    */
   
   public class RequestUtils {
  @@ -291,7 +290,7 @@
        * @param forward Logical forward name for which to look up
        *  the context-relative URI (if specified)
        * @param href URL to be utilized unmodified (if specified)
  -     * @param page Context-relative page for which a URL should
  +     * @param page Application-relative page for which a URL should
        *  be created (if specified)
        *
        * @param params Map of parameters to be dynamically included (if any)
  @@ -310,40 +309,57 @@
   
           // Validate that exactly one specifier was included
           int n = 0;
  -        if (forward != null)
  +        if (forward != null) {
               n++;
  -        if (href != null)
  +        }
  +        if (href != null) {
               n++;
  -        if (page != null)
  +        }
  +        if (page != null) {
               n++;
  -        if (n != 1)
  +        }
  +        if (n != 1) {
               throw new MalformedURLException
                   (messages.getMessage("computeURL.specifier"));
  +        }
  +
  +        // Look up the application configuration for this request
  +        ApplicationConfig config = (ApplicationConfig)
  +            pageContext.getRequest().getAttribute(Action.APPLICATION_KEY);
  +        if (config == null) { // Backwards compatibility hack
  +            config = (ApplicationConfig)
  +                pageContext.getServletContext().getAttribute
  +                (Action.APPLICATION_KEY);
  +        }
   
           // Calculate the appropriate URL
           StringBuffer url = new StringBuffer();
           HttpServletRequest request =
               (HttpServletRequest) pageContext.getRequest();
           if (forward != null) {
  -            ActionForwards forwards = (ActionForwards)
  -                pageContext.getAttribute(Action.FORWARDS_KEY,
  -                                         PageContext.APPLICATION_SCOPE);
  -            if (forwards == null)
  -                throw new MalformedURLException
  -                    (messages.getMessage("computeURL.forwards"));
  -            ActionForward af = forwards.findForward(forward);
  -            if (af == null)
  +            ActionForward af =
  +                (ActionForward) config.findForwardConfig(forward);
  +            if (af == null) {
                   throw new MalformedURLException
                       (messages.getMessage("computeURL.forward", forward));
  -            if (af.getRedirect())
  +            }
  +            if (af.getRedirect()) {
                   redirect = true;
  -            if (af.getPath().startsWith("/"))
  +            }
  +            if (af.getPath().startsWith("/")) {
                   url.append(request.getContextPath());
  +                if ((config != null) && !af.getContextRelative()) {
  +                    url.append(config.getPrefix());
  +                }
  +            }
               url.append(af.getPath());
           } else if (href != null) {
               url.append(href);
           } else /* if (page != null) */ {
               url.append(request.getContextPath());
  +            if (config != null) {
  +                url.append(config.getPrefix());
  +            }
               url.append(page);
           }
   
  @@ -351,8 +367,9 @@
           if (anchor != null) {
               String temp = url.toString();
               int hash = temp.indexOf('#');
  -            if (hash >= 0)
  +            if (hash >= 0) {
                   url.setLength(hash);
  +            }
               url.append('#');
               url.append(URLEncoder.encode(anchor));
           }
  @@ -367,8 +384,9 @@
                   anchor = temp.substring(hash + 1);
                   url.setLength(hash);
                   temp = url.toString();
  -            } else
  +            } else {
                   anchor = null;
  +            }
   
               // Add the required request parameters
               boolean question = temp.indexOf('?') >= 0;
  @@ -380,16 +398,18 @@
                       if (!question) {
                           url.append('?');
                           question = true;
  -                    } else
  +                    } else {
                           url.append("&amp;");
  +                    }
                       url.append(URLEncoder.encode(key));
                       url.append('='); // Interpret null as "no value"
                   } else if (value instanceof String) {
                       if (!question) {
                           url.append('?');
                           question = true;
  -                    } else
  +                    } else {
                           url.append("&amp;");
  +                    }
                       url.append(URLEncoder.encode(key));
                       url.append('=');
                       url.append(URLEncoder.encode((String) value));
  @@ -399,8 +419,9 @@
                           if (!question) {
                               url.append('?');
                               question = true;
  -                        } else
  +                        } else {
                               url.append("&amp;");
  +                        }
                           url.append(URLEncoder.encode(key));
                           url.append('=');
                           url.append(URLEncoder.encode(values[i]));
  @@ -409,8 +430,9 @@
                       if (!question) {
                           url.append('?');
                           question = true;
  -                    } else
  +                    } else {
                           url.append("&amp;");
  +                    }
                       url.append(URLEncoder.encode(key));
                       url.append('=');
                       url.append(URLEncoder.encode(value.toString()));
  @@ -429,12 +451,14 @@
           if (pageContext.getSession() != null) {
               HttpServletResponse response =
                   (HttpServletResponse) pageContext.getResponse();
  -            if (redirect)
  +            if (redirect) {
                   return (response.encodeRedirectURL(url.toString()));
  -            else
  +            } else {
                   return (response.encodeURL(url.toString()));
  -        } else
  +            }
  +        } else {
               return (url.toString());
  +        }
   
       }
   
  @@ -592,11 +616,19 @@
                                    String locale, String key, Object args[])
           throws JspException {
   
  +        MessageResources resources = null;
  +
           // Look up the requested MessageResources
  -        if (bundle == null)
  +        if (bundle == null) {
               bundle = Action.MESSAGES_KEY;
  -        MessageResources resources = (MessageResources)
  -            pageContext.getAttribute(bundle, PageContext.APPLICATION_SCOPE);
  +            resources = (MessageResources)
  +                pageContext.getAttribute(bundle);
  +        }
  +        if (resources == null) {
  +            resources = (MessageResources)
  +                pageContext.getAttribute(bundle,
  +                                         PageContext.APPLICATION_SCOPE);
  +        }
           if (resources == null) {
               JspException e = new JspException
                   (messages.getMessage("message.bundle", bundle));
  @@ -605,13 +637,16 @@
           }
   
           // Look up the requested Locale
  +        if (locale == null)
  +            locale = Action.LOCALE_KEY;
           Locale userLocale = retrieveUserLocale( pageContext, locale );
   
           // Return the requested message
  -        if (args == null)
  +        if (args == null) {
               return (resources.getMessage(userLocale, key));
  -        else
  +        } else {
               return (resources.getMessage(userLocale, key, args));
  +        }
   
       }
   
  @@ -812,7 +847,9 @@
                   return multipartHandler;
           }
   
  -        multipartClass = servlet.getMultipartClass();
  +        ApplicationConfig appConfig = (ApplicationConfig)
  +            request.getAttribute(Action.APPLICATION_KEY);
  +        multipartClass = appConfig.getControllerConfig().getMultipartClass();
   
           // Try to initialize the global request handler
           if (multipartClass != null) {
  @@ -822,19 +859,19 @@
               }
               catch (ClassNotFoundException cnfe) {
                   throw new ServletException("Cannot find multipart class \"" +
  -                    servlet.getMultipartClass() + "\"" +
  +                    multipartClass + "\"" +
                       ", exception: " + cnfe.getMessage());
               }
               catch (InstantiationException ie) {
                   throw new ServletException(
                       "InstantiaionException when instantiating " +
  -                    "multipart class \"" + servlet.getMultipartClass() +
  +                    "multipart class \"" + multipartClass +
                       "\", exception: " + ie.getMessage());
               }
               catch (IllegalAccessException iae) {
                   throw new ServletException(
                       "IllegalAccessException when instantiating " +
  -                    "multipart class \"" + servlet.getMultipartClass() +
  +                    "multipart class \"" + multipartClass +
                       "\", exception: " + iae.getMessage());
               }
   
  @@ -863,11 +900,19 @@
                                     String locale, String key)
           throws JspException {
   
  +        MessageResources resources = null;
  +
           // Look up the requested MessageResources
  -        if (bundle == null)
  +        if (bundle == null) {
               bundle = Action.MESSAGES_KEY;
  -        MessageResources resources = (MessageResources)
  -            pageContext.getAttribute(bundle, PageContext.APPLICATION_SCOPE);
  +            resources = (MessageResources)
  +                pageContext.getAttribute(bundle);
  +        }
  +        if (resources == null) {
  +            resources = (MessageResources)
  +                pageContext.getAttribute(bundle,
  +                                         PageContext.APPLICATION_SCOPE);
  +        }
           if (resources == null) {
               JspException e = new JspException
                   (messages.getMessage("message.bundle", bundle));
  
  
  
  1.4       +1 -1      jakarta-struts/web/exercise-taglib/html-select.jsp
  
  Index: html-select.jsp
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/web/exercise-taglib/html-select.jsp,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- html-select.jsp	8 Nov 2001 03:34:39 -0000	1.3
  +++ html-select.jsp	13 Jan 2002 00:25:37 -0000	1.4
  @@ -1,4 +1,4 @@
  -<%@ page language="java" import="java.util.*, org.apache.struts.util.*;"%>
  +<%@ page language="java" import="java.util.*, org.apache.struts.util.*"%>
   <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
   <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
   <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
  
  
  
  1.3       +4 -0      jakarta-struts/web/exercise-taglib/WEB-INF/web.xml
  
  Index: web.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/web/exercise-taglib/WEB-INF/web.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- web.xml	25 Jun 2001 00:02:32 -0000	1.2
  +++ web.xml	13 Jan 2002 00:25:37 -0000	1.3
  @@ -12,6 +12,10 @@
       <servlet-name>action</servlet-name>
       <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
       <init-param>
  +      <param-name>application</param-name>
  +      <param-value>org.apache.struts.webapp.exercise.ApplicationResources</param-value>
  +    </init-param>
  +    <init-param>
         <param-name>config</param-name>
         <param-value>/WEB-INF/struts-config.xml</param-value>
       </init-param>
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-struts/web/exercise-taglib/WEB-INF web.xml

Posted by Ted Husted <hu...@apache.org>.
"Craig R. McClanahan" wrote:
> The ApplicationConfig object itself is exposed (as a request attribute),
> so all the usual introspection-based access to its innards is still
> possible.  What's missing?

I was trying to expose the innards in a very convenient way so that they
would be trivial to use with other presentation systems. For example,
with the ContextHelper, the <struts:errors/> tag could be rendered in a 
Velocity template as 

$!get.errorMarkup

and the Action for a form could be represented as 

<form method="POST" action="$get.action('/logonSubmit')">

a forward as 

<a href="$get.link('logon')">Sign in</a>

and so forth. 

Gabriel and Geir used a slightly different approach in their
Velocity/Struts toolkit, that more closely mimics the tags, and so
renders the same thing as 

$!html.errorMarkup()
        
<form method="POST" action="$html.actionMappingURL('/logonSubmit_vm')">

<a href="$html.link('logon_vm')">Sign in</a>

and they also have another object for $bean.message(), et cetera.


Can we do the equivalent with the ActionConfig object?


I'm now taking a look at the current JSTL EA to see what we would need
to
do to support that in a similar fashion, so we might put these together
into a common approach. 

One thought might be to have ContextHelper factories that might render
an optimized API object for a given presentation device. Which would
also
imply that would could have a null factory that would not bother
inserting anything, if that is a concern.


-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Java Web Development with Struts.
-- Tel +1 585 737-3463.
-- Web http://www.husted.com/struts/

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-struts/web/exercise-taglib/WEB-INF web.xml

Posted by "Craig R. McClanahan" <cr...@apache.org>.

On Wed, 23 Jan 2002, Ted Husted wrote:

> Date: Wed, 23 Jan 2002 17:53:56 -0500
> From: Ted Husted <hu...@apache.org>
> Reply-To: Struts Developers List <st...@jakarta.apache.org>
> To: Struts Developers List <st...@jakarta.apache.org>
> Subject: Re: cvs commit: jakarta-struts/web/exercise-taglib/WEB-INF
>     web.xml
>
> craigmcc@apache.org wrote:
> >   Removed:     src/share/org/apache/struts/action ActionExceptions.java
> >                         ContextHelper.java
>
> Craig,
>
> One idea behind the ContextHelper was to expose the controller's "model"
> to arbitrary presentation systems, like Velocity Templates and perhaps
> JSTL.
>
> Are we planning to add this functionality to the ApplicationConfig ?
>
> The idea is to have a bean in the request that presentation layer
> devices can access without having to import any binaries from the
> framework -- pure API.
>

The ApplicationConfig object itself is exposed (as a request attribute),
so all the usual introspection-based access to its innards is still
possible.  What's missing?

> Should I update the class for the new ActionServlet and commit it back.
> It worked well with Velocity
>
> http://husted.com/struts/resources/velservlet.zip
>
> and I was about to try it with the JSTL EA.
>
> -Ted.

Craig


> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-struts/web/exercise-taglib/WEB-INF web.xml

Posted by Ted Husted <hu...@apache.org>.
craigmcc@apache.org wrote:
>   Removed:     src/share/org/apache/struts/action ActionExceptions.java
>                         ContextHelper.java

Craig, 

One idea behind the ContextHelper was to expose the controller's "model"
to arbitrary presentation systems, like Velocity Templates and perhaps
JSTL. 

Are we planning to add this functionality to the ApplicationConfig ?

The idea is to have a bean in the request that presentation layer
devices can access without having to import any binaries from the
framework -- pure API. 

Should I update the class for the new ActionServlet and commit it back.
It worked well with Velocity 

http://husted.com/struts/resources/velservlet.zip

and I was about to try it with the JSTL EA.

-Ted.

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-struts/web/exercise-taglib/WEB-INF web.xml

Posted by Ted Husted <hu...@apache.org>.
A couple of points before I move this to Scaffold ...

"Craig R. McClanahan" wrote:
> Chaining is unlikely to be significantly more efficient than request
> dispatcher forwarding.  Also, beyond that, I do have a couple of
> design/architecture concerns:

Chaining is a misnomer. Here, we are actually *including* another
action. Control does not pass to the other action, but returns to the
caller. It is the current situation that encourages chaining, and loss
of centralized control of the request/response event.


> * Not using a RequestDispatcher.forward() means you don't get
>   the container semantics of erasing any previously generated
>   output (and complaining if you've already committed the response).
>   Unless you simulate this -- which you could do with wrappers in
>   Servlet 2.3 -- an action invoked this way sees different behavior
>   than one invoked via an RD.

Since this is one action including another, we are already past the
container semantics. It is the developer's responsibility to ensure that
an insecure action does not include a secure action, the same as it
would be for any servlet resource.



> * In the early days of servlets (prior to the 2.0 spec) there was a
>   feature of some containers called "servlet chaining", which differs
>   in details from this but was the same idea in spirit -- seducing
>   the developer into combining components in ways that were not the
>   original intent.  People that used this technique tended to create
>   spaghetti code that was very difficult to maintain.  I'd rather
>   avoid that.

The suggested approach is an alternative to chaining, which is what we
now encourage. By allowing one action to include another, we are
bringing conventional servlet semantics to the actions. Since the
actions are in effect proxy servlets, this simply provides the
functionality actions need to do their job, without resorting to a
chaining paradigm.


 
> * Because using a request dispatcher flows back through the controller,
>   we have the opportunity to "value add" new standard logic (such as
>   role-based access)  before the forward is completed -- but chaining
>   would bypass this.

The value-add is most often a value-diminish, since the current
controller is not designed to recognize action chaining. Instead, it is
designed to overwrite any changes developers might have made to an
ActionForm that they are trying to pass to another action. This causes
the developer to either extend the ActionForm to support an immutable
mode, or to construct a query string to override the original. 

Constructing a query string in the action encroaches on the seperation
of concern created by the Struts configuration. Actions do not otherwise
need to be concerned with the semantics of query strings, since this
information can be encapsulated in the ActionForm, unless they need to
chain to another action. 

We are currently forcing workarounds rather than recognizing that
including actions is a common development pattern. From the framework's
perspective, the ActionForm is an API object for passing parameters to
the perform method, and so the framework should support passing that API
object from one action to another, using a well understood mechanism.  

The proposed methods may not be the optimal approach to including
actions, but neglecting to provide the functionality encourages
chaining, which has been dimissed as an inappropriate pattern. If these
methods are vetoed, I would suggest that another concrete strategy be
proposed, so that developers have a common way to approach this typical
design pattern.


> I vote for maintaining the original design intent, and requiring actions
> who want to invoke others to simply return an ActionForward that points at
> another action, instead of a UI component.

I submit that including actions is a feature that the original design
implies but does not implement. The proposed methods supply
functionality that could have been present from the beginning, but was
overlooked.


-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Java Web Development with Struts.
-- Tel +1 585 737-3463.
-- Web http://www.husted.com/struts/

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-struts/web/exercise-taglib/WEB-INF web.xml

Posted by Ted Husted <hu...@apache.org>.
The problem I see when I review applications is that people are already
writing spaghetti code. They create dynamic forwards, pasting on
parameters, and so forth, building up an package of arcane 
instuctions, just so they can turn around and have those parsed 
back into an ActionForm someplace else. 

If someone wants to chain an action, this lets them do so cleanly
without infesting the action class with all the HTTP parameters the
ActionForms work so hard to strip out :)

Bypassing the semantics is actually the point, since the Struts
request/forward cycle has side effects like resetting and refreshing
the ActionForm from the request. 

There are workarounds, like adding a switch to make an ActionForm
immutable, but it really seems to me that, in practice, keeping one
action from invoking another promotes spaghetti code, rather than
preventing it. Creating an ActionForward to send control around the
mulberry bush is not as clear as simply invoking the Action you want.

Personally, I do * not * chain Actions. I put the functionality in a
business API that various Actions can call if they need to. But I see a
lot of people trying to chain Actions, and this seemed like a cleaner
alternative than hardcoding HTTP details, like parameters, into the
Actions. It's not a perfect solution but HTTP is not a perfect protocol.

Again, I strongly feel that the better alternative is to use the Actions
like macros to call a business API, but it's like pulling teeth to get
people to do that =:0( And this seems like the next best thing. 

Of course, it would not be hard to just put this in an optional package,
like Scaffold, since I understand the importance of not encouraging
incorrect behavior, * so that's what I will plan on doing *, and we 
can ldave it out of the cannonical ActionServlet. But it is important 
to recognize that the approach we have now does not really
encourage correct behavior either. At least in practice.

Hopefully, the workflow model * will * encourage better behavior, since
that encourages use of a business API rather than casting Actions in
that role. I've been doing a lot of workflow-type things in my own
applications lately, which I think will map well to the Commons
initiative. It's gotten so I rarely write a new custom action anymore,
but simply instruct a standard one to access business method, and return
the result. Everything is run from the Struts config, as you envisioned
in the original workflow proposal :)

-T.


"Craig R. McClanahan" wrote:
> Chaining is unlikely to be significantly more efficient than request
> dispatcher forwarding.  Also, beyond that, I do have a couple of
> design/architecture concerns:
> 
> * Not using a RequestDispatcher.forward() means you don't get
>   the container semantics of erasing any previously generated
>   output (and complaining if you've already committed the response).
>   Unless you simulate this -- which you could do with wrappers in
>   Servlet 2.3 -- an action invoked this way sees different behavior
>   than one invoked via an RD.
> 
> * In the early days of servlets (prior to the 2.0 spec) there was a
>   feature of some containers called "servlet chaining", which differs
>   in details from this but was the same idea in spirit -- seducing
>   the developer into combining components in ways that were not the
>   original intent.  People that used this technique tended to create
>   spaghetti code that was very difficult to maintain.  I'd rather
>   avoid that.
> 
> * Because using a request dispatcher flows back through the controller,
>   we have the opportunity to "value add" new standard logic (such as
>   role-based access)  before the forward is completed -- but chaining
>   would bypass this.
> 
> I vote for maintaining the original design intent, and requiring actions
> who want to invoke others to simply return an ActionForward that points at
> another action, instead of a UI component.
> 
> > Or, did you just want to deal with it later? Should I take care of it
> > now?
> >
> > -Ted.

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-struts/web/exercise-taglib/WEB-INF web.xml

Posted by "Craig R. McClanahan" <cr...@apache.org>.

On Wed, 23 Jan 2002, Ted Husted wrote:

> Date: Wed, 23 Jan 2002 18:10:07 -0500
> From: Ted Husted <hu...@apache.org>
> Reply-To: Struts Developers List <st...@jakarta.apache.org>
> To: Struts Developers List <st...@jakarta.apache.org>
> Subject: Re: cvs commit: jakarta-struts/web/exercise-taglib/WEB-INF
>     web.xml
>
> Craig,
>
> I had thought this would be a useful way for Developers to chain actions
> without generating additional forwards. Do you disagree? Is there a
> problem with the implementation? I know some people have found it
> useful, and have made dependencies on it.
>

Chaining is unlikely to be significantly more efficient than request
dispatcher forwarding.  Also, beyond that, I do have a couple of
design/architecture concerns:

* Not using a RequestDispatcher.forward() means you don't get
  the container semantics of erasing any previously generated
  output (and complaining if you've already committed the response).
  Unless you simulate this -- which you could do with wrappers in
  Servlet 2.3 -- an action invoked this way sees different behavior
  than one invoked via an RD.

* In the early days of servlets (prior to the 2.0 spec) there was a
  feature of some containers called "servlet chaining", which differs
  in details from this but was the same idea in spirit -- seducing
  the developer into combining components in ways that were not the
  original intent.  People that used this technique tended to create
  spaghetti code that was very difficult to maintain.  I'd rather
  avoid that.

* Because using a request dispatcher flows back through the controller,
  we have the opportunity to "value add" new standard logic (such as
  role-based access)  before the forward is completed -- but chaining
  would bypass this.

I vote for maintaining the original design intent, and requiring actions
who want to invoke others to simply return an ActionForward that points at
another action, instead of a UI component.

> Or, did you just want to deal with it later? Should I take care of it
> now?
>
> -Ted.

Craig


>
> >   -    /**
> >   -     * Return an instance of the ActionForm associated with the specified
> >   -     * path, if any; otherwise return <code>null</code>.
> >   -     * May be used to create an ActionForm for InvokeAction.
> >   -     *
> >   -     * @param name path of the Action using the ActionForm bean
> >   -     * @since 1.1
> >   -     */
> >   -    public ActionForm createActionForm(String path) {
> >   -
> >   -        ActionMapping mapping = findMapping(path);
> >   -        String name = mapping.getName();
> >   -
> >   -        ActionForm form = null;
> >   -
> >   -        ActionFormBean formBean = findFormBean(name);
> >   -        if (formBean != null) {
> >   -            String className = null;
> >   -            className = formBean.getType();
> >   -            try {
> >   -                Class clazz = Class.forName(className);
> >   -                form = (ActionForm) clazz.newInstance();
> >   -            } catch (Throwable t) {
> >   -                form = null;
> >   -            }
> >   -        }
> >   -
> >   -        return form;
> >   -
> >   -    }
> >   -
> >   -
> >   -    /**
> >   -     * Directly process the Action perform associated with the
> >   -     * given path.
> >   -     * Return the <code>ActionForward</code> instance (if any)
> >   -     * returned by the called <code>Action</code>.
> >   -     * <code>createActionForm</code> may be used to create an
> >   -     * ActionForm instance to pass to the Action invoked.
> >   -     *
> >   -     * @param action The path to the Action to invoke
> >   -     * @param form The ActionForm we are processing
> >   -     * @param request The servlet request we are processing
> >   -     * @param response The servlet response we are creating
> >   -     *
> >   -     * @exception IOException if an input/output error occurs
> >   -     * @exception ServletException if a servlet exception occurs
> >   -     * @since 1.1
> >   -     */
> >   -    public ActionForward invokeAction(
> >   -            String path,
> >   -            ActionForm form,
> >   -            HttpServletRequest request,
> >   -            HttpServletResponse response)
> >   -        throws IOException, ServletException {
> >   -
> >   -        ActionMapping mapping =
> >   -            processMapping(path,request);
> >   -
> >   -        Action action =
> >   -            processActionCreate(mapping,request);
> >   -
> >   -        ActionForward forward = processActionPerform(
> >   -            action,mapping,form,request,response);
> >   -
> >   -        return forward;
> >   -
> >   -    }
>
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: cvs commit: jakarta-struts/web/exercise-taglib/WEB-INF web.xml

Posted by Ted Husted <hu...@apache.org>.
Craig, 

I had thought this would be a useful way for Developers to chain actions
without generating additional forwards. Do you disagree? Is there a
problem with the implementation? I know some people have found it
useful, and have made dependencies on it. 

Or, did you just want to deal with it later? Should I take care of it
now?

-Ted.

>   -    /**
>   -     * Return an instance of the ActionForm associated with the specified
>   -     * path, if any; otherwise return <code>null</code>.
>   -     * May be used to create an ActionForm for InvokeAction.
>   -     *
>   -     * @param name path of the Action using the ActionForm bean
>   -     * @since 1.1
>   -     */
>   -    public ActionForm createActionForm(String path) {
>   -
>   -        ActionMapping mapping = findMapping(path);
>   -        String name = mapping.getName();
>   -
>   -        ActionForm form = null;
>   -
>   -        ActionFormBean formBean = findFormBean(name);
>   -        if (formBean != null) {
>   -            String className = null;
>   -            className = formBean.getType();
>   -            try {
>   -                Class clazz = Class.forName(className);
>   -                form = (ActionForm) clazz.newInstance();
>   -            } catch (Throwable t) {
>   -                form = null;
>   -            }
>   -        }
>   -
>   -        return form;
>   -
>   -    }
>   -
>   -
>   -    /**
>   -     * Directly process the Action perform associated with the
>   -     * given path.
>   -     * Return the <code>ActionForward</code> instance (if any)
>   -     * returned by the called <code>Action</code>.
>   -     * <code>createActionForm</code> may be used to create an
>   -     * ActionForm instance to pass to the Action invoked.
>   -     *
>   -     * @param action The path to the Action to invoke
>   -     * @param form The ActionForm we are processing
>   -     * @param request The servlet request we are processing
>   -     * @param response The servlet response we are creating
>   -     *
>   -     * @exception IOException if an input/output error occurs
>   -     * @exception ServletException if a servlet exception occurs
>   -     * @since 1.1
>   -     */
>   -    public ActionForward invokeAction(
>   -            String path,
>   -            ActionForm form,
>   -            HttpServletRequest request,
>   -            HttpServletResponse response)
>   -        throws IOException, ServletException {
>   -
>   -        ActionMapping mapping =
>   -            processMapping(path,request);
>   -
>   -        Action action =
>   -            processActionCreate(mapping,request);
>   -
>   -        ActionForward forward = processActionPerform(
>   -            action,mapping,form,request,response);
>   -
>   -        return forward;
>   -
>   -    }

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>