webwork/src/main/webwork/util URLCodec.java,NONE,1.1 Encoding.java,NONE,1.1

[email protected] Tue, 16 May 2006 00:34:11 -0700
Newsgroups gmane.comp.java.open-symphony.cvs
Message-ID <[email protected]>
Update of /cvsroot/opensymphony/webwork/src/main/webwork/util
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv22536/src/main/webwork/util

Added Files:
	URLCodec.java Encoding.java 
Log Message:
Encode URLs using webwork's encoding, and not the system encoding.  This fixes a number of bugs in JIRA :)
I'd raise an issue in Webwork's JIRA instance, but I can't seem to find it now...

--- NEW FILE: URLCodec.java ---
package webwork.util;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.BitSet;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;

/**
 * <p>Implements the 'www-form-urlencoded' encoding scheme,
 * also misleadingly known as URL encoding.</p>
 * <p/>
 * <p>For more detailed information please refer to
 * <a href="http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1">
 * Chapter 17.13.4 'Form content types'</a> of the
 * <a href="http://www.w3.org/TR/html4/">HTML 4.01 Specification<a></p>
 * <p/>
 * <p/>
 * This codec is meant to be a replacement for standard Java classes
 * {@link java.net.URLEncoder} and {@link java.net.URLDecoder}
 * on older Java platforms, as these classes in Java versions below
 * 1.4 rely on the platform's default charset encoding.
 * </p>
 * <p>
 * This class was copied from Apache, with some modifications
 * </p>
 *
 * @author Apache Software Foundation
 */
public class URLCodec
{

    protected static Log log = LogFactory.getLog(URLCodec.class);

    protected static byte ESCAPE_CHAR = '%';
    /**
     * BitSet of www-form-url safe characters.
     */
    protected static final BitSet WWW_FORM_URL = new BitSet(256);

    // Static initializer for www_form_url
    static
    {
        // alpha characters
        for (int i = 'a'; i <= 'z'; i++)
        {
            URLCodec.WWW_FORM_URL.set(i);
        }
        for (int i = 'A'; i <= 'Z'; i++)
        {
            URLCodec.WWW_FORM_URL.set(i);
        }
        // numeric characters
        for (int i = '0'; i <= '9'; i++)
        {
            URLCodec.WWW_FORM_URL.set(i);
        }
        // special chars
        URLCodec.WWW_FORM_URL.set('-');
        URLCodec.WWW_FORM_URL.set('_');
        URLCodec.WWW_FORM_URL.set('.');
        URLCodec.WWW_FORM_URL.set('*');
        // blank to be replaced with +
        URLCodec.WWW_FORM_URL.set(' ');
    }


    /**
     * Encodes an array of bytes into an array of URL safe 7-bit
     * characters. Unsafe characters are escaped.
     *
     * @param urlsafe bitset of characters deemed URL safe
     * @param bytes   array of bytes to convert to URL safe characters
     * @return array of bytes containing URL safe characters
     */
    public static byte[] encodeUrl(BitSet urlsafe, byte[] bytes)
    {
        if (bytes == null)
        {
            return null;
        }
        if (urlsafe == null)
        {
            urlsafe = URLCodec.WWW_FORM_URL;
        }

        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        for (int i = 0; i < bytes.length; i++)
        {
            int b = bytes[i];
            if (b < 0)
            {
                b = 256 + b;
            }
            if (urlsafe.get(b))
            {
                if (b == ' ')
                {
                    b = '+';
                }
                buffer.write(b);
            }
            else
            {
                buffer.write(URLCodec.ESCAPE_CHAR);
                char hex1 = Character.toUpperCase(Character.forDigit((b >> 4) & 0xF, 16));
                char hex2 = Character.toUpperCase(Character.forDigit(b & 0xF, 16));
                buffer.write(hex1);
                buffer.write(hex2);
            }
        }
        return buffer.toByteArray();
    }


    /**
     * Decodes an array of URL safe 7-bit characters into an array of
     * original bytes. Escaped characters are converted back to their
     * original representation.
     *
     * @param bytes array of URL safe characters
     * @return array of original bytes
     * @throws java.io.UnsupportedEncodingException Thrown if URL decoding is unsuccessful
     */
    public static byte[] decodeUrl(byte[] bytes) throws UnsupportedEncodingException
    {
        if (bytes == null)
        {
            return null;
        }
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        for (int i = 0; i < bytes.length; i++)
        {
            int b = bytes[i];
            if (b == '+')
            {
                buffer.write(' ');
            }
            else if (b == URLCodec.ESCAPE_CHAR)
            {
                try
                {
                    int u = Character.digit((char) bytes[++i], 16);
                    int l = Character.digit((char) bytes[++i], 16);
                    if (u == -1 || l == -1)
                    {
                        throw new UnsupportedEncodingException("Invalid URL encoding");
                    }
                    buffer.write((char) ((u << 4) + l));
                }
                catch (ArrayIndexOutOfBoundsException e)
                {
                    throw new UnsupportedEncodingException("Invalid URL encoding");
                }
            }
            else
            {
                buffer.write(b);
            }
        }
        return buffer.toByteArray();
    }


    /**
     * Encodes an array of bytes into an array of URL safe 7-bit
     * characters. Unsafe characters are escaped.
     *
     * @param bytes array of bytes to convert to URL safe characters
     * @return array of bytes containing URL safe characters
     */
    public static byte[] encode(byte[] bytes)
    {
        return URLCodec.encodeUrl(URLCodec.WWW_FORM_URL, bytes);
    }


    /**
     * Decodes an array of URL safe 7-bit characters into an array of
     * original bytes. Escaped characters are converted back to their
     * original representation.
     *
     * @param bytes array of URL safe characters
     * @return array of original bytes
     * @throws java.io.UnsupportedEncodingException Thrown if URL decoding is unsuccessful
     */
    public static byte[] decode(byte[] bytes) throws UnsupportedEncodingException
    {
        return URLCodec.decodeUrl(bytes);
    }


    /**
     * Encodes a string into its URL safe form using the specified
     * string charset. Unsafe characters are escaped.
     *
     * @param pString string to convert to a URL safe form
     * @param charset the charset for pString
     * @return URL safe string
     * @throws java.io.UnsupportedEncodingException Thrown if charset is not
     *                                      supported
     */
    public static String encode(String pString, String charset) throws UnsupportedEncodingException
    {
        if (pString == null)
        {
            return null;
        }
        return new String(URLCodec.encode(pString.getBytes(charset)), "US-ASCII");
    }


    /**
     * Encodes a string into its URL safe form using the default string
     * charset. Unsafe characters are escaped.
     *
     * @param pString string to convert to a URL safe form
     * @return URL safe string
     * @throws java.io.UnsupportedEncodingException Thrown if URL encoding is unsuccessful
     * @see #getWebworkDefaultCharset()
     */
    public static String encode(String pString)
    {
        if (pString == null)
        {
            return null;
        }

        try
        {
            return URLCodec.encode(pString, URLCodec.getWebworkDefaultCharset());
        }
        catch (UnsupportedEncodingException e)
        {
            log.warn("UnsupportedEncodingException whilst using encoding '" + URLCodec.getWebworkDefaultCharset() + "' ", e);
            return pString;
        }
    }


    /**
     * Decodes a URL safe string into its original form using the
     * specified encoding. Escaped characters are converted back
     * to their original representation.
     *
     * @param pString URL safe string to convert into its original form
     * @param charset the original string charset
     * @return original string
     * @throws java.io.UnsupportedEncodingException Thrown if charset is not
     *                                      supported
     */
    public static String decode(String pString, String charset) throws UnsupportedEncodingException
    {
        if (pString == null)
        {
            return null;
        }
        return new String(URLCodec.decode(pString.getBytes("US-ASCII")), charset);
    }


    /**
     * Decodes a URL safe string into its original form using the default
     * string charset. Escaped characters are converted back to their
     * original representation.
     *
     * @param pString URL safe string to convert into its original form
     * @return original string
     * @throws java.io.UnsupportedEncodingException Thrown if URL decoding is unsuccessful
     * @see #getWebworkDefaultCharset()
     */
    public static String decode(String pString) throws UnsupportedEncodingException
    {
        if (pString == null)
        {
            return null;
        }
        return URLCodec.decode(pString, URLCodec.getWebworkDefaultCharset());
    }

    /**
     * Encodes an object into its URL safe form. Unsafe characters are
     * escaped.
     *
     * @param pObject string to convert to a URL safe form
     * @return URL safe object
     * @throws java.io.UnsupportedEncodingException Thrown if URL encoding is not
     *                          applicable to objects of this type or
     *                          if encoding is unsuccessful
     */
    public static Object encode(Object pObject) throws UnsupportedEncodingException
    {
        if (pObject == null)
        {
            return null;
        }
        else if (pObject instanceof byte[])
        {
            return URLCodec.encode((byte[]) pObject);
        }
        else if (pObject instanceof String)
        {
            return URLCodec.encode((String) pObject);
        }
        else
        {
            throw new UnsupportedEncodingException("Objects of type " + pObject.getClass().getName() + " cannot be URL encoded");

        }
    }

    /**
     * Decodes a URL safe object into its original form. Escaped characters are converted back to their original
     * representation.
     *
     * @param pObject URL safe object to convert into its original form
     * @return original object
     * @throws java.io.UnsupportedEncodingException Thrown if the argument is not a <code>String</code> or <code>byte[]</code>. Thrown if a failure condition is
     *                          encountered during the decode process.
     */
    public static Object decode(Object pObject) throws UnsupportedEncodingException
    {
        if (pObject == null)
        {
            return null;
        }
        else if (pObject instanceof byte[])
        {
            return URLCodec.decode((byte[]) pObject);
        }
        else if (pObject instanceof String)
        {
            return URLCodec.decode((String) pObject);
        }
        else
        {
            throw new UnsupportedEncodingException("Objects of type " + pObject.getClass().getName() + " cannot be URL decoded");

        }
    }

    /**
     * The default charset used for string decoding and encoding.
     *
     * @return the default string charset.
     */
    private static String getWebworkDefaultCharset()
    {
        return Encoding.getEncoding();
    }

}

--- NEW FILE: Encoding.java ---
package webwork.util;

import webwork.config.Configuration;

/**
 * This class acts as a cache around webwork's encoding property
 */
public class Encoding
{
    private static String encoding;
    private static boolean encodingDefined = true;

    /**
     * Get the encoding specified by the property 'webwork.i18n.encoding' in webwork.properties,
     * or return the default platform encoding if not specified.
     * <p>
     * Note that if the property is not initially defined, this will return the system default,
     * even if the property is later defined.  This is mainly for performance reasons.  Undefined
     * properties throw exceptions, which are a costly operation.
     * <p>
     * If the property is initially defined, it is read every time, until is is undefined, and then
     * the system default is used.
     * <p>
     * Why not cache it completely?  Some applications will wish to be able to dynamically set the
     * encoding at runtime.
     *
     * @return  The encoding to be used.
     */
    public static String getEncoding()
    {
        if (encodingDefined)
        {
            try
            {
                encoding = Configuration.getString("webwork.i18n.encoding");
            }
            catch (IllegalArgumentException e)
            {
                encoding = System.getProperty("file.encoding");
                encodingDefined = false;
            }
        }
        return encoding;

    }
}



-------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642