craigmcc    01/05/09 12:31:33

  Modified:    doc      struts-bean.xml struts-html.xml struts-logic.xml
               src/share/org/apache/struts/taglib/bean IncludeTag.java
                        LocalStrings.properties
               src/share/org/apache/struts/taglib/html LinkTag.java
                        LocalStrings.properties RewriteTag.java
               src/share/org/apache/struts/taglib/logic
                        LocalStrings.properties RedirectTag.java
               src/share/org/apache/struts/util LocalStrings.properties
                        RequestUtils.java
  Log:
  Refactor the hyperlink-generation code used in the <bean:include>,
  <html:link>, <html:rewrite>, and <logic:redirect> tags to use common
  utility methods based on URLs rather than Strings.  This will ensure
  consistency in implementation, and make it easy to provide full
  URL-processing functionality to other tags as necessary.
  
  Revision  Changes    Path
  1.4       +22 -0     jakarta-struts/doc/struts-bean.xml
  
  Index: struts-bean.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/doc/struts-bean.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- struts-bean.xml   2001/04/22 00:46:19     1.3
  +++ struts-bean.xml   2001/05/09 19:31:00     1.4
  @@ -353,6 +353,17 @@
       </info>
   
       <attribute>
  +      <name>anchor</name>
  +      <required>false</required>
  +      <rtexprvalue>true</rtexprvalue>
  +      <info>
  +      <p>Optional anchor tag ("#xxx") to be added to the generated
  +      hyperlink.  Specify this value <strong>without</strong> any
  +      "#" character.</p>
  +      </info>
  +    </attribute>
  +
  +    <attribute>
         <name>forward</name>
         <required>false</required>
         <rtexprvalue>true</rtexprvalue>
  @@ -404,6 +415,17 @@
         <info>
         <p>Context-relative URI (starting with a '/') of the web application
         resource to be included.</p>
  +      </info>
  +    </attribute>
  +
  +    <attribute>
  +      <name>transaction</name>
  +      <required>false</required>
  +      <rtexprvalue>true</rtexprvalue>
  +      <info>
  +        <p>Set to <code>true</code> if you want the current
  +        transaction control token included in the generated
  +        URL for this include.</p>
         </info>
       </attribute>
   
  
  
  
  1.9       +81 -6     jakarta-struts/doc/struts-html.xml
  
  Index: struts-html.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/doc/struts-html.xml,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- struts-html.xml   2001/05/05 00:59:50     1.8
  +++ struts-html.xml   2001/05/09 19:31:01     1.9
  @@ -3704,6 +3704,17 @@
                   </info>
   
                   <attribute>
  +                  <name>anchor</name>
  +                  <required>false</required>
  +                  <rtexprvalue>true</rtexprvalue>
  +                  <info>
  +                  <p>Optional anchor tag ("#xxx") to be added to the generated
  +                  hyperlink.  Specify this value <strong>without</strong> any
  +                  "#" character.</p>
  +                  </info>
  +                </attribute>
  +
  +                <attribute>
                     <name>forward</name>
                     <required>false</required>
                     <rtexprvalue>true</rtexprvalue>
  @@ -3735,6 +3746,19 @@
                   </attribute>
   
                   <attribute>
  +                  <name>name</name>
  +                  <required>false</required>
  +                  <rtexprvalue>true</rtexprvalue>
  +                  <info>
  +                  <p>The name of a JSP bean that contains a <code>Map</code>
  +                  representing the query parameters (if <code>property</code>
  +                  is not specified), or a JSP bean whose property getter is
  +                  called to return a <code>Map</code> (if <code>property</code>
  +                  is specified).</p>
  +                  </info>
  +                </attribute>
  +
  +                <attribute>
                     <name>page</name>
                     <required>false</required>
                     <rtexprvalue>true</rtexprvalue>
  @@ -3751,15 +3775,54 @@
                   </attribute>
   
                   <attribute>
  -                  <name>name</name>
  +                  <name>paramId</name>
                     <required>false</required>
                     <rtexprvalue>true</rtexprvalue>
                     <info>
  -                  <p>The name of a JSP bean that contains a <code>Map</code>
  -                  representing the query parameters (if <code>property</code>
  -                  is not specified), or a JSP bean whose property getter is
  -                  called to return a <code>Map</code> (if <code>property</code>
  -                  is specified).</p>
  +                  <p>The name of the request parameter that will be dynamically
  +                  added to the generated hyperlink.  The corresponding value is
  +                  defined by the <code>paramName</code> and (optional)
  +                  <code>paramProperty</code> attributes, optionally scoped by
  +                  the <code>paramScope</code> attributel</p>
  +                  </info>
  +                </attribute>
  +
  +                <attribute>
  +                  <name>paramName</name>
  +                  <required>false</required>
  +                  <rtexprvalue>true</rtexprvalue>
  +                  <info>
  +                  <p>The name of a JSP bean that is a String containing the
  +                  value for the request parameter named by <code>paramId</code>
  +                  (if <code>paramProperty</code> is not specified), or a JSP
  +                  bean whose property getter is called to return a String
  +                  (if <code>paramProperty</code> is specified).  The JSP bean
  +                  is constrained to the bean scope specified by the
  +                  <code>paramScope</code> property, if it is specified.</p>
  +                  </info>
  +                </attribute>
  +
  +                <attribute>
  +                  <name>paramProperty</name>
  +                  <required>false</required>
  +                  <rtexprvalue>true</rtexprvalue>
  +                  <info>
  +                  <p>The name of a property of the bean specified by the
  +                  <code>paramName</code> attribute, whose return value must
  +                  be a String containing the value of the request parameter
  +                  (named by the <code>paramId</code> attribute) that will be
  +                  dynamically added to this hyperlink.</p>
  +                  </info>
  +                </attribute>
  +
  +                <attribute>
  +                  <name>paramScope</name>
  +                  <required>false</required>
  +                  <rtexprvalue>true</rtexprvalue>
  +                  <info>
  +                  <p>The scope within which to search for the bean specified
  +                  by the <code>paramName</code> attribute.  If not specified,
  +                  all scopes are searched.</p>
                     </info>
                   </attribute>
   
  @@ -3785,6 +3848,18 @@
                     <p>The scope within which to search for the bean specified
                     by the <code>name</code> attribute.  If not specified, all
                     scopes are searched.</p>
  +                  </info>
  +                </attribute>
  +
  +                <attribute>
  +                  <name>transaction</name>
  +                  <required>false</required>
  +                  <rtexprvalue>true</rtexprvalue>
  +                  <info>
  +                  <p>If set to <code>true</code>, any current transaction
  +                  control token will be included in the generated hyperlink,
  +                  so that it will pass an <code>isTokenValid()</code> test
  +                  in the receiving Action.</p>
                     </info>
                   </attribute>
   
  
  
  
  1.6       +22 -0     jakarta-struts/doc/struts-logic.xml
  
  Index: struts-logic.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-struts/doc/struts-logic.xml,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- struts-logic.xml  2001/04/19 21:25:04     1.5
  +++ struts-logic.xml  2001/05/09 19:31:02     1.6
  @@ -1318,6 +1318,17 @@
                   </info>
   
                   <attribute>
  +                  <name>anchor</name>
  +                  <required>false</required>
  +                  <rtexprvalue>true</rtexprvalue>
  +                  <info>
  +                  <p>Optional anchor tag ("#xxx") to be added to the generated
  +                  hyperlink.  Specify this value <strong>without</strong> any
  +                  "#" character.</p>
  +                  </info>
  +                </attribute>
  +
  +                <attribute>
                     <name>forward</name>
                     <required>false</required>
                     <rtexprvalue>true</rtexprvalue>
  @@ -1451,6 +1462,17 @@
                     <p>The scope within which to search for the bean specified
                     by the <code>name</code> attribute.  If not specified, all
                     scopes are searched.</p>
  +                  </info>
  +                </attribute>
  +
  +                <attribute>
  +                  <name>transaction</name>
  +                  <required>false</required>
  +                  <rtexprvalue>true</rtexprvalue>
  +                  <info>
  +                    <p>Set to <code>true</code> if you want the current
  +                    transaction control token included in the generated
  +                    URL for this redirect.</p>
                     </info>
                   </attribute>
   
  
  
  
  1.13      +46 -117   
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.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- IncludeTag.java   2001/05/09 04:42:10     1.12
  +++ IncludeTag.java   2001/05/09 19:31:10     1.13
  @@ -1,5 +1,5 @@
   /*
  - * $Id: IncludeTag.java,v 1.12 2001/05/09 04:42:10 craigmcc Exp $
  + * $Id: IncludeTag.java,v 1.13 2001/05/09 19:31:10 craigmcc Exp $
    * ====================================================================
    *
    * The Apache Software License, Version 1.1
  @@ -66,6 +66,7 @@
   import java.net.MalformedURLException;
   import java.net.URL;
   import java.net.URLConnection;
  +import java.util.Map;
   import javax.servlet.ServletContext;
   import javax.servlet.http.HttpServletRequest;
   import javax.servlet.http.HttpServletResponse;
  @@ -91,7 +92,7 @@
    * wrapped response passed to RequestDispatcher.include().
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.12 $ $Date: 2001/05/09 04:42:10 $
  + * @version $Revision: 1.13 $ $Date: 2001/05/09 19:31:10 $
    */
   
   public class IncludeTag extends TagSupport {
  @@ -107,6 +108,20 @@
   
   
       /**
  +     * The anchor to be added to the end of the generated hyperlink.
  +     */
  +    protected String anchor = null;
  +
  +    public String getAnchor() {
  +        return (this.anchor);
  +    }
  +
  +    public void setAnchor(String anchor) {
  +        this.anchor = anchor;
  +    }
  +
  +
  +    /**
        * The name of the global <code>ActionForward</code> that contains a
        * path to our requested resource.
        */
  @@ -183,6 +198,20 @@
       }
   
   
  +    /**
  +     * Include transaction token (if any) in the hyperlink?
  +     */
  +    protected boolean transaction = false;
  +
  +    public boolean getTransaction() {
  +        return (this.transaction);
  +    }
  +
  +    public void setTransaction(boolean transaction) {
  +        this.transaction = transaction;
  +    }
  +
  +
       // --------------------------------------------------------- Public Methods
   
   
  @@ -195,7 +224,19 @@
       public int doStartTag() throws JspException {
   
        // Set up a URLConnection to read the requested resource
  -        URL url = hyperlink();
  +        Map params = RequestUtils.computeParameters
  +            (pageContext, null, null, null, null,
  +             null, null, null, transaction); // FIXME - <html:link> attributes
  +        URL url = null;
  +        try {
  +            url = RequestUtils.computeURL(pageContext, forward, href,
  +                                          page, params, anchor, false);
  +        } catch (MalformedURLException e) {
  +            RequestUtils.saveException(pageContext, e);
  +            throw new JspException
  +                (messages.getMessage("include.url", e.toString()));
  +        }
  +
        URLConnection conn = null;
        try {
            conn = url.openConnection();
  @@ -247,124 +288,12 @@
       public void release() {
   
           super.release();
  +        anchor = null;
           forward = null;
           href = null;
           id = null;
           page = null;
  -
  -    }
  -
  -
  -    // ------------------------------------------------------ Protected Methods
  -
  -
  -    /**
  -     * Return a URL to the requested resource, modified to include the session
  -     * identifier if necessary.
  -     *
  -     * @exception JspException if an error occurs preparing the hyperlink
  -     */
  -    protected URL hyperlink() throws JspException {
  -
  -        // Validate the number of href specifiers that were specified
  -        int n = 0;
  -        if (forward != null)
  -            n++;
  -        if (href != null)
  -            n++;
  -        if (page != null)
  -            n++;
  -        if (n != 1) {
  -            JspException e = new JspException
  -                (messages.getMessage("include.destination"));
  -            RequestUtils.saveException(pageContext, e);
  -            throw e;
  -        }
  -
  -        // Calculate the appropriate hyperlink
  -        String href = null;
  -        boolean includeSession = true;
  -        if (this.forward != null) {
  -            ActionForwards forwards = (ActionForwards)
  -                pageContext.getAttribute(Action.FORWARDS_KEY,
  -                                         PageContext.APPLICATION_SCOPE);
  -            if (forwards == null) {
  -                JspException e = new JspException
  -                    (messages.getMessage("include.forwards"));
  -                RequestUtils.saveException(pageContext, e);
  -                throw e;
  -            }
  -            ActionForward forward = forwards.findForward(this.forward);
  -            if (forward == null) {
  -                JspException e = new JspException
  -                    (messages.getMessage("include.forward", this.forward));
  -                RequestUtils.saveException(pageContext, e);
  -                throw e;
  -            }
  -            HttpServletRequest request =
  -                (HttpServletRequest) pageContext.getRequest();
  -            try {
  -                href = RequestUtils.absoluteURL(request, forward.getPath());
  -            } catch (MalformedURLException mue) {
  -                RequestUtils.saveException(pageContext, mue);
  -                ServletContext sc = pageContext.getServletContext();
  -                sc.log(messages.getMessage("include.url",
  -                                           request.getScheme(),
  -                                           request.getServerName(),
  -                                           "" + request.getServerPort(),
  -                                           forward.getPath()),
  -                       mue);
  -                JspException e = new JspException
  -                    (messages.getMessage("include.url",
  -                                         request.getScheme(),
  -                                         request.getServerName(),
  -                                         "" + request.getServerPort(),
  -                                         forward.getPath()));
  -                throw e;
  -            }
  -        } else if (this.href != null) {
  -            href = this.href;
  -            includeSession = false;
  -        } else /* if (this.page != null) */ {
  -            HttpServletRequest request =
  -                (HttpServletRequest) pageContext.getRequest();
  -            try {
  -                href = RequestUtils.absoluteURL(request, this.page);
  -            } catch (MalformedURLException mue) {
  -                RequestUtils.saveException(pageContext, mue);
  -                ServletContext sc = pageContext.getServletContext();
  -                sc.log(messages.getMessage("include.url",
  -                                           request.getScheme(),
  -                                           request.getServerName(),
  -                                           "" + request.getServerPort(),
  -                                           this.page),
  -                       mue);
  -                JspException e = new JspException
  -                    (messages.getMessage("include.url",
  -                                         request.getScheme(),
  -                                         request.getServerName(),
  -                                         "" + request.getServerPort(),
  -                                         this.page));
  -                throw e;
  -            }
  -        }
  -
  -        // Append the session identifier if appropriate
  -        if (includeSession) {
  -            HttpServletResponse response =
  -                (HttpServletResponse) pageContext.getResponse();
  -            href = response.encodeURL(href);
  -        }
  -
  -        // Convert the hyperlink to a URL
  -        try {
  -            return (new URL(href));
  -        } catch (MalformedURLException e) {
  -            RequestUtils.saveException(pageContext, e);
  -            JspException f = new JspException
  -                (messages.getMessage("include.malformed", href));
  -            throw f;
  -        }
  +        transaction = false;
   
       }
   
  
  
  
  1.12      +1 -1      
jakarta-struts/src/share/org/apache/struts/taglib/bean/LocalStrings.properties
  
  Index: LocalStrings.properties
  ===================================================================
  RCS file: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/bean/LocalStrings.properties,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- LocalStrings.properties   2001/05/03 03:29:36     1.11
  +++ LocalStrings.properties   2001/05/09 19:31:11     1.12
  @@ -6,7 +6,7 @@
   include.malformed=Cannot create URL for {0}
   include.open=Exception opening resource {0}: {1}
   include.read=Exception reading resource {0}: {1}
  -include.url=Cannot create URL with scheme={0} server={1} port={2} path={3}
  +include.url=Cannot create include URL: {0}
   message.message=Missing message for key {0}
   message.resources=Missing resources attribute {0}
   page.selector=Invalid page context selector {0}
  
  
  
  1.13      +30 -127   
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.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- LinkTag.java      2001/05/03 03:29:36     1.12
  +++ LinkTag.java      2001/05/09 19:31:15     1.13
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/LinkTag.java,v 1.12 
2001/05/03 03:29:36 craigmcc Exp $
  - * $Revision: 1.12 $
  - * $Date: 2001/05/03 03:29:36 $
  + * $Header: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/LinkTag.java,v 1.13 
2001/05/09 19:31:15 craigmcc Exp $
  + * $Revision: 1.13 $
  + * $Date: 2001/05/09 19:31:15 $
    *
    * ====================================================================
    *
  @@ -66,6 +66,7 @@
   import java.io.IOException;
   import java.lang.reflect.InvocationTargetException;
   import java.net.MalformedURLException;
  +import java.net.URL;
   import java.net.URLEncoder;
   import java.util.Iterator;
   import java.util.Map;
  @@ -88,7 +89,7 @@
    * Generate a URL-encoded hyperlink to the specified URI.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.12 $ $Date: 2001/05/03 03:29:36 $
  + * @version $Revision: 1.13 $ $Date: 2001/05/09 19:31:15 $
    */
   
   public class LinkTag extends BaseHandlerTag {
  @@ -320,21 +321,32 @@
        */
       public int doStartTag() throws JspException {
   
  -     // Generate the name definition or hyperlink element
  -     HttpServletResponse response =
  -       (HttpServletResponse) pageContext.getResponse();
  -     StringBuffer results = new StringBuffer("<a");
  -        String hyperlink = hyperlink();
  -        if (hyperlink != null) {
  -            results.append(" href=\"");
  -            results.append(response.encodeURL(hyperlink));
  -            results.append("\"");
  -        }
  +        // Special case for name anchors
           if (linkName != null) {
  -            results.append(" name=\"");
  +            StringBuffer results = new StringBuffer("<a name=\"");
               results.append(linkName);
  -            results.append("\"");
  +            results.append("\">");
  +            return (EVAL_BODY_TAG);
  +        }
  +
  +     // Generate the hyperlink URL
  +        Map params = RequestUtils.computeParameters
  +            (pageContext, paramId, paramName, paramProperty, paramScope,
  +             name, property, scope, transaction);
  +        URL url = null;
  +        try {
  +            url = RequestUtils.computeURL(pageContext, forward, href,
  +                                          page, params, anchor, false);
  +        } catch (MalformedURLException e) {
  +            RequestUtils.saveException(pageContext, e);
  +            throw new JspException
  +                (messages.getMessage("rewrite.url", e.toString()));
           }
  +
  +        // Generate the opening anchor element
  +        StringBuffer results = new StringBuffer("<a href=\"");
  +        results.append(url.toString());
  +        results.append("\"");
        if (target != null) {
            results.append(" target=\"");
            results.append(target);
  @@ -418,118 +430,9 @@
   
       }
   
  -
  -    // ------------------------------------------------------ Protected Methods
   
  +    /*
   
  -    /**
  -     * Return the specified hyperlink, modified as necessary with optional
  -     * request parameters.  Return <code>null</code> if we are generating
  -     * a name anchor rather than a hyperlink.
  -     *
  -     * @exception JspException if an error occurs preparing the hyperlink
  -     */
  -    protected String hyperlink() throws JspException {
  -
  -        if (linkName != null)
  -            return (null);      // We are not generating a hyperlink
  -
  -        // Validate the number of href specifiers that were specified
  -        int n = 0;
  -        if (forward != null)
  -            n++;
  -        if (href != null)
  -            n++;
  -        if (linkName != null)
  -            n++;
  -        if (page != null)
  -            n++;
  -        if (n != 1) {
  -            JspException e = new JspException
  -                (messages.getMessage("linkTag.destination"));
  -            RequestUtils.saveException(pageContext, e);
  -            throw e;
  -        }
  -
  -        // Start with an unadorned "href"
  -     String href = null;
  -
  -        // If "href" was specified, use it as is
  -        if (this.href != null) {
  -            href = this.href;
  -        }
  -
  -     // If "forward" was specified, compute the "href" to forward to
  -     else if (forward != null) {
  -         ActionForwards forwards = (ActionForwards)
  -             pageContext.getAttribute(Action.FORWARDS_KEY,
  -                                      PageContext.APPLICATION_SCOPE);
  -         if (forwards == null) {
  -                JspException e = new JspException
  -                 (messages.getMessage("linkTag.forwards"));
  -                RequestUtils.saveException(pageContext, e);
  -                throw e;
  -            }
  -         ActionForward forward = forwards.findForward(this.forward);
  -         if (forward == null) {
  -                JspException e = new JspException
  -                 (messages.getMessage("linkTag.forward"));
  -                RequestUtils.saveException(pageContext, e);
  -                throw e;
  -            }
  -         HttpServletRequest request =
  -             (HttpServletRequest) pageContext.getRequest();
  -            try {
  -                href = RequestUtils.absoluteURL(request, forward.getPath());
  -            } catch (MalformedURLException mue) {
  -                RequestUtils.saveException(pageContext, mue);
  -                ServletContext sc = pageContext.getServletContext();
  -                sc.log(messages.getMessage("linkTag.url",
  -                                           request.getScheme(),
  -                                           request.getServerName(),
  -                                           "" + request.getServerPort(),
  -                                           forward.getPath()),
  -                       mue);
  -                JspException e = new JspException
  -                    (messages.getMessage("linkTag.url",
  -                                         request.getScheme(),
  -                                         request.getServerName(),
  -                                         "" + request.getServerPort(),
  -                                         forward.getPath()));
  -                throw e;
  -            }
  -     }
  -
  -        // If "linkName" was specified, return null (not making an href)
  -        else if (linkName != null) {
  -            return (null);
  -        }
  -
  -        // If "page" was specified, compute the "href" to forward to
  -        else if (page != null) {
  -            HttpServletRequest request =
  -                (HttpServletRequest) pageContext.getRequest();
  -            try {
  -                href = RequestUtils.absoluteURL(request, page);
  -            } catch (MalformedURLException mue) {
  -                RequestUtils.saveException(pageContext, mue);
  -                ServletContext sc = pageContext.getServletContext();
  -                sc.log(messages.getMessage("linkTag.url",
  -                                           request.getScheme(),
  -                                           request.getServerName(),
  -                                           "" + request.getServerPort(),
  -                                           page),
  -                       mue);
  -                JspException e = new JspException
  -                    (messages.getMessage("linkTag.url",
  -                                         request.getScheme(),
  -                                         request.getServerName(),
  -                                         "" + request.getServerPort(),
  -                                         page));
  -                throw e;
  -            }
  -        }
  -
           // Save any currently specified anchor string
           String anchor = this.anchor;
           int hash = href.indexOf('#');
  @@ -652,7 +555,7 @@
        // Return the final result
        return (sb.toString());
   
  -    }
  +    */
   
   
   }
  
  
  
  1.9       +2 -1      
jakarta-struts/src/share/org/apache/struts/taglib/html/LocalStrings.properties
  
  Index: LocalStrings.properties
  ===================================================================
  RCS file: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/LocalStrings.properties,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- LocalStrings.properties   2001/05/03 03:29:37     1.8
  +++ LocalStrings.properties   2001/05/09 19:31:17     1.9
  @@ -27,7 +27,7 @@
   linkTag.forwards=Cannot locate forwards mapping table
   linkTag.type=Object must be of type Map
   linkTag.type1=Object must be of type Dictionary
  -linkTag.url=Cannot create URL with scheme={0} server={1} port={2} path={3}
  +linkTag.url=Cannot create link URL: {0}
   messageTag.message=Missing message for key {0}
   messageTag.resources=Missing resources attribute {0}
   multiboxTag.value=You must specify the value attribute or nested tag content
  @@ -35,3 +35,4 @@
   optionsTag.enumeration=Cannot create enumeration for {0}
   optionsTag.iterator=Cannot create iterator for {0}
   optionsTag.select=Options tag must be nested in a Select tag
  +rewrite.url=Cannot create rewrite URL: {0}
  
  
  
  1.5       +21 -10    
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.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- RewriteTag.java   2001/04/29 00:38:04     1.4
  +++ RewriteTag.java   2001/05/09 19:31:18     1.5
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/RewriteTag.java,v 1.4 
2001/04/29 00:38:04 craigmcc Exp $
  - * $Revision: 1.4 $
  - * $Date: 2001/04/29 00:38:04 $
  + * $Header: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/html/RewriteTag.java,v 1.5 
2001/05/09 19:31:18 craigmcc Exp $
  + * $Revision: 1.5 $
  + * $Date: 2001/05/09 19:31:18 $
    *
    * ====================================================================
    *
  @@ -65,6 +65,8 @@
   
   import java.io.IOException;
   import java.lang.reflect.InvocationTargetException;
  +import java.net.MalformedURLException;
  +import java.net.URL;
   import java.net.URLEncoder;
   import java.util.Iterator;
   import java.util.Map;
  @@ -78,6 +80,7 @@
   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;
   
   
  @@ -85,7 +88,7 @@
    * Generate a URL-encoded URI as a string.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.4 $ $Date: 2001/04/29 00:38:04 $
  + * @version $Revision: 1.5 $ $Date: 2001/05/09 19:31:18 $
    */
   
   public class RewriteTag extends LinkTag {
  @@ -101,14 +104,22 @@
        */
       public int doStartTag() throws JspException {
   
  -     // Generate the hyperlink start element
  -     HttpServletResponse response =
  -       (HttpServletResponse) pageContext.getResponse();
  -        StringBuffer results = new StringBuffer();
  -     results.append(response.encodeURL(hyperlink()));
  +     // Generate the hyperlink URL
  +        Map params = RequestUtils.computeParameters
  +            (pageContext, paramId, paramName, paramProperty, paramScope,
  +             name, property, scope, transaction);
  +        URL url = null;
  +        try {
  +            url = RequestUtils.computeURL(pageContext, forward, href,
  +                                          page, params, anchor, false);
  +        } catch (MalformedURLException e) {
  +            RequestUtils.saveException(pageContext, e);
  +            throw new JspException
  +                (messages.getMessage("rewrite.url", e.toString()));
  +        }
   
        // Print this element to our output writer
  -        ResponseUtils.write(pageContext, results.toString());
  +        ResponseUtils.write(pageContext, url.toString());
   
        // Skip the body of this tag
        return (SKIP_BODY);
  
  
  
  1.6       +1 -1      
jakarta-struts/src/share/org/apache/struts/taglib/logic/LocalStrings.properties
  
  Index: LocalStrings.properties
  ===================================================================
  RCS file: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/logic/LocalStrings.properties,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- LocalStrings.properties   2001/05/03 03:29:37     1.5
  +++ LocalStrings.properties   2001/05/09 19:31:22     1.6
  @@ -11,4 +11,4 @@
   redirect.forward=Missing ActionForward for {0}
   redirect.forwards=Missing ActionForwards collection
   redirect.map=Property {0} of bean {1} is not a Map
  -redirect.url=Cannot create URL with scheme={0} server={1} port={2} path={3}
  +redirect.url=Cannot create redirect URL: {0}
  
  
  
  1.9       +49 -188   
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.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- RedirectTag.java  2001/05/03 03:29:38     1.8
  +++ RedirectTag.java  2001/05/09 19:31:23     1.9
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/logic/RedirectTag.java,v 
1.8 2001/05/03 03:29:38 craigmcc Exp $
  - * $Revision: 1.8 $
  - * $Date: 2001/05/03 03:29:38 $
  + * $Header: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/taglib/logic/RedirectTag.java,v 
1.9 2001/05/09 19:31:23 craigmcc Exp $
  + * $Revision: 1.9 $
  + * $Date: 2001/05/09 19:31:23 $
    *
    * ====================================================================
    *
  @@ -65,6 +65,7 @@
   
   import java.io.IOException;
   import java.net.MalformedURLException;
  +import java.net.URL;
   import java.net.URLEncoder;
   import java.util.Iterator;
   import java.util.Map;
  @@ -88,7 +89,7 @@
    * Generate a URL-encoded redirect to the specified URI.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.8 $ $Date: 2001/05/03 03:29:38 $
  + * @version $Revision: 1.9 $ $Date: 2001/05/09 19:31:23 $
    */
   
   public class RedirectTag extends TagSupport {
  @@ -98,6 +99,20 @@
   
   
       /**
  +     * The anchor to be added to the end of the generated hyperlink.
  +     */
  +    protected String anchor = null;
  +
  +    public String getAnchor() {
  +        return (this.anchor);
  +    }
  +
  +    public void setAnchor(String anchor) {
  +        this.anchor = anchor;
  +    }
  +
  +
  +    /**
        * The logical forward name from which to retrieve the redirect URI.
        */
       protected String forward = null;
  @@ -246,6 +261,20 @@
       }
   
   
  +    /**
  +     * Include our transaction control token?
  +     */
  +    protected boolean transaction = false;
  +
  +    public boolean getTransaction() {
  +        return (this.transaction);
  +    }
  +
  +    public void setTransaction(boolean transaction) {
  +        this.transaction = transaction;
  +    }
  +
  +
       // --------------------------------------------------------- Public Methods
   
   
  @@ -268,12 +297,25 @@
        */
       public int doEndTag() throws JspException {
   
  +        // Calculate the redirect URL
  +        Map params = RequestUtils.computeParameters
  +            (pageContext, paramId, paramName, paramProperty, paramScope,
  +             name, property, scope, transaction);
  +        URL url = null;
  +        try {
  +            url = RequestUtils.computeURL(pageContext, forward, href,
  +                                          page, params, anchor, true);
  +        } catch (MalformedURLException e) {
  +            RequestUtils.saveException(pageContext, e);
  +            throw new JspException
  +                (messages.getMessage("redirect.url", e.toString()));
  +        }
  +
           // Perform the redirection
        HttpServletResponse response =
          (HttpServletResponse) pageContext.getResponse();
  -        String hyperlink = hyperlink();
           try {
  -            response.sendRedirect(response.encodeRedirectURL(hyperlink));
  +            response.sendRedirect(url.toString());
           } catch (IOException e) {
               RequestUtils.saveException(pageContext, e);
               throw new JspException(e.getMessage());
  @@ -291,6 +333,7 @@
       public void release() {
   
        super.release();
  +        anchor = null;
        forward = null;
        href = null;
        name = null;
  @@ -301,188 +344,6 @@
        paramScope = null;
        property = null;
           scope = null;
  -
  -    }
  -
  -
  -    // ------------------------------------------------------ Protected Methods
  -
  -
  -    /**
  -     * Return the specified hyperlink, modified as necessary with optional
  -     * request parameters.  Return <code>null</code> if we are generating
  -     * a name anchor rather than a hyperlink.
  -     *
  -     * @exception JspException if an error occurs preparing the hyperlink
  -     */
  -    protected String hyperlink() throws JspException {
  -
  -        // Validate the number of href specifiers that were specified
  -        int n = 0;
  -        if (forward != null)
  -            n++;
  -        if (href != null)
  -            n++;
  -        if (page != null)
  -            n++;
  -        if (n != 1) {
  -            JspException e = new JspException
  -                (messages.getMessage("redirect.destination"));
  -            RequestUtils.saveException(pageContext, e);
  -            throw e;
  -        }
  -
  -        // Start with an unadorned "href"
  -     String href = null;
  -
  -        // If "href" was specified, use it as is
  -        if (this.href != null) {
  -            href = this.href;
  -        }
  -
  -     // If "forward" was specified, compute the "href" to forward to
  -     else if (forward != null) {
  -         ActionForwards forwards = (ActionForwards)
  -             pageContext.getAttribute(Action.FORWARDS_KEY,
  -                                      PageContext.APPLICATION_SCOPE);
  -         if (forwards == null) {
  -                JspException e = new JspException
  -                 (messages.getMessage("redirect.forwards"));
  -                RequestUtils.saveException(pageContext, e);
  -                throw e;
  -            }
  -         ActionForward forward = forwards.findForward(this.forward);
  -         if (forward == null) {
  -                JspException e = new JspException
  -                 (messages.getMessage("redirect.forward", this.forward));
  -                RequestUtils.saveException(pageContext, e);
  -                throw e;
  -            }
  -         HttpServletRequest request =
  -             (HttpServletRequest) pageContext.getRequest();
  -            try {
  -                href = RequestUtils.absoluteURL(request, forward.getPath());
  -            } catch (MalformedURLException mue) {
  -                RequestUtils.saveException(pageContext, mue);
  -                ServletContext sc = pageContext.getServletContext();
  -                sc.log(messages.getMessage("redirect.url",
  -                                           request.getScheme(),
  -                                           request.getServerName(),
  -                                           "" + request.getServerPort(),
  -                                           forward.getPath()),
  -                       mue);
  -                JspException e = new JspException
  -                    (messages.getMessage("redirect.url",
  -                                         request.getScheme(),
  -                                         request.getServerName(),
  -                                         "" + request.getServerPort(),
  -                                         forward.getPath()));
  -                throw e;
  -            }
  -     }
  -
  -        // If "page" was specified, compute the "href" to forward to
  -        else if (page != null) {
  -            HttpServletRequest request =
  -                (HttpServletRequest) pageContext.getRequest();
  -            try {
  -                href = RequestUtils.absoluteURL(request, page);
  -            } catch (MalformedURLException mue) {
  -                RequestUtils.saveException(pageContext, mue);
  -                ServletContext sc = pageContext.getServletContext();
  -                sc.log(messages.getMessage("redirect.url",
  -                                           request.getScheme(),
  -                                           request.getServerName(),
  -                                           "" + request.getServerPort(),
  -                                           page),
  -                       mue);
  -                JspException e = new JspException
  -                    (messages.getMessage("redirect.url",
  -                                         request.getScheme(),
  -                                         request.getServerName(),
  -                                         "" + request.getServerPort(),
  -                                         page));
  -                throw e;
  -            }
  -        }
  -
  -        // Append a single-parameter name and value, if requested
  -        if ((paramId != null) && (paramName != null)) {
  -            if (href.indexOf('?') < 0)
  -                href += '?';
  -            else
  -                href += '&';
  -            href += paramId;
  -            href += '=';
  -            Object value =
  -                RequestUtils.lookup(pageContext, paramName, paramProperty,
  -                                    paramScope);
  -            if (value != null)
  -                href += value.toString();
  -        }
  -
  -     // Just return the "href" attribute if there is no bean to look up
  -     if (name == null)
  -         return (href);
  -
  -     // Look up the map we will be using
  -        Object value =
  -            RequestUtils.lookup(pageContext, name, property, scope);
  -        if (value == null)
  -            return (href);
  -        if (!(value instanceof Map)) {
  -            JspException e = new JspException
  -                (messages.getMessage("redirect.map", property, name));
  -            RequestUtils.saveException(pageContext, e);
  -            throw e;
  -        }
  -        Map map = (Map) value;
  -
  -     // Append the required query parameters
  -     StringBuffer sb = new StringBuffer(href);
  -     boolean question = (href.indexOf("?") >= 0);
  -     Iterator keys = map.keySet().iterator();
  -     while (keys.hasNext()) {
  -         String key = (String) keys.next();
  -         value = map.get(key);
  -            if (value == null) {
  -                if (question)
  -                    sb.append('&');
  -                else {
  -                    sb.append('?');
  -                    question = true;
  -                }
  -                sb.append(key);
  -                sb.append('=');
  -                // Interpret null as "no value specified"
  -         } else if (value instanceof String[]) {
  -             String values[] = (String[]) value;
  -             for (int i = 0; i < values.length; i++) {
  -                 if (question)
  -                     sb.append('&');
  -                 else {
  -                     sb.append('?');
  -                     question = true;
  -                 }
  -                 sb.append(key);
  -                 sb.append('=');
  -                 sb.append(URLEncoder.encode(values[i]));
  -             }
  -         } else {
  -             if (question)
  -                 sb.append('&');
  -             else {
  -                 sb.append('?');
  -                 question = true;
  -             }
  -             sb.append(key);
  -             sb.append('=');
  -             sb.append(URLEncoder.encode(value.toString()));
  -         }
  -     }
  -
  -     // Return the final result
  -     return (sb.toString());
   
       }
   
  
  
  
  1.3       +5 -0      
jakarta-struts/src/share/org/apache/struts/util/LocalStrings.properties
  
  Index: LocalStrings.properties
  ===================================================================
  RCS file: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/util/LocalStrings.properties,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- LocalStrings.properties   2001/02/20 01:48:46     1.2
  +++ LocalStrings.properties   2001/05/09 19:31:28     1.3
  @@ -1,7 +1,12 @@
  +computeURL.forward=Cannot retrive ActionForward named {0}
  +computeURL.forwards=Cannot retrieve ActionForwards collection
  +computeURL.specifier=You must specify exactly one of "forward", "href", or "page"
   lookup.access=Invalid access looking up property {0} of bean {1}
   lookup.bean=Cannot find bean {0} in scope {1}
   lookup.method=No getter method for property {0} of bean {1}
   lookup.scope=Invalid bean scope {0}
   lookup.target=Exception thrown by getter for property {0} of bean {1}
   message.bundle=Cannot find message resources under key {0}
  +parameters.multi=Cannot cast to Map for name={0} property={1e} scope={2}
  +parameters.single=Cannot cast to String for name={0} property={1} scope={2}
   write.io=Input/output error: {0}
  
  
  
  1.11      +276 -11   
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.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- RequestUtils.java 2001/05/03 03:29:38     1.10
  +++ RequestUtils.java 2001/05/09 19:31:29     1.11
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/util/RequestUtils.java,v 1.10 
2001/05/03 03:29:38 craigmcc Exp $
  - * $Revision: 1.10 $
  - * $Date: 2001/05/03 03:29:38 $
  + * $Header: 
/home/cvs/jakarta-struts/src/share/org/apache/struts/util/RequestUtils.java,v 1.11 
2001/05/09 19:31:29 craigmcc Exp $
  + * $Revision: 1.11 $
  + * $Date: 2001/05/09 19:31:29 $
    *
    * ====================================================================
    *
  @@ -66,6 +66,7 @@
   import java.lang.reflect.InvocationTargetException;
   import java.net.MalformedURLException;
   import java.net.URL;
  +import java.net.URLEncoder;
   import java.util.Enumeration;
   import java.util.HashMap;
   import java.util.Hashtable;
  @@ -74,12 +75,17 @@
   import java.util.Map;
   import javax.servlet.ServletException;
   import javax.servlet.http.HttpServletRequest;
  +import javax.servlet.http.HttpServletResponse;
  +import javax.servlet.http.HttpSession;
   import javax.servlet.jsp.JspException;
   import javax.servlet.jsp.PageContext;
   import org.apache.struts.action.Action;
   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.ActionServlet;
  +import org.apache.struts.taglib.html.Constants;
   import org.apache.struts.upload.FormFile;
   import org.apache.struts.upload.MultipartRequestHandler;
   
  @@ -89,7 +95,7 @@
    * in the Struts controller framework.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.10 $ $Date: 2001/05/03 03:29:38 $
  + * @version $Revision: 1.11 $ $Date: 2001/05/09 19:31:29 $
    */
   
   public class RequestUtils {
  @@ -119,28 +125,287 @@
       /**
        * Create and return an absolute URL for the specified context-relative
        * path, based on the server and context information in the specified
  -     * request.  If no valid URL can be created, returns <code>null</code>.
  +     * request.
        *
        * @param request The servlet request we are processing
        * @param path The context-relative path (must start with '/')
        *
        * @exception MalformedURLException if we cannot create an absolute URL
        */
  -    public static String absoluteURL(HttpServletRequest request, String path)
  +    public static URL absoluteURL(HttpServletRequest request, String path)
           throws MalformedURLException {
   
  -        URL url = null;
           int port = request.getServerPort();
           String scheme = request.getScheme();
           String serverName = request.getServerName();
           String uri = request.getContextPath() + path;
           if ("http".equals(scheme) && (80 == port))
  -            url = new URL(scheme, serverName, uri);
  +            return (new URL(scheme, serverName, uri));
           else if ("https".equals(scheme) && (443 == port))
  -            url = new URL(scheme, serverName, uri);
  +            return (new URL(scheme, serverName, uri));
  +        else // Nonstandard port for the specified protocol
  +            return (new URL(scheme, serverName, port, uri));
  +
  +    }
  +
  +
  +    /**
  +     * Compute a set of query parameters that will be dynamically added to
  +     * a generated URL.  The returned Map is keyed by parameter name, and the
  +     * values are either null (no value specified), a String (single value
  +     * specified), or a String[] array (multiple values specified).  Parameter
  +     * names correspond to the corresponding attributes of the
  +     * <code>&lt;html:link&gt;</code> tag.  If no query parameters are
  +     * identified, return <code>null</code>.
  +     *
  +     * @param pageContext PageContext we are operating in
  +     *
  +     * @param paramId Single-value request parameter name (if any)
  +     * @param paramName Bean containing single-value parameter value
  +     * @param paramProperty Property (of bean named by <code>paramName</code>
  +     *  containing single-value parameter value
  +     * @param paramScope Scope containing bean named by
  +     *  <code>paramScope</code>
  +     *
  +     * @param name Bean containing multi-value parameters Map (if any)
  +     * @param property Property (of bean named by <code>name</code>
  +     *  containing multi-value parameters Map
  +     * @param scope Scope containing bean named by
  +     *  <code>name</code>
  +     *
  +     * @param transaction Should we add our transaction control token?
  +     *
  +     * @exception JspException if we cannot look up the required beans
  +     * @exception JspException if a class cast exception occurs on a
  +     *  looked-up bean or property
  +     */
  +    public static Map computeParameters(PageContext pageContext,
  +                                        String paramId, String paramName,
  +                                        String paramProperty,
  +                                        String paramScope, String name,
  +                                        String property, String scope,
  +                                        boolean transaction)
  +        throws JspException {
  +
  +        // Short circuit if no parameters are specified
  +        if ((paramId == null) && (name == null))
  +            return (null);
  +
  +        // Locate the Map containing our multi-value parameters map
  +        Map map = null;
  +        try {
  +            map = (Map) lookup(pageContext, name,
  +                               property, scope);
  +        } catch (ClassCastException e) {
  +            saveException(pageContext, e);
  +            throw new JspException
  +                (messages.getMessage("parameters.multi", name,
  +                                     property, scope));
  +        } catch (JspException e) {
  +            saveException(pageContext, e);
  +            throw e;
  +        }
  +
  +        // Create a Map to contain our results from the multi-value parameters
  +        Map results = null;
  +        if (map != null)
  +            results = new HashMap(map);
           else
  -            url = new URL(scheme, serverName, port, uri);
  -        return (url.toString());
  +            results = new HashMap();
  +
  +        // Add the single-value parameter (if any)
  +        if (paramId != null) {
  +            String paramValue = null;
  +            try {
  +                paramValue =(String) lookup(pageContext, paramName,
  +                                            paramProperty, paramScope);
  +            } catch (ClassCastException e) {
  +                saveException(pageContext, e);
  +                throw new JspException
  +                    (messages.getMessage("parameters.single", paramName,
  +                                         paramProperty, paramScope));
  +            } catch (JspException e) {
  +                saveException(pageContext, e);
  +                throw e;
  +            }
  +            Object mapValue = map.get(paramId);
  +            if (mapValue == null)
  +                map.put(paramId, paramValue);
  +            else if (mapValue instanceof String) {
  +                String newValues[] = new String[2];
  +                newValues[0] = (String) mapValue;
  +                newValues[1] = paramValue;
  +                map.put(paramId, newValues);
  +            } else /* if (mapValue instanceof String[]) */ {
  +                String oldValues[] = (String[]) mapValue;
  +                String newValues[] = new String[oldValues.length + 1];
  +                System.arraycopy(oldValues, 0, newValues, 0, oldValues.length);
  +                newValues[oldValues.length] = paramValue;
  +                map.put(paramId, newValues);
  +            }
  +        }
  +
  +        // Add our transaction control token (if requested)
  +        if (transaction) {
  +            HttpSession session = pageContext.getSession();
  +            String token = null;
  +            if (session != null)
  +                token = (String)
  +                    session.getAttribute(Action.TRANSACTION_TOKEN_KEY);
  +            if (token != null)
  +                map.put(Constants.TOKEN_KEY, token);
  +        }
  +
  +        // Return the completed Map
  +        return (results);
  +
  +    }
  +
  +
  +    /**
  +     * Compute an absolute URL based on the <code>forward</code>,
  +     * <code>href</code>, or <code>page</code> parameter that is not null.
  +     * The returned URL will have already been passed to
  +     * <code>response.encodeURL()</code> for adding a session identifier.
  +     *
  +     * @param pageContext PageContext for the tag making this call
  +     * @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
  +     *  be created (if specified)
  +     * @param params Map of parameters to be dynamically included (if any)
  +     * @param anchor Anchor to be dynamically included (if any)
  +     * @param redirect Is this URL for a <code>response.sendRedirect()</code>?
  +     *
  +     * @exception MalformedURLException if a URL cannot be created
  +     *  for the specified parameters
  +     */
  +    public static URL computeURL(PageContext pageContext, String forward,
  +                                 String href, String page,
  +                                 Map params, String anchor, boolean redirect)
  +        throws MalformedURLException {
  +
  +        // Validate that exactly one specifier was included
  +        int n = 0;
  +        if (forward != null)
  +            n++;
  +        if (href != null)
  +            n++;
  +        if (page != null)
  +            n++;
  +        if (n != 1)
  +            throw new MalformedURLException
  +                (messages.getMessage("computeURL.specifier"));
  +
  +        // Calculate the appropriate URL
  +        URL url = null;
  +        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)
  +                throw new MalformedURLException
  +                    (messages.getMessage("computeURL.forward", forward));
  +            HttpServletRequest request =
  +                (HttpServletRequest) pageContext.getRequest();
  +            url = absoluteURL(request, af.getPath());
  +        } else if (href != null) {
  +            url = new URL(href);
  +        } else /* if (page != null) */ {
  +            HttpServletRequest request =
  +                (HttpServletRequest) pageContext.getRequest();
  +            url = absoluteURL(request, page);
  +        }
  +
  +        // Add anchor if requested (replacing any existing anchor)
  +        if (anchor != null) {
  +            String temp = url.toString();
  +            int hash = temp.indexOf('#');
  +            if (hash >= 0)
  +                temp = temp.substring(0, hash);
  +            StringBuffer sb = new StringBuffer(temp);
  +            sb.append('#');
  +            sb.append(URLEncoder.encode(anchor));
  +            url = new URL(sb.toString());
  +        }
  +        
  +        // Add dynamic parameters if requested
  +        if ((params != null) && (params.size() > 0)) {
  +
  +            // Save any existing anchor
  +            String temp = url.toString();
  +            int hash = temp.indexOf('#');
  +            if (hash >= 0) {
  +                anchor = temp.substring(hash + 1);
  +                temp = temp.substring(0, hash);
  +            } else
  +                anchor = null;
  +
  +            // Add the required request parameters
  +            boolean question = temp.indexOf('?') >= 0;
  +            StringBuffer sb = new StringBuffer(temp);
  +            Iterator keys = params.keySet().iterator();
  +            while (keys.hasNext()) {
  +                String key = (String) keys.next();
  +                Object value = params.get(key);
  +                if (value == null) {
  +                    if (!question) {
  +                        sb.append('?');
  +                        question = true;
  +                    } else
  +                        sb.append('&');
  +                    sb.append(URLEncoder.encode(key));
  +                    sb.append('='); // Interpret null as "no value"
  +                } else if (value instanceof String) {
  +                    if (!question) {
  +                        sb.append('?');
  +                        question = true;
  +                    } else
  +                        sb.append('&');
  +                    sb.append(URLEncoder.encode(key));
  +                    sb.append('=');
  +                    sb.append(URLEncoder.encode((String) value));
  +                } else /* if (value instanceof String[]) */ {
  +                    String values[] = (String[]) value;
  +                    for (int i = 0; i < values.length; i++) {
  +                        if (!question) {
  +                            sb.append('?');
  +                            question = true;
  +                        } else
  +                            sb.append('&');
  +                        sb.append(URLEncoder.encode(key));
  +                        sb.append('=');
  +                        sb.append(URLEncoder.encode(values[i]));
  +                    }
  +                }
  +            }
  +
  +            // Re-add the saved anchor (if any)
  +            if (anchor != null) {
  +                sb.append('#');
  +                sb.append(anchor);
  +            }
  +
  +            // Update to the completed URL
  +            url = new URL(sb.toString());
  +
  +        }
  +
  +        // Perform URL rewriting to include our session ID (if any)
  +        if (pageContext.getSession() != null) {
  +            HttpServletResponse response =
  +                (HttpServletResponse) pageContext.getResponse();
  +            if (redirect)
  +                url = new URL(response.encodeRedirectURL(url.toString()));
  +            else
  +                url = new URL(response.encodeURL(url.toString()));
  +        }
  +        return (url);
   
       }
   
  
  
  

Reply via email to