Sorry for the reformatting folks -- it is unintentional -- all the meat
is down at the end.

On Tue, 2002-04-16 at 12:49, [EMAIL PROTECTED] wrote:
> jtaylor     02/04/16 09:49:38
> 
>   Modified:    src/java/org/apache/turbine DynamicURI.java
>   Log:
>   No longer uses java.net.URLEncoder, use StringBuffer more effectively. A couple
>   of times faster and fewer object creations. There is probably room for more
>   optimization, any improvement is probably worthwhile since this is a real
>   hotspot.
>   
>   Revision  Changes    Path
>   1.6       +285 -194  jakarta-turbine-3/src/java/org/apache/turbine/DynamicURI.java
>   
>   Index: DynamicURI.java
>   ===================================================================
>   RCS file: /home/cvs/jakarta-turbine-3/src/java/org/apache/turbine/DynamicURI.java,v
>   retrieving revision 1.5
>   retrieving revision 1.6
>   diff -u -r1.5 -r1.6
>   --- DynamicURI.java 5 Mar 2002 01:32:34 -0000       1.5
>   +++ DynamicURI.java 16 Apr 2002 16:49:38 -0000      1.6
>   @@ -54,14 +54,11 @@
>     * <http://www.apache.org/>.
>     */
>    
>   -import org.apache.turbine.RunData;
>   -import java.net.URLEncoder;
>   +import java.util.BitSet;
>    import java.util.Enumeration;
>    import java.util.Vector;
>    import javax.servlet.http.HttpServletRequest;
>    import javax.servlet.http.HttpServletResponse;
>   -import org.apache.turbine.Turbine;
>   -import org.apache.turbine.ParameterParser;
>    
>    /**
>     * This creates a Dynamic URI for use within the Turbine system
>   @@ -84,7 +81,8 @@
>     * @author <a href="mailto:[EMAIL PROTECTED]";>Jon S. Stevens</a>
>     * @author <a href="mailto:[EMAIL PROTECTED]";>Jason van Zyl</a>
>     * @author <a href="mailto:[EMAIL PROTECTED]";>John McNally</a>
>   - * @version $Id: DynamicURI.java,v 1.5 2002/03/05 01:32:34 jon Exp $
>   + * @author <a href="mailto:[EMAIL PROTECTED]";>James Taylor</a>
>   + * @version $Id: DynamicURI.java,v 1.6 2002/04/16 16:49:38 jtaylor Exp $
>     */
>    public class DynamicURI
>    {
>   @@ -141,7 +139,7 @@
>         *
>         * @param data A Turbine RunData object.
>         */
>   -    public DynamicURI( RunData data )
>   +    public DynamicURI(RunData data)
>        {
>            init(data);
>        }
>   @@ -160,8 +158,8 @@
>         * @param data A Turbine RunData object.
>         * @param screen A String with the name of a screen.
>         */
>   -    public DynamicURI( RunData data,
>   -                       String screen )
>   +    public DynamicURI(RunData data,
>   +                      String screen)
>        {
>            this(data);
>            setScreen(screen);
>   @@ -174,11 +172,11 @@
>         * @param screen A String with the name of a screen.
>         * @param action A String with the name of an action.
>         */
>   -    public DynamicURI( RunData data,
>   -                       String screen,
>   -                       String action )
>   +    public DynamicURI(RunData data,
>   +                      String screen,
>   +                      String action)
>        {
>   -        this( data, screen );
>   +        this(data, screen);
>            setAction(action);
>        }
>    
>   @@ -190,12 +188,12 @@
>         * @param action A String with the name of an action.
>         * @param redirect True if it should redirect.
>         */
>   -    public DynamicURI( RunData data,
>   -                       String screen,
>   -                       String action,
>   -                       boolean redirect )
>   +    public DynamicURI(RunData data,
>   +                      String screen,
>   +                      String action,
>   +                      boolean redirect)
>        {
>   -        this( data, screen, action );
>   +        this(data, screen, action);
>            this.redirect = redirect;
>        }
>    
>   @@ -206,11 +204,11 @@
>         * @param screen A String with the name of a screen.
>         * @param redirect True if it should redirect.
>         */
>   -    public DynamicURI( RunData data,
>   -                       String screen,
>   -                       boolean redirect )
>   +    public DynamicURI(RunData data,
>   +                      String screen,
>   +                      boolean redirect)
>        {
>   -        this( data, screen );
>   +        this(data, screen);
>            this.redirect = redirect;
>        }
>    
>   @@ -220,19 +218,19 @@
>         * @param data A Turbine RunData object.
>         * @param redirect True if it should redirect.
>         */
>   -    public DynamicURI( RunData data,
>   -                       boolean redirect )
>   +    public DynamicURI(RunData data,
>   +                      boolean redirect)
>        {
>   -        this( data );
>   +        this(data);
>            this.redirect = redirect;
>        }
>    
>        /**
>         * Initialize with a RunData object
>         *
>   -     * @param RunData
>   +     * @param data
>         */
>   -    public void init( RunData data )
>   +    public void init(RunData data)
>        {
>            this.data = data;
>            this.res = data.getResponse();
>   @@ -250,23 +248,23 @@
>         * @param name A String with the name to add.
>         * @param value A String with the value to add.
>         */
>   -    protected void add ( int type,
>   +    protected void add(int type,
>                           String name,
>   -                       String value )
>   +                       String value)
>        {
>            Object[] tmp = new Object[2];
>            tmp[0] = (Object) data.getParameters().convertAndTrim(name);
>            tmp[1] = (Object) value;
>            switch (type)
>            {
>   -        case PATH_INFO:
>   -            this.pathInfo.addElement ( tmp );
>   -            this.hasPathInfo = true;
>   -            break;
>   -        case QUERY_DATA:
>   -            this.queryData.addElement ( tmp );
>   -            this.hasQueryData = true;
>   -            break;
>   +            case PATH_INFO:
>   +                this.pathInfo.addElement(tmp);
>   +                this.hasPathInfo = true;
>   +                break;
>   +            case QUERY_DATA:
>   +                this.queryData.addElement(tmp);
>   +                this.hasQueryData = true;
>   +                break;
>            }
>        }
>    
>   @@ -283,21 +281,21 @@
>         * @param type Type (P or Q) of insertion.
>         * @param pp A ParameterParser.
>         */
>   -    protected void add( int type,
>   -                      ParameterParser pp )
>   +    protected void add(int type,
>   +                       ParameterParser pp)
>        {
>            Enumeration e = pp.keys();
>   -        while ( e.hasMoreElements() )
>   +        while (e.hasMoreElements())
>            {
>   -            String key = (String)e.nextElement();
>   -            if ( !key.equalsIgnoreCase(Turbine.ACTION) &&
>   -                 !key.equalsIgnoreCase(Turbine.SCREEN) &&
>   -                 !key.equalsIgnoreCase(Turbine.TEMPLATE) )
>   +            String key = (String) e.nextElement();
>   +            if (!key.equalsIgnoreCase(Turbine.ACTION) &&
>   +                !key.equalsIgnoreCase(Turbine.SCREEN) &&
>   +                !key.equalsIgnoreCase(Turbine.TEMPLATE))
>                {
>                    String[] values = pp.getStrings(key);
>   -                for ( int i=0; i<values.length; i++ )
>   +                for (int i = 0; i < values.length; i++)
>                    {
>   -                    add( type, key, values[i] );
>   +                    add(type, key, values[i]);
>                    }
>                }
>            }
>   @@ -309,9 +307,9 @@
>         * @param name A String with the name to add.
>         * @param value An Object with the value to add.
>         */
>   -    public DynamicURI addPathInfo ( String name, Object value )
>   +    public DynamicURI addPathInfo(String name, Object value)
>        {
>   -        add ( PATH_INFO, name, value.toString() );
>   +        add(PATH_INFO, name, value.toString());
>            return this;
>        }
>    
>   @@ -321,9 +319,9 @@
>         * @param name A String with the name to add.
>         * @param value A String with the value to add.
>         */
>   -    public DynamicURI addPathInfo ( String name, String value )
>   +    public DynamicURI addPathInfo(String name, String value)
>        {
>   -        add ( PATH_INFO, name, value );
>   +        add(PATH_INFO, name, value);
>            return this;
>        }
>    
>   @@ -333,9 +331,9 @@
>         * @param name A String with the name to add.
>         * @param value A double with the value to add.
>         */
>   -    public DynamicURI addPathInfo ( String name, double value )
>   +    public DynamicURI addPathInfo(String name, double value)
>        {
>   -        add ( PATH_INFO, name, Double.toString(value) );
>   +        add(PATH_INFO, name, Double.toString(value));
>            return this;
>        }
>    
>   @@ -345,9 +343,9 @@
>         * @param name A String with the name to add.
>         * @param value An int with the value to add.
>         */
>   -    public DynamicURI addPathInfo ( String name, int value )
>   +    public DynamicURI addPathInfo(String name, int value)
>        {
>   -        add ( PATH_INFO, name, new Integer(value).toString() );
>   +        add(PATH_INFO, name, new Integer(value).toString());
>            return this;
>        }
>    
>   @@ -357,9 +355,9 @@
>         * @param name A String with the name to add.
>         * @param value A long with the value to add.
>         */
>   -    public DynamicURI addPathInfo ( String name, long value )
>   +    public DynamicURI addPathInfo(String name, long value)
>        {
>   -        add ( PATH_INFO, name, new Long(value).toString() );
>   +        add(PATH_INFO, name, new Long(value).toString());
>            return this;
>        }
>    
>   @@ -369,9 +367,9 @@
>         *
>         * @param pp A ParameterParser.
>         */
>   -    public DynamicURI addPathInfo ( ParameterParser pp )
>   +    public DynamicURI addPathInfo(ParameterParser pp)
>        {
>   -        add ( PATH_INFO, pp );
>   +        add(PATH_INFO, pp);
>            return this;
>        }
>    
>   @@ -381,9 +379,9 @@
>         * @param name A String with the name to add.
>         * @param value An Object with the value to add.
>         */
>   -    public DynamicURI addQueryData ( String name, Object value )
>   +    public DynamicURI addQueryData(String name, Object value)
>        {
>   -        add ( QUERY_DATA, name, value.toString() );
>   +        add(QUERY_DATA, name, value.toString());
>            return this;
>        }
>    
>   @@ -393,9 +391,9 @@
>         * @param name A String with the name to add.
>         * @param value A String with the value to add.
>         */
>   -    public DynamicURI addQueryData ( String name, String value )
>   +    public DynamicURI addQueryData(String name, String value)
>        {
>   -        add ( QUERY_DATA, name, value );
>   +        add(QUERY_DATA, name, value);
>            return this;
>        }
>    
>   @@ -405,9 +403,9 @@
>         * @param name A String with the name to add.
>         * @param value A double with the value to add.
>         */
>   -    public DynamicURI addQueryData ( String name, double value )
>   +    public DynamicURI addQueryData(String name, double value)
>        {
>   -        add ( QUERY_DATA, name, Double.toString(value) );
>   +        add(QUERY_DATA, name, Double.toString(value));
>            return this;
>        }
>    
>   @@ -417,9 +415,9 @@
>         * @param name A String with the name to add.
>         * @param value An int with the value to add.
>         */
>   -    public DynamicURI addQueryData ( String name, int value )
>   +    public DynamicURI addQueryData(String name, int value)
>        {
>   -        add ( QUERY_DATA, name, new Integer(value).toString() );
>   +        add(QUERY_DATA, name, new Integer(value).toString());
>            return this;
>        }
>    
>   @@ -429,9 +427,9 @@
>         * @param name A String with the name to add.
>         * @param value A long with the value to add.
>         */
>   -    public DynamicURI addQueryData ( String name, long value )
>   +    public DynamicURI addQueryData(String name, long value)
>        {
>   -        add ( QUERY_DATA, name, new Long(value).toString() );
>   +        add(QUERY_DATA, name, new Long(value).toString());
>            return this;
>        }
>    
>   @@ -441,9 +439,9 @@
>         *
>         * @param pp A ParameterParser.
>         */
>   -    public DynamicURI addQueryData ( ParameterParser pp )
>   +    public DynamicURI addQueryData(ParameterParser pp)
>        {
>   -        add ( QUERY_DATA, pp );
>   +        add(QUERY_DATA, pp);
>            return this;
>        }
>    
>   @@ -463,7 +461,7 @@
>         * @param name A String with the name for the anchor.
>         * @return The anchor as a &lt;A HREF=""&gt;name&lt;/A&gt;.
>         */
>   -    public String getA( String name )
>   +    public String getA(String name)
>        {
>            return new StringBuffer("<a href=\"")
>                .append(this.toString())
>   @@ -479,7 +477,7 @@
>         *
>         * @return A String with the script name.
>         */
>   -    public String getScriptName ()
>   +    public String getScriptName()
>        {
>            return data.getScriptName();
>        }
>   @@ -489,7 +487,7 @@
>         *
>         * @return A String with the server name.
>         */
>   -    public String getServerName ()
>   +    public String getServerName()
>        {
>            return data.getServerName();
>        }
>   @@ -499,7 +497,7 @@
>         *
>         * @return A String with the server port.
>         */
>   -    public int getServerPort ()
>   +    public int getServerPort()
>        {
>            return data.getServerPort();
>        }
>   @@ -533,48 +531,48 @@
>         * @param type Type (P or Q) of removal.
>         * @param name A String with the name to be removed.
>         */
>   -    protected void remove ( int type,
>   -                          String name )
>   +    protected void remove(int type,
>   +                          String name)
>        {
>            try
>            {
>                switch (type)
>                {
>   -            case PATH_INFO:
>   -                for (Enumeration e = this.pathInfo.elements() ;
>   -                     e.hasMoreElements() ;)
>   -                {
>   -                    Object[] tmp = (Object[]) e.nextElement();
>   -                    if ( data.getParameters().convertAndTrim(name)
>   -                         .equals ( (String)tmp[0] ) )
>   +                case PATH_INFO:
>   +                    for (Enumeration e = this.pathInfo.elements();
>   +                         e.hasMoreElements();)
>                        {
>   -                        this.pathInfo.removeElement ( tmp );
>   +                        Object[] tmp = (Object[]) e.nextElement();
>   +                        if (data.getParameters().convertAndTrim(name)
>   +                            .equals((String) tmp[0]))
>   +                        {
>   +                            this.pathInfo.removeElement(tmp);
>   +                        }
>                        }
>   -                }
>   -                if ( hasPathInfo && this.pathInfo.size() == 0 )
>   -                {
>   -                    this.hasPathInfo = false;
>   -                }
>   -                break;
>   -            case QUERY_DATA:
>   -                for (Enumeration e = this.queryData.elements() ;
>   -                     e.hasMoreElements() ;)
>   -                {
>   -                    Object[] tmp = (Object[]) e.nextElement();
>   -                    if ( data.getParameters().convertAndTrim(name)
>   -                         .equals ( (String)tmp[0] ) )
>   +                    if (hasPathInfo && this.pathInfo.size() == 0)
>                        {
>   -                        this.queryData.removeElement ( tmp );
>   +                        this.hasPathInfo = false;
>                        }
>   -                }
>   -                if ( hasQueryData && this.queryData.size() == 0 )
>   -                {
>   -                    this.hasQueryData = false;
>   -                }
>   -                break;
>   +                    break;
>   +                case QUERY_DATA:
>   +                    for (Enumeration e = this.queryData.elements();
>   +                         e.hasMoreElements();)
>   +                    {
>   +                        Object[] tmp = (Object[]) e.nextElement();
>   +                        if (data.getParameters().convertAndTrim(name)
>   +                            .equals((String) tmp[0]))
>   +                        {
>   +                            this.queryData.removeElement(tmp);
>   +                        }
>   +                    }
>   +                    if (hasQueryData && this.queryData.size() == 0)
>   +                    {
>   +                        this.hasQueryData = false;
>   +                    }
>   +                    break;
>                }
>            }
>   -        catch ( Exception e )
>   +        catch (Exception e)
>            {
>            }
>        }
>   @@ -582,7 +580,7 @@
>        /**
>         * Removes all the path info elements.
>         */
>   -    public void removePathInfo ()
>   +    public void removePathInfo()
>        {
>            this.pathInfo.removeAllElements();
>            this.hasPathInfo = false;
>   @@ -593,15 +591,15 @@
>         *
>         * @param name A String with the name to be removed.
>         */
>   -    public void removePathInfo ( String name )
>   +    public void removePathInfo(String name)
>        {
>   -        remove ( PATH_INFO, name );
>   +        remove(PATH_INFO, name);
>        }
>    
>        /**
>         * Removes all the query string elements.
>         */
>   -    public void removeQueryData ()
>   +    public void removeQueryData()
>        {
>            this.queryData.removeAllElements();
>            this.hasQueryData = false;
>   @@ -612,9 +610,9 @@
>         *
>         * @param name A String with the name to be removed.
>         */
>   -    public void removeQueryData ( String name )
>   +    public void removeQueryData(String name)
>        {
>   -        remove ( QUERY_DATA, name );
>   +        remove(QUERY_DATA, name);
>        }
>    
>        /**
>   @@ -624,36 +622,39 @@
>         * @param data A Vector of key/value arrays.
>         * @return A String with the URL encoded data.
>         */
>   -    protected String renderPathInfo ( Vector data )
>   +    protected String renderPathInfo(Vector data)
>        {
>   -        String key = null;
>   -        String value = null;
>   -        String tmp = null;
>            StringBuffer out = new StringBuffer();
>   +
>   +        renderPathInfo(data, out);
>   +
>   +        return out.toString();
>   +    }
>   +
>   +    /**
>   +     * This method takes a Vector of key/value arrays and writes it to the
>   +     * supplied StringBuffer as encoded path info.
>   +     *
>   +     * @param data A Vector of key/value arrays.
>   +     * @param out Buffer to which encoded path info is written
>   +     */
>   +    protected void renderPathInfo(Vector data, StringBuffer out)
>   +    {
>            Enumeration keys = data.elements();
>   -        while(keys.hasMoreElements())
>   +
>   +        while (keys.hasMoreElements())
>            {
>                Object[] stuff = (Object[]) keys.nextElement();
>   -            key = URLEncoder.encode((String)stuff[0]);
>   -            tmp = (String) stuff[1];
>   -            if (tmp == null || tmp.length() == 0)
>   -            {
>   -                value = "null";
>   -            }
>   -            else
>   -            {
>   -                value = URLEncoder.encode(tmp);
>   -            }
>    
>                if (out.length() > 0)
>                {
>   -                out.append ( "/" );
>   +                out.append("/");
>                }
>   -            out.append ( key );
>   -            out.append ( "/" );
>   -            out.append ( value );
>   +
>   +            writeEncoded((String) stuff[0], out);
>   +            out.append("/");
>   +            writeEncoded((String) stuff[1], out);
>            }
>   -        return out.toString();
>        }
>    
>        /**
>   @@ -663,36 +664,39 @@
>         * @param data A Vector of key/value arrays.
>         * @return A String with the URL encoded data.
>         */
>   -    protected String renderQueryString ( Vector data )
>   +    protected String renderQueryString(Vector data)
>        {
>   -        String key = null;
>   -        String value = null;
>   -        String tmp = null;
>            StringBuffer out = new StringBuffer();
>   +
>   +        renderQueryString(data, out);
>   +
>   +        return out.toString();
>   +    }
>   +
>   +    /**
>   +     * This method takes a Vector of key/value arrays and writes it to the
>   +     * provided StringBuffer in encoded query string format.
>   +     *
>   +     * @param data A Vector of key/value arrays.
>   +     * @param out Buffer to which encoded query string is written.
>   +     */
>   +    protected void renderQueryString(Vector data, StringBuffer out)
>   +    {
>            Enumeration keys = data.elements();
>   -        while(keys.hasMoreElements())
>   +
>   +        while (keys.hasMoreElements())
>            {
>                Object[] stuff = (Object[]) keys.nextElement();
>   -            key   = URLEncoder.encode((String) stuff[0]);
>   -            tmp = (String) stuff[1];
>   -            if (tmp == null || tmp.length() == 0)
>   -            {
>   -                value = "null";
>   -            }
>   -            else
>   -            {
>   -                value = URLEncoder.encode(tmp);
>   -            }
>    
>   -            if ( out.length() > 0)
>   +            if (out.length() > 0)
>                {
>   -                out.append ( "&" );
>   +                out.append("&");
>                }
>   -            out.append ( key );
>   -            out.append ( "=" );
>   -            out.append ( value );
>   +
>   +            writeEncoded((String) stuff[0], out);
>   +            out.append("=");
>   +            writeEncoded((String) stuff[1], out);
>            }
>   -        return out.toString();
>        }
>    
>        /**
>   @@ -704,9 +708,9 @@
>         * @param action A String with the action value.
>         * @return A DynamicURI (self).
>         */
>   -    public DynamicURI setAction ( String action )
>   +    public DynamicURI setAction(String action)
>        {
>   -        add ( PATH_INFO, Turbine.ACTION, action );
>   +        add(PATH_INFO, Turbine.ACTION, action);
>            return this;
>        }
>    
>   @@ -716,12 +720,12 @@
>         * <p>By default it adds the information to the path_info instead
>         * of the query data.
>         *
>   -     * @param action A String with the screen value.
>   +     * @param screen A String with the screen value.
>         * @return A DynamicURI (self).
>         */
>   -    public DynamicURI setScreen ( String screen )
>   +    public DynamicURI setScreen(String screen)
>        {
>   -        add ( PATH_INFO, Turbine.SCREEN, screen );
>   +        add(PATH_INFO, Turbine.SCREEN, screen);
>            return this;
>        }
>    
>   @@ -760,7 +764,7 @@
>         * if true, the scheme, domain, and port will not be included in the
>         * String representation of this uri..
>         *
>   -     * @param b a <code>boolean</code> 
>   +     * @param b a <code>boolean</code>
>         * @return a <code>DynamicURI</code> (self)
>         */
>        public DynamicURI setRelative(boolean b)
>   @@ -783,7 +787,7 @@
>        /**
>         * Can be used to disable url rewriting.
>         *
>   -     * @param b a <code>boolean</code> 
>   +     * @param b a <code>boolean</code>
>         * @return a <code>DynamicURI</code> (self)
>         */
>        public DynamicURI setEncodeUrl(boolean b)
>   @@ -825,44 +829,44 @@
>        public String toString()
>        {
>            StringBuffer output = new StringBuffer();
>   -        if (!isRelative)
>   +        if (!isRelative())
>            {
>   -            output.append ( getServerScheme() );
>   -            output.append ( "://" );
>   -            output.append ( getServerName() );
>   -            if ( (getServerScheme().equals(HTTP) && getServerPort() != 80)
>   -                 || (getServerScheme().equals(HTTPS) && getServerPort() != 443)
>   -               )
>   +            output.append(getServerScheme());
>   +            output.append("://");
>   +            output.append(getServerName());
>   +            if ((getServerScheme().equals(HTTP) && getServerPort() != 80)
>   +                || (getServerScheme().equals(HTTPS) && getServerPort() != 443))
>                {
>   -                output.append (':');
>   -                output.append ( getServerPort() );
>   +                output.append(':');
>   +                output.append(getServerPort());
>                }
>            }
>    
>   -        output.append ( getScriptName() );
>   -        if ( this.hasPathInfo )
>   +        output.append(getScriptName());
>   +
>   +        if (this.hasPathInfo)
>            {
>   -            output.append ('/');
>   -            output.append ( renderPathInfo(this.pathInfo) );
>   +            output.append('/');
>   +            renderPathInfo(this.pathInfo, output);
>            }
>   -        if ( this.hasQueryData )
>   +        if (this.hasQueryData)
>            {
>   -            output.append ('?');
>   -            output.append ( renderQueryString(this.queryData) );
>   +            output.append('?');
>   +            renderQueryString(this.queryData, output);
>            }
>    
>            // There seems to be a bug in Apache JServ 1.0 where the
>            // session id is not appended to the end of the url when a
>            // cookie has not been set.
>   -        if ( this.res != null && encodeUrl )
>   +        if (this.res != null && isEncodeUrl())
>            {
>   -            if ( this.redirect )
>   +            if (this.redirect)
>                {
>   -                return res.encodeRedirectURL (output.toString());
>   +                return res.encodeRedirectURL(output.toString());
>                }
>                else
>                {
>   -                return res.encodeURL (output.toString());
>   +                return res.encodeURL(output.toString());
>                }
>            }
>            else
>   @@ -894,7 +898,7 @@
>         * would not.
>         *
>         * @param data A Turbine RunData object.
>   -     * @param boolean to determine absolute vs. relative links.
>   +     * @param isAbsolute to determine absolute vs. relative links.
>         * @return A String with the URL representing the RunData.
>         */
>        public static String toString(RunData data, boolean isAbsolute)
>   @@ -904,32 +908,119 @@
>    
>            if (isAbsolute)
>            {
>   -            output.append (data.getServerScheme());
>   -            output.append ( "://" );
>   -            output.append (data.getServerName());
>   -            
>   -            if ( (data.getServerScheme().equals(HTTP) &&
>   -                  data.getServerPort() != 80) ||
>   -                 (data.getServerScheme().equals(HTTPS) &&
>   -                  data.getServerPort() != 443) )
>   +            output.append(data.getServerScheme());
>   +            output.append("://");
>   +            output.append(data.getServerName());
>   +
>   +            if ((data.getServerScheme().equals(HTTP) &&
>   +                data.getServerPort() != 80) ||
>   +                (data.getServerScheme().equals(HTTPS) &&
>   +                data.getServerPort() != 443))
>                {
>   -                output.append (':');
>   -                output.append (data.getServerPort());
>   +                output.append(':');
>   +                output.append(data.getServerPort());
>                }
>            }
>    
>   -        output.append (data.getScriptName());
>   +        output.append(data.getScriptName());
>    
>   -        if ( request.getPathInfo() != null )
>   +        if (request.getPathInfo() != null)
>            {
>                output.append(request.getPathInfo());
>            }
>    
>   -        if ( request.getQueryString() != null )
>   +        if (request.getQueryString() != null)
>            {
>   -            output.append ('?');
>   -            output.append (request.getQueryString());
>   +            output.append('?');
>   +            output.append(request.getQueryString());
>            }
>            return output.toString();
>   +    }
>   +
>   +    /**
>   +     * URL encodes <code>in</code> and writes it to <code>out</code>. If the
>   +     * string is null, 'null' will be written.
>   +     *
>   +     * @param in String to write.
>   +     * @param out Buffer to write to.
>   +     */
>   +    protected static final void writeEncoded(String in, StringBuffer out)
>   +    {
>   +        if (in == null || in.length() == 0)
>   +        {
>   +            out.append("null");
>   +            return;
>   +        }
>   +
>   +        // This is the most expensive operation:
>   +
>   +        byte[] bytes = in.getBytes();
>   +
>   +        for (int i = 0; i < bytes.length; i++)
>   +        {
>   +            char c = (char) bytes[i];
>   +
>   +            if ( safe[ c ] )
>   +            {
>   +                out.append(c);
>   +            }
>   +            else if (c == ' ')
>   +            {
>   +                out.append('+');
>   +            }
>   +            else
>   +            {
>   +                byte toEscape = bytes[i];
>   +                out.append('%');
>   +                int low = (int) (toEscape & 0x0f);
>   +                int high = (int) ((toEscape & 0xf0) >> 4);
>   +                out.append(hexadecimal[high]);
>   +                out.append(hexadecimal[low]);
>   +            }
>   +        }
>   +    }
>   +
>   +    // ------------------------------------- private constants for url encoding
>   +
>   +    /**
>   +     * Array mapping hexadecimal values to the corresponding ASCII characters.
>   +     */
>   +    private static final char[] hexadecimal =
>   +        {
>   +            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
>   +            'A', 'B', 'C', 'D', 'E', 'F'
>   +        };
>   +
>   +    /**
>   +     * Characters that need not be encoded. This is much faster than using a
>   +     * BitSet, and for such a small array the space cost seems justified.
>   +     */
>   +    private static boolean[] safe = new boolean[ 255 ];
>   +
>   +    /** Static initializer for {@link #safe} */
>   +    static
>   +    {
>   +        for (int i = 'a'; i <= 'z'; i++)
>   +        {
>   +            safe[ i ] = true;
>   +        }
>   +        for (int i = 'A'; i <= 'Z'; i++)
>   +        {
>   +            safe[ i ] = true;
>   +        }
>   +        for (int i = '0'; i <= '9'; i++)
>   +        {
>   +            safe[ i ] = true;
>   +        }
>   +
>   +        safe['-'] = true;
>   +        safe['_'] = true;
>   +        safe['.'] = true;
>   +        safe['!'] = true;
>   +        safe['~'] = true;
>   +        safe['*'] = true;
>   +        safe['\''] = true;
>   +        safe['('] = true;
>   +        safe[')'] = true;
>        }
>    }
>   
>   
>   
> 
> --
> To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
> 
> 



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

Reply via email to