husted      01/12/16 08:41:21

  Modified:    src/share/org/apache/struts/action ActionServlet.java
                        Action.java
  Added:       src/share/org/apache/struts/action ContextHelper.java
  Log:
  Add ContextHelper to action package, and
  corresponding support for the class to Action and ActionServlet.  See Bugzilla issue 
#5395.
  
  Revision  Changes    Path
  1.77      +305 -265  
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.76
  retrieving revision 1.77
  diff -u -r1.76 -r1.77
  --- ActionServlet.java        2001/10/07 04:48:08     1.76
  +++ ActionServlet.java        2001/12/16 16:41:21     1.77
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java,v 1.76 
2001/10/07 04:48:08 martinc Exp $
  - * $Revision: 1.76 $
  - * $Date: 2001/10/07 04:48:08 $
  + * $Header: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/action/ActionServlet.java,v 1.77 
2001/12/16 16:41:21 husted Exp $
  + * $Revision: 1.77 $
  + * $Date: 2001/12/16 16:41:21 $
    *
    * ====================================================================
    *
  @@ -165,6 +165,8 @@
    * <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>
  + * <li><strong>context</strong> - The request attribute name under which our
  + *     ContextHelper is stored.[org.apache.struts.action.CONTEXT_HELPER]</li>
    * <li><strong>debug</strong> - The debugging detail level for this
    *     servlet, which controls how much information is logged.  [0]</li>
    * <li><strong>detail</strong> - The debugging detail level for the Digester
  @@ -230,7 +232,8 @@
    * </ul>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.76 $ $Date: 2001/10/07 04:48:08 $
  + * @author Ted Husted
  + * @version $Revision: 1.77 $ $Date: 2001/12/16 16:41:21 $
    */
   
   public class ActionServlet
  @@ -267,6 +270,12 @@
   
   
       /**
  +     * The request attribute name for our ContextHelper object.
  +     */
  +    protected String contextHelper = Action.CONTEXT_HELPER_KEY;
  +
  +
  +    /**
        * The JDBC data sources that has been configured for this application,
        * if any, keyed by the servlet context attribute under which they are
        * stored.
  @@ -310,7 +319,7 @@
        * The Java class name of the ActionForward implementation class to use.
        */
       protected String forwardClass =
  -     "org.apache.struts.action.ActionForward";
  +    "org.apache.struts.action.ActionForward";
   
   
       /**
  @@ -342,7 +351,7 @@
        * The Java class name of our ActionMapping implementation class.
        */
       protected String mappingClass =
  -     "org.apache.struts.action.ActionMapping";
  +    "org.apache.struts.action.ActionMapping";
   
   
       /**
  @@ -398,22 +407,22 @@
        * 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", 
  +     * 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
  @@ -433,13 +442,13 @@
        */
       public void destroy() {
   
  -     if (debug >= 1)
  -         log(internal.getMessage("finalizing"));
  +    if (debug >= 1)
  +        log(internal.getMessage("finalizing"));
   
           destroyActions();
  -     destroyApplication();
  +    destroyApplication();
           destroyDataSources();
  -     destroyInternal();
  +    destroyInternal();
   
       }
   
  @@ -454,18 +463,18 @@
       public void init() throws ServletException {
   
           initActions();
  -     initInternal();
  -     initDebug();
  -     initApplication();
  -     try {
  -         initMapping();
  -     } catch (IOException e) {
  -         throw new UnavailableException
  -             (internal.getMessage("configIO", config));
  -     }
  +    initInternal();
  +    initDebug();
  +    initApplication();
  +    try {
  +        initMapping();
  +    } catch (IOException e) {
  +        throw new UnavailableException
  +        (internal.getMessage("configIO", config));
  +    }
           initUpload();
           initDataSources();
  -     initOther();
  +    initOther();
           initServlet();
   
       }
  @@ -481,10 +490,10 @@
        * @exception ServletException if a servlet exception occurs
        */
       public void doGet(HttpServletRequest request,
  -                   HttpServletResponse response)
  -     throws IOException, ServletException {
  +              HttpServletResponse response)
  +    throws IOException, ServletException {
   
  -     process(request, response);
  +    process(request, response);
   
       }
   
  @@ -499,10 +508,10 @@
        * @exception ServletException if a servlet exception occurs
        */
       public void doPost(HttpServletRequest request,
  -                    HttpServletResponse response)
  -     throws IOException, ServletException {
  +               HttpServletResponse response)
  +    throws IOException, ServletException {
   
  -     process(request, response);
  +    process(request, response);
   
       }
   
  @@ -545,7 +554,7 @@
        */
       public void addForward(ActionForward forward) {
   
  -     forwards.addForward(forward);
  +    forwards.addForward(forward);
   
       }
   
  @@ -573,7 +582,7 @@
           }
   
           // Add this mapping to our global collection
  -     mappings.addMapping(mapping);
  +    mappings.addMapping(mapping);
   
       }
   
  @@ -635,7 +644,7 @@
        */
       public ActionForward findForward(String name) {
   
  -     return (forwards.findForward(name));
  +    return (forwards.findForward(name));
   
       }
   
  @@ -648,15 +657,15 @@
        */
       public ActionMapping findMapping(String path) {
   
  -     return (mappings.findMapping(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
        */
       public int getBufferSize() {
  @@ -671,7 +680,7 @@
        */
       public int getDebug() {
   
  -     return (this.debug);
  +    return (this.debug);
   
       }
   
  @@ -693,7 +702,7 @@
        */
       public String getForwardClass() {
   
  -     return (this.forwardClass);
  +    return (this.forwardClass);
   
       }
   
  @@ -704,11 +713,11 @@
        */
       public String getMappingClass() {
   
  -     return (this.mappingClass);
  +    return (this.mappingClass);
   
       }
  -    
  -    
  +
  +
       /**
        * Get the maximum file size.  See {@link #setMaxFileSize(java.lang.String) 
setMaxFileSize}
        * for information on the number format used.
  @@ -716,10 +725,10 @@
       public String getMaxFileSize() {
           return maxFileSize;
       }
  -    
  +
       /**
        * Get the class name of the MultipartRequestHandler implementation
  -     * 
  +     *
        * @return A qualified classname of the MultipartRequestHandler implementation
        */
        public String getMultipartClass() {
  @@ -733,10 +742,10 @@
        */
       public MessageResources getResources() {
   
  -     return (application);
  +    return (application);
   
       }
  -    
  +
       /**
        * Get the directory used to temporarily store form files
        *
  @@ -815,7 +824,7 @@
        */
       public void removeForward(ActionForward forward) {
   
  -     forwards.removeForward(forward);
  +    forwards.removeForward(forward);
   
       }
   
  @@ -827,12 +836,12 @@
        */
       public void removeMapping(ActionMapping mapping) {
   
  -     mappings.removeMapping(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.
  @@ -883,7 +892,7 @@
           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",
  @@ -896,7 +905,7 @@
       public void setMaxFileSize(String maxFileSize) {
           this.maxFileSize = maxFileSize;
       }
  -    
  +
       /**
        * Set the class name of the MultipartRequestHandler implementation
        *
  @@ -905,8 +914,8 @@
       public void setMultipartClass(String multipartClass) {
           this.multipartClass = multipartClass;
       }
  +
   
  -    
       /**
        * Set the directory used to temporarily store files for MultipartRequestHandler
        * implementations that write to the disk
  @@ -943,9 +952,9 @@
        */
       protected void destroyApplication() {
   
  -     if (application != null)
  -         getServletContext().removeAttribute(Action.MESSAGES_KEY);
  -     application = null;
  +    if (application != null)
  +        getServletContext().removeAttribute(Action.MESSAGES_KEY);
  +    application = null;
   
       }
   
  @@ -983,7 +992,7 @@
        */
       protected void destroyInternal() {
   
  -     internal = null;
  +    internal = null;
   
       }
   
  @@ -1009,36 +1018,36 @@
        */
       protected void initApplication() throws ServletException {
   
  -     String value = getServletConfig().getInitParameter("application");
  -     if (value == null)
  -         return;
  +    String value = getServletConfig().getInitParameter("application");
  +    if (value == null)
  +        return;
           String factory =
               getServletConfig().getInitParameter("factory");
  -     if (debug >= 1)
  -         log(internal.getMessage("applicationLoading", value));
  -     try {
  +    if (debug >= 1)
  +        log(internal.getMessage("applicationLoading", value));
  +    try {
               String oldFactory =
  -                MessageResourcesFactory.getFactoryClass();      
  +                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);
  +        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);
   
       }
   
  @@ -1092,13 +1101,13 @@
        */
       protected void initDebug() throws ServletException {
   
  -     String value = getServletConfig().getInitParameter("debug");
  -     try {
  -         debug = Integer.parseInt(value);
  -     } catch (Throwable t) {
  -         debug = 0;
  -     }
  +    String value = getServletConfig().getInitParameter("debug");
  +    try {
  +        debug = Integer.parseInt(value);
  +    } catch (Throwable t) {
  +        debug = 0;
       }
  +    }
   
   
       /**
  @@ -1107,21 +1116,21 @@
        */
       protected Digester initDigester(int detail) {
   
  -     // Initialize a new Digester instance
  -     Digester digester = new Digester();
  -     digester.push(this);
  -     digester.setDebug(detail);
  +    // Initialize a new Digester instance
  +    Digester digester = new Digester();
  +    digester.push(this);
  +    digester.setDebug(detail);
           digester.setNamespaceAware(true);
  -     digester.setValidating(validating);
  +    digester.setValidating(validating);
   
  -     // Register our local copy of the DTDs that we can find
  +    // 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
  +    // Configure the processing rules
   
           digester.addObjectCreate("struts-config/data-sources/data-source",
                                    "org.apache.struts.util.GenericDataSource",
  @@ -1179,7 +1188,7 @@
               ("struts-config/global-forwards/forward/set-property",
                "property", "value");
   
  -     return (digester);
  +    return (digester);
   
       }
   
  @@ -1191,14 +1200,14 @@
        */
       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 + "'");
  -     }
  +    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 + "'");
  +    }
   
       }
   
  @@ -1211,76 +1220,76 @@
        */
       protected void initMapping() throws IOException, ServletException {
   
  -     String value = null;
  +    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 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");
  -     if (value != null) {
  -         if (value.equalsIgnoreCase("true") ||
  -             value.equalsIgnoreCase("yes"))
  -             validating = true;
  -         else
  -             validating = false;
  -     }
  +    // Initialize the validating XML parser flag
  +    value = getServletConfig().getInitParameter("validating");
  +    if (value != null) {
  +        if (value.equalsIgnoreCase("true") ||
  +            value.equalsIgnoreCase("yes"))
  +            validating = true;
  +        else
  +            validating = false;
  +    }
   
           // 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));
  +    // 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);
  +    // Build a digester to process our configuration resource
  +    Digester digester = initDigester(detail);
   
  -     // Parse the input stream to configure our mappings
  -     try {
  +    // Parse the input stream to configure our mappings
  +    try {
               formBeans.setFast(false);
               forwards.setFast(false);
               mappings.setFast(false);
  -         digester.parse(input);
  +        digester.parse(input);
               mappings.setFast(true);
               forwards.setFast(true);
               formBeans.setFast(true);
  -     } catch (SAXException e) {
  -         throw new ServletException
  -             (internal.getMessage("configParse", config), e);
  +    } catch (SAXException e) {
  +        throw new ServletException
  +        (internal.getMessage("configParse", config), e);
           } finally {
  -         input.close();
  -     }
  +        input.close();
  +    }
   
       }
   
  @@ -1293,13 +1302,17 @@
        */
       protected void initOther() throws ServletException {
   
  -     // Process the "content", "locale", and "nocache" parameters
  -     String value = null;
  +    // Process the "content", "locale", and "nocache" parameters
  +    String value = null;
   
           value = getServletConfig().getInitParameter("content");
           if (value != null)
               content = value;
   
  +        value = getServletConfig().getInitParameter("context");
  +        if (value != null)
  +            contextHelper = value;
  +
           value = getServletConfig().getInitParameter("locale");
           if (value != null) {
               if ("true".equalsIgnoreCase(value) ||
  @@ -1316,14 +1329,14 @@
                   nocache = true;
           }
   
  -     // Publish our internal collections as necessary
  +    // 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);
  +    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>
  @@ -1341,7 +1354,7 @@
           digester.setNamespaceAware(true);
           digester.setValidating(false);
   
  -     // Register our local copy of the DTDs that we can find
  +    // 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)
  @@ -1387,10 +1400,10 @@
        * @exception ServletException if there are invalid parameters
        */
       protected void initUpload() throws ServletException {
  -      
  +
           //buffer size
           String bufferValue = getServletConfig().getInitParameter("bufferSize");
  -        
  +
           if ((bufferValue != null) && (bufferValue.length() > 0)) {
               int oldBufferSize = bufferSize;
               try {
  @@ -1405,27 +1418,27 @@
                   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;
           }
  @@ -1443,12 +1456,15 @@
        * @exception ServletException if a servlet exception occurs
        */
       protected void process(HttpServletRequest request,
  -                        HttpServletResponse response)
  -     throws IOException, ServletException {
  +               HttpServletResponse response)
  +    throws IOException, ServletException {
  +
  +        // Insert ContextHelper object before processing request
  +        ContextHelper context = processContext(request,response);
   
           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
  @@ -1457,47 +1473,47 @@
               && (method.equals("POST"))) {
                   request = new MultipartRequestWrapper(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);
   
  +    // 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
  +    // Set the content type and no-caching headers if requested
           processContent(response);
  -     processNoCache(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;
  -     }
  +    // 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);
  +    // Process any ActionForm bean related to this request
  +    ActionForm formInstance = processActionForm(mapping, request);
           processPopulate(formInstance, mapping, request);
  -     if (!processValidate(mapping, formInstance, request, response))
  -         return;
  -        
  +    if (!processValidate(mapping, formInstance, request, response))
  +        return;
  +
           // Execute a forward if specified by this mapping
           if (!processForward(mapping, request, response))
               return;
  @@ -1515,7 +1531,7 @@
               return;
           }
   
  -     // Call the Action instance itself
  +    // Call the Action instance itself
           ActionForward forward =
               processActionPerform(actionInstance, mapping, formInstance,
                                    request, response);
  @@ -1587,10 +1603,10 @@
        * @param request The servlet request we are processing
        */
       protected ActionForm processActionForm(ActionMapping mapping,
  -                                        HttpServletRequest request) {
  +                           HttpServletRequest request) {
   
           // Is there a form bean associated with this mapping?
  -     String attribute = mapping.getAttribute();
  +    String attribute = mapping.getAttribute();
           if (attribute == null)
               return (null);
   
  @@ -1598,8 +1614,8 @@
           if (debug >= 1)
               log(" Looking for ActionForm bean under attribute '" +
                   attribute + "'");
  -     ActionForm instance = null;
  -     HttpSession session = null;
  +    ActionForm instance = null;
  +    HttpSession session = null;
           if ("request".equals(mapping.getScope())) {
               instance = (ActionForm) request.getAttribute(attribute);
           } else {
  @@ -1607,36 +1623,36 @@
               instance = (ActionForm) session.getAttribute(attribute);
           }
   
  -     // Determine the form bean class that we expect to use
  +    // 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
  +    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);
  -     }
  +    // 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();
  +        + 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);
  -     }
  +        log("Error creating ActionForm instance of class '" +
  +        className + "'", t);
  +    }
           if (instance == null)
               return (null);
   
  @@ -1672,30 +1688,37 @@
                                           ActionForm formInstance,
                                           HttpServletRequest request,
                                           HttpServletResponse response)
  -     throws IOException, ServletException {
  +    throws IOException, ServletException {
   
  -     if (forward != null) {
  -         String path = forward.getPath();
  -         if (forward.getRedirect()) {
  -             if (path.startsWith("/"))
  +    if (forward != null) {
  +        String path = forward.getPath();
  +        if (forward.getRedirect()) {
  +            if (path.startsWith("/"))
                       path = request.getContextPath() + path;
  -             response.sendRedirect(response.encodeRedirectURL(path));
  -         } else {
  -             RequestDispatcher rd =
  -                 getServletContext().getRequestDispatcher(path);
  +        response.sendRedirect(response.encodeRedirectURL(path));
  +        } 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);
  -         }
  -     }
   
  +        // Update ContextHelper object before forwarding request
  +        ContextHelper context = (ContextHelper)
  +            request.getAttribute(contextHelper);
  +        if (context!=null)
  +            context.setForward(forward);
  +
  +        rd.forward(request, response);
  +        }
       }
   
  +    }
   
  +
       /**
        * Ask the specified Action instance to handle this request.  Return
        * the <code>ActionForward</code> instance (if any) returned by
  @@ -1715,16 +1738,33 @@
                                           ActionForm formInstance,
                                           HttpServletRequest request,
                                           HttpServletResponse response)
  -     throws IOException, ServletException {
  +    throws IOException, ServletException {
   
  -     ActionForward forward =
  -         action.perform(mapping, formInstance, request, response);
  +    ActionForward forward =
  +        action.perform(mapping, formInstance, request, response);
           return (forward);
   
       }
   
   
       /**
  +     * Instantiate an ContextHelper object for this request.
  +     *
  +     * @param request The request we are processing
  +     * @param response The response we are processing
  +     */
  +    protected ContextHelper processContext(HttpServletRequest request,
  +            HttpServletResponse response) {
  +
  +        ContextHelper context =
  +            new ContextHelper(getServletContext(), request, response);
  +        request.setAttribute(contextHelper, context);
  +        return (context);
  +
  +    }
  +
  +
  +    /**
        * Set the default content type (with optional character encoding) for
        * all responses.  This value may be overridden by forwarded-to servlets
        * or JSP pages.
  @@ -1889,14 +1929,14 @@
        * @exception ServletException if a servlet exception occurs
        */
       protected void processNoCache(HttpServletResponse response)
  -     throws IOException, ServletException {
  +    throws IOException, ServletException {
   
  -     if (!nocache)
  -         return;
  +    if (!nocache)
  +        return;
   
  -     response.setHeader("Pragma", "No-cache");
  -     response.setHeader("Cache-Control", "no-cache");
  -     response.setDateHeader("Expires", 1);
  +    response.setHeader("Pragma", "No-cache");
  +    response.setHeader("Cache-Control", "no-cache");
  +    response.setDateHeader("Expires", 1);
   
       }
   
  @@ -1910,26 +1950,26 @@
        */
       protected String processPath(HttpServletRequest request) {
   
  -     String path = null;
  +    String path = null;
   
  -     // For prefix matching, we want to match on the path info (if any)
  +    // 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);
  +    if ((path != null) && (path.length() > 0))
  +        return (path);
   
  -     // For extension matching, we want to strip the extension (if any)
  +    // 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);
  +    int slash = path.lastIndexOf("/");
  +    int period = path.lastIndexOf(".");
  +    if ((period >= 0) && (period > slash))
  +        path = path.substring(0, period);
  +    return (path);
   
       }
   
  @@ -1974,7 +2014,7 @@
       protected void processPopulate(ActionForm formInstance,
                                      ActionMapping mapping,
                                      HttpServletRequest request)
  -     throws ServletException {
  +    throws ServletException {
   
           if (formInstance == null)
               return;
  @@ -2024,7 +2064,7 @@
               log(" Validating input form properties");
   
           // Was this submit cancelled?
  -     if ((request.getParameter(Constants.CANCEL_PROPERTY) != null) ||
  +    if ((request.getParameter(Constants.CANCEL_PROPERTY) != null) ||
               (request.getParameter(Constants.CANCEL_PROPERTY_X) != null)) {
               if (debug >= 1)
                   log("  Cancelled transaction, no validation");
  @@ -2042,19 +2082,19 @@
                   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();
           }
   
           // Has an input form been specified for this mapping?
  -     String uri = mapping.getInput();
  +    String uri = mapping.getInput();
           if (uri == null) {
               if (debug >= 1)
                   log("  No input form, but validation returned errors");
  @@ -2064,23 +2104,23 @@
               return (false);
           }
   
  -     // Save our error messages and return to the input form if possible
  -     if (debug >= 1)
  -         log("  Validation error(s), redirecting to: " + uri);
  -     request.setAttribute(Action.ERROR_KEY, errors);
  +    // Save our error messages and return to the input form if possible
  +    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);
  +    RequestDispatcher rd = getServletContext().getRequestDispatcher(uri);
           if (rd == null) {
               response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                                  internal.getMessage("requestDispatcher",
                                                      uri));
               return (false);
           }
  -     rd.forward(request, response);
  -     return (false);
  +    rd.forward(request, response);
  +    return (false);
   
       }
   
  
  
  
  1.26      +48 -40    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.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- Action.java       2001/08/16 03:52:09     1.25
  +++ Action.java       2001/12/16 16:41:21     1.26
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/action/Action.java,v 1.25 
2001/08/16 03:52:09 craigmcc Exp $
  - * $Revision: 1.25 $
  - * $Date: 2001/08/16 03:52:09 $
  + * $Header: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/action/Action.java,v 1.26 
2001/12/16 16:41:21 husted Exp $
  + * $Revision: 1.26 $
  + * $Date: 2001/12/16 16:41:21 $
    *
    * ====================================================================
    *
  @@ -108,7 +108,7 @@
    * by this Action.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.25 $ $Date: 2001/08/16 03:52:09 $
  + * @version $Revision: 1.26 $ $Date: 2001/12/16 16:41:21 $
    */
   
   public class Action {
  @@ -237,6 +237,14 @@
   
   
   
  +    /**
  +     * The request attributes key under which our ActionContext is
  +     * normally stored, unless overridden when initializing our ActionServlet.
  +     */
  +    public static final String CONTEXT_HELPER_KEY =
  +        "org.apache.struts.action.CONTEXT_HELPER";
  +
  +
       // ----------------------------------------------------- Instance Variables
   
   
  @@ -333,10 +341,10 @@
        * @exception ServletException if a servlet exception occurs
        */
       public ActionForward perform(ActionMapping mapping,
  -                              ActionForm form,
  -                              HttpServletRequest request,
  -                              HttpServletResponse response)
  -     throws IOException, ServletException {
  +                 ActionForm form,
  +                 HttpServletRequest request,
  +                 HttpServletResponse response)
  +    throws IOException, ServletException {
   
           return (null);  // Override this method to provide functionality
   
  @@ -370,8 +378,8 @@
           }
   
       }
  -    
   
  +
       /**
        * Return the user's currently selected Locale.
        *
  @@ -379,11 +387,11 @@
        */
       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);
   
       }
   
  @@ -393,7 +401,7 @@
        */
       protected MessageResources getResources() {
   
  -     return (servlet.getResources());
  +    return (servlet.getResources());
   
       }
   
  @@ -412,11 +420,11 @@
        */
       protected boolean isCancelled(HttpServletRequest request) {
   
  -     return ((request.getParameter(Constants.CANCEL_PROPERTY) != null) ||
  +    return ((request.getParameter(Constants.CANCEL_PROPERTY) != null) ||
                   (request.getParameter(Constants.CANCEL_PROPERTY_X) != null));
   
       }
  -    
  +
       /**
        * Return <code>true</code> if there is a transaction token stored in
        * the user's current session, and the value submitted as a request
  @@ -512,39 +520,39 @@
        * @param errors Error messages object
        */
       protected void saveErrors(HttpServletRequest request,
  -                           ActionErrors errors) {
  +                  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 
  +     * 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
  +     * @param request   The servlet request we are processing
  +     * @param messages  Messages object
        */
       protected void saveMessages(HttpServletRequest request,
  -                             ActionMessages messages) {
  +                    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);
   
       }
   
  @@ -573,10 +581,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.1                  
jakarta-struts/src/share/org/apache/struts/action/ContextHelper.java
  
  Index: ContextHelper.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/action/ContextHelper.java,v 1.1 
2001/12/16 16:41:21 husted Exp $
   * $Revision: 1.1 $
   * $Date: 2001/12/16 16:41:21 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Struts", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  
  
  package org.apache.struts.action;
  
  
  import java.util.Locale;
  import java.util.Iterator;
  import javax.servlet.ServletContext;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  import javax.servlet.http.HttpSession;
  import javax.sql.DataSource;
  import org.apache.struts.upload.MultipartRequestWrapper;
  import org.apache.struts.util.MessageResources;
  
  
  /**
   * NOTE: THIS CLASS IS UNDER ACTIVE DEVELOPMENT.
   * THE CURRENT CODE IS WRITTEN FOR CLARITY NOT EFFICIENCY.
   * NOT EVERY API FUNCTION HAS BEEN IMPLEMENTED YET.
   *
   * A helper object to expose the Struts shared resources,
   * which are be stored in the application, session, or
   * request contexts, as appropriate.
   *
   * An instance should be created for each request
   * processed. The  methods which return resources from
   * the request or session contexts are not thread-safe.
   *
   * Provided for use by other servlets in the application
   * so they can easily access the Struts shared resources.
   *
   * The resources are stored under attributes in the
   * application, session, or request contexts.
   *
   * The ActionConfig methods simply return the resources
   * from under the context and key used by the Struts
   * ActionServlet when the resources are created.
   *
   * @author Ted Husted
   * @version $Revision: 1.1 $ $Date: 2001/12/16 16:41:21 $
   */
  public class ContextHelper {
  
  
  // --------------------------------------------------------  Properites
  
  
      /**
       * The application associated with this instance.
       */
      private ServletContext application = null;
  
  
      /**
       * Set the application associated with this instance.
       * [servlet.getServletContext()]
       */
      public void setApplication(ServletContext application) {
          this.application = application;
      }
  
  
      /**
       * The session associated with this instance.
       */
      private HttpSession session = null;
  
  
      /**
       * Set the session associated with this instance.
       */
      public void setSession(HttpSession session) {
          this.session = session;
      }
  
  
      /**
       * The request associated with this instance.
       */
      private HttpServletRequest request = null;
  
  
      /**
       * Set the request associated with this object.
       * Session object is also set or cleared.
       */
      public void setRequest(HttpServletRequest request) {
          this.request = request;
          if (this.request==null)
              setSession(null);
          else
              setSession(this.request.getSession());
      }
  
  
      /**
       * The response associated with this instance.
       */
      private HttpServletResponse response = null;
  
  
      /**
       * Set the response associated with this isntance.
       * Session object is also set or cleared.
       */
      public void setResponse(HttpServletResponse response) {
          this.response = response;
      }
  
  
      /**
       * The forward associated with this instance.
       */
      private ActionForward forward = null;
  
  
      /**
       * Set the forward associated with this instance.
       */
      public void setForward(ActionForward forward) {
          this.forward = forward;
      }
  
  
      /**
       * Set the application and request for this object instance.
       * The ServletContext can be set by any servlet in the application.
       * The request should be the instant request.
       * Most of the other methods retrieve their own objects
       * by reference to the application, request, or session
       * attributes.
       * Do not call other methods without setting these first!
       * This is also called by the convenience constructor.
       *
       * @param application - The associated ServletContext.
       * @param request - The associated HTTP request.
       * @param response - The associated HTTP response.
       */
      public void setResources(ServletContext application,
          HttpServletRequest request, HttpServletResponse response) {
          setApplication(application);
          setRequest(request);
          setResponse(response);
      }
  
  
  // ------------------------------------------------ Application Context
  
      /**
       * The strong>default</strong>
       * configured data source (which must implement
       * <code>javax.sql.DataSource</code>),
       * if one is configured for this application.
       */
      public DataSource getDataSource() {
  
      if (this.application==null)
          return null;
      return (DataSource)
          this.application.getAttribute(Action.DATA_SOURCE_KEY);
  
      }
  
  
      public ActionMessages getActionMessages() {
  
          if (this.application==null)
              return null;
          return (ActionMessages)
              this.application.getAttribute(Action.MESSAGE_KEY);
  
      }
  
  
      /**
       * The <code>org.apache.struts.action.ActionFormBeans</code> collection
       * for this application.
       */
      public ActionFormBeans getActionFormBeans() {
  
          if (this.application==null)
              return null;
          return (ActionFormBeans)
              this.application.getAttribute(Action.FORM_BEANS_KEY);
  
      }
  
  
      /**
       * The <code>org.apache.struts.action.ActionForwards</code> collection
       * for this application.
       */
      public ActionForwards getActionForwards() {
  
          if (this.application==null)
              return null;
          return (ActionForwards)
              this.application.getAttribute(Action.FORWARDS_KEY);
  
      }
  
  
      /**
       * The context attributes key under which our
       * <code>org.apache.struts.action.ActionMappings</code> collection
       * is normally stored, unless overridden when initializing our
       * ActionServlet.
       */
      public ActionMappings getActionMappings() {
          if (this.application==null)
              return null;
          return (ActionMappings)
              this.application.getAttribute(Action.MAPPINGS_KEY);
      }
  
  
      /**
       * The application resources for this application.
       */
      public MessageResources getMessageResources() {
  
          if (this.application==null)
              return null;
          return (MessageResources)
              this.application.getAttribute(Action.MESSAGES_KEY);
  
      }
  
  
      /**
       * The path-mapped pattern (<code>/action/*</code>) or
       * extension mapped pattern ((<code>*.do</code>)
       * used to determine our Action URIs in this application.
       */
      public String getServletMapping() {
  
          if (this.application==null)
              return null;
          return (String)
              this.application.getAttribute(Action.SERVLET_KEY);
  
      }
  
  
  // ---------------------------------------------------- Session Context
  
  
      /**
       * The <code>java.util.Locale</code> for the user, if any.
       * If a default locale object is not in the user's session,
       * the system default locale is returned.
       * If used, the user locale is typically set during login
       * processing under the key <code>Action.LOCALE_KEY</code>.
       */
      public Locale getLocale() {
          Locale locale = null;
  
          if (session!=null)
              locale = (Locale) session.getAttribute(Action.LOCALE_KEY);
  
          if ((locale==null) && (request!=null))
              locale = request.getLocale();
  
          return locale;
      }
  
  
      /**
       * The transaction token stored in this session, if it is used.
       */
      public String getToken() {
  
          if (this.session==null) return null;
          return (String) session.getAttribute(Action.TRANSACTION_TOKEN_KEY);
  
      }
  
  
  // ---------------------------------------------------- Request Context
  
  
      /**
       * The <code>org.apache.struts.action.ActionErrors</code> object,
       * for this request.
       */
      public ActionErrors getActionErrors() {
  
          if (this.request==null)
              return null;
          return (ActionErrors)
              this.request.getAttribute(Action.ERROR_KEY);
  
      }
  
  
      /**
       * The runtime JspException that may be been thrown by a Struts tag
       * extension, or compatible presentation extension, and placed
       * in the request.
       */
      public Throwable getException() {
  
          if (this.request==null)
              return null;
          return (Throwable)
              this.request.getAttribute(Action.EXCEPTION_KEY);
  
      }
  
  
      /**
       * The multipart object for this request.
       */
      public MultipartRequestWrapper getMultipartRequestWrapper() {
  
          if (this.request==null)
              return null;
          return (MultipartRequestWrapper)
              this.request.getAttribute(Action.MULTIPART_KEY);
      }
  
  
     /**
       * The <code>org.apache.struts.ActionMapping</code>
       * instance for this request.
       */
      public ActionMapping getMapping() {
  
          if (this.request==null)
              return null;
          return (ActionMapping)
              this.request.getAttribute(Action.MAPPING_KEY);
  
      }
  
  
  
  // ---------------------------------------------------- Utility Methods
  
      /**
       * Return true if a message string for the specified message key
       * is present for the user's Locale.
       *
       * @param key Message key
       */
      public boolean isMessage(String key) {
  
          // Look up the requested MessageResources
          MessageResources resources = getMessageResources();
  
          if (resources == null) return false;
  
          // Return the requested message presence indicator
          return (resources.isPresent(getLocale(), key));
  
      }
  
  
      /*
       * 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>.
       *
       */
       public ActionForm getActionForm() {
  
          // Is there a mapping associated with this request?
          ActionMapping mapping = getMapping();
          if (mapping == null)
              return (null);
  
          // 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
          ActionForm instance = null;
          if ("request".equals(mapping.getScope())) {
              instance = (ActionForm) this.request.getAttribute(attribute);
          } else {
              instance = (ActionForm) this.session.getAttribute(attribute);
          }
  
          return instance;
      }
  
  
      /**
       * 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
       */
      public ActionFormBean getFormBean(String name) {
  
          ActionFormBeans formBeans = getActionFormBeans();
  
          if (formBeans==null)
              return null;
          return formBeans.findFormBean(name);
  
      }
  
  
      /**
       * Return the forwarding associated with the specified logical name,
       * if any; otherwise return <code>null</code>.
       *
       * @param name Logical name of the requested forwarding
       */
      public ActionForward getActionForward(String name) {
  
          ActionForwards forwards = getActionForwards();
  
          if (forwards==null)
              return null;
          return forwards.findForward(name);
  
      }
  
  
      /**
       * Return the mapping associated with the specified request path, if any;
       * otherwise return <code>null</code>.
       *
       * @param path Request path for which a mapping is requested
       */
      public ActionMapping getActionMapping(String path) {
  
          ActionMappings mappings = getActionMappings();
  
          if (mappings==null)
              return null;
          return mappings.findMapping(path);
  
      }
  
  
      /**
       * Return the form action converted into an action mapping path.  The
       * value of the <code>action</code> property is manipulated as follows in
       * computing the name of the requested mapping:
       * <ul>
       * <li>Any filename extension is removed (on the theory that extension
       *     mapping is being used to select the controller servlet).</li>
       * <li>If the resulting value does not start with a slash, then a
       *     slash is prepended.</li>
       * </ul>
       */
      protected String getActionMappingName(String action) {
  
          String value = action;
          int question = action.indexOf("?");
          if (question >= 0)
              value = value.substring(0, question);
          int slash = value.lastIndexOf("/");
          int period = value.lastIndexOf(".");
          if ((period >= 0) && (period > slash))
              value = value.substring(0, period);
          if (value.startsWith("/"))
              return (value);
          else
              return ("/" + value);
  
      }
  
  
      /**
       * Return the form action converted into a server-relative URL.
       */
      protected String getActionMappingURL(String action) {
  
          StringBuffer value = new StringBuffer(this.request.getContextPath());
  
          // Use our servlet mapping, if one is specified
          String servletMapping = getServletMapping();
  
          if (servletMapping != null) {
              String queryString = null;
              int question = action.indexOf("?");
              if (question >= 0)
                  queryString = action.substring(question);
              String actionMapping = getActionMappingName(action);
              if (servletMapping.startsWith("*.")) {
                  value.append(actionMapping);
                  value.append(servletMapping.substring(1));
              } else if (servletMapping.endsWith("/*")) {
                  value.append(servletMapping.substring
                               (0, servletMapping.length() - 2));
                  value.append(actionMapping);
              }
              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("/"))
                  value.append("/");
              value.append(action);
          }
  
          // Return the completed value
          return (value.toString());
  
      }
  
  
  
      /**
       * Return the url encoded to maintain the user session, if any.
       */
      protected String getEncodeURL(String url) {
  
          if ((session!=null) && (response != null)) {
  
              boolean redirect = false;
              if (forward!=null)
                  redirect = forward.redirect;
  
              if (redirect)
                  return response.encodeRedirectURL(url);
              else
                  return response.encodeURL(url);
          } else
              return (url);
      }
  
  
  
  // ------------------------------------------------ Presentation API
  
  
      /**
       * Renders the reference for a HTML <base> element
       *
       * @author Luis Arias <[EMAIL PROTECTED]>
       * @author Ted Husted
       */
      public String getOrigRef() {
  
   // HttpServletRequest request = (HttpServletRequest)pageContext.getRequest();
  
          if (request==null) return null;
  
          StringBuffer result = new StringBuffer();
          result.append(request.getScheme());
          result.append("://");
          result.append(request.getServerName());
          if ("http".equals(request.getScheme()) &&
              (80 == request.getServerPort())) {
              ;
          } else if ("https".equals(request.getScheme()) &&
                     (443 == request.getServerPort())) {
              ;
          } else {
              result.append(":");
              result.append(request.getServerPort());
          }
          result.append(request.getRequestURI());
  
          return result.toString();
      }
  
  
      /**
       * Renders the reference for a HTML <base> element
       *
       * @author Luis Arias <[EMAIL PROTECTED]>
       * @author Ted Husted
       */
      public String getBaseRef() {
  
          if (request==null) return null;
  
          StringBuffer result = new StringBuffer();
          result.append(request.getScheme());
          result.append("://");
          result.append(request.getServerName());
          if ("http".equals(request.getScheme()) &&
              (80 == request.getServerPort())) {
              ;
          } else if ("https".equals(request.getScheme()) &&
                     (443 == request.getServerPort())) {
              ;
          } else {
              result.append(":");
              result.append(request.getServerPort());
          }
          String path = null;
          if (forward==null)
              path = request.getRequestURI();
          else
              path = request.getContextPath() + forward.getPath();
          result.append(path);
  
          return result.toString();
      }
  
  
      /**
       * Return the path for the specified forward,
       * otherwise return <code>null</code>.
       *
       * @param name Name given to local or global forward.
       */
       public String getLink(String name) {
  
          ActionForward forward = getActionForward(name);
          if (forward == null)
              return null;
  
         StringBuffer path = new StringBuffer(this.request.getContextPath());
         path.append(forward.getPath());
  
         // :TODO: What about runtime parameters?
  
         return getEncodeURL( path.toString() );
  
      }
  
  
      /**
       * Wrapper for getLink(String)
       *
       * @param name Name given to local or global forward.
       */
      public String link(String name) {
          return getLink(name);
      }
  
  
      /**
       * Return the localized message for the specified key,
       * otherwise return <code>null</code>.
       *
       * @param key Message key
       */
      public String getMessage(String key) {
  
          MessageResources resources = getMessageResources();
          if (resources == null)
              return null;
          return resources.getMessage(getLocale(),key);
  
      }
  
      /**
       * Wrapper for getMessage(String)
       *
       * @param key Message key
       */
      public String message(String key) {
          return getMessage(key);
      }
  
  
      /**
       * Look up and return a message string, based on the specified parameters.
       *
       * @param key Message key to be looked up and returned
       * @param args Replacement parameters for this message
       */
      public String getMessage(String key, Object args[]) {
  
          MessageResources resources = getMessageResources();
  
          if (resources == null) return null;
  
          // Return the requested message
          if (args == null)
              return (resources.getMessage(getLocale(), key));
          else
              return (resources.getMessage(getLocale(), key, args));
  
      }
  
      /**
       * Wrapper for getMessage(String,Object[])
       *
       * @param key Message key to be looked up and returned
       * @param args Replacement parameters for this message
       */
      public String message(String key, Object args[]) {
          return getMessage(key, args);
      }
  
  
      /**
       * Return the URL for the specified ActionMapping,
       * otherwise return <code>null</code>.
       *
       * @param name Name given to local or global forward.
       */
      public String getAction(String path) {
  
          return getEncodeURL( getActionMappingURL(path) );
  
      }
  
  
      /**
       * Wrapper for getAction(String)
       *
       * @param name Name given to local or global forward.
       */
      public String action(String path) {
          return getAction(path);
      }
  
  
      /**
       * Return the number of error messages.
       */
      public int getErrorSize() {
  
          ActionErrors actionErrors = getActionErrors();
  
          if (actionErrors == null)
              return 0;
  
          return actionErrors.size();
      }
  
      /**
       * Alias for getErrorSize()
       */
      public int errorSize() {
          return getErrorSize();
      }
  
  
      /**
       * Return true if there are no errors queued
       */
      public boolean getErrorsEmpty() {
  
          ActionErrors actionErrors = getActionErrors();
  
          if (actionErrors == null)
              return false;
  
          return actionErrors.empty();
      }
  
      /**
       * Wrapper for getErrorEmpty()
       */
      public boolean errorsEmpty() {
          return getErrorsEmpty();
      }
  
  
      /**
       * Return the error messages
       */
      public Iterator getErrors() {
  
          ActionErrors actionErrors = getActionErrors();
  
          if (actionErrors == null)
              return null;
  
          return actionErrors.get();
      }
  
      /**
       * Wrapper for getErrors()
       */
      public Iterator errors() {
          return errors();
      }
  
  
      /**
       * Return an ActionError for a property
       *
       * @param property Property name
       */
      public Iterator getErrors(String property) {
  
          ActionErrors actionErrors = getActionErrors();
  
          if (actionErrors == null)
              return null;
  
          return actionErrors.get(property);
      }
  
      /**
       * Wrapper for getErrors(String)
       */
      public Iterator errors(String property) {
          return getErrors(property);
      }
  
  
      /**
       * Return the number of error messages.
       *
       * @param property Property name
       */
      public int getErrorSize(String property) {
  
          ActionErrors actionErrors = getActionErrors();
  
          if (actionErrors == null)
              return 0;
  
          return actionErrors.size(property);
      }
  
      /**
       * Wrapper for getErrorSize(String)
       *
       * @param property Property name
       */
      public int errorSize(String property) {
          return getErrorSize(property);
      }
  
  
      /**
       * Returns the errors.header, any errors, and the errors.footer.
       *
       * @param property Property name
       */
      public String getErrorOutput(String property) {
  
          ActionErrors errors = getActionErrors();
  
          if ((errors==null) || (errors.empty()))
              return null;
  
          // Check for presence of header and footer message keys
          boolean headerPresent = isMessage("errors.header");
          boolean footerPresent = isMessage("errors.footer");
  
          // Render the error messages appropriately
          StringBuffer results = new StringBuffer();
          String message = null;
          if (headerPresent)
              message = getMessage("errors.header");
          Iterator reports = null;
  
          if (property == null)
              reports = errors.get();
          else
              reports = errors.get(property);
  
         // Render header if this is a global tag or there is an error for this 
property
         boolean propertyMsgPresent = reports.hasNext();
         if ((message != null)&&(property == null) || propertyMsgPresent) {
             results.append(message);
             results.append("\r\n");
         }
  
          while (reports.hasNext()) {
              ActionError report = (ActionError) reports.next();
              message = getMessage( report.getKey(),
                  report.getValues());
              if (message != null) {
                  results.append(message);
                  results.append("\r\n");
              }
          }
          message = null;
          if (footerPresent)
              message = getMessage("errors.footer");
  
          if ((message != null)&&(property == null) || propertyMsgPresent) {
              results.append(message);
              results.append("\r\n");
          }
  
          // return result
          return results.toString();
  
      }
  
      /**
       * Wrapper for getErrorMarkup(String)
       */
      public String errorOutput(String property) {
          return getErrorOutput(property);
      }
  
      /**
       * Wrapper for getErrorMarkup(null)
       */
      public String getErrorMarkup() {
          return getErrorOutput((String) null);
      }
  
      /**
       * Wrapper for getErrorMarkup()
       */
      public String errorMarkup() {
          return getErrorMarkup();
      }
  
  
  // ------------------------------------------------------- Constructors
  
  
      public ContextHelper() {
          super();
      }
  
  
      public ContextHelper(
              ServletContext application,
              HttpServletRequest request,
              HttpServletResponse response) {
          super();
          setResources(application,request,response);
      }
  
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to