jicarilla-sandbox/platform/components/http/api/src/java/org/jicarilla/http Encoding.java,NONE,1.1 ErrorHandler.java,NONE,1.1 Field.java,NONE,1.1 FileReader.java,NONE,1.1 Message.java,NONE,1.1 MessageHandler.java,NONE,1.1 MessageWriter.java,NONE,1.1 Parser.java,NONE,1.1 HTTPException.java,1.5,1.6 HTTPEncoding.java,1.5,NONE HTTPErrorHandler.java,1.2,NONE HTTPField.java,1.5,NONE HTTPFileReader.java,1.1,NONE HTTPHandler.java,1.5,NONE HTTPMessage.java,1.6,NONE HTTPMessageWriter.java,1.2,NONE HTTPParser.java,1.4,NONE

Leo Simons <[email protected]>
Newsgroups gmane.comp.java.jicarilla.cvs
Message-ID <[email protected]>
Update of /cvsroot/jicarilla/jicarilla-sandbox/platform/components/http/api/src/java/org/jicarilla/http
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18181/platform/components/http/api/src/java/org/jicarilla/http

Modified Files:
	HTTPException.java 
Added Files:
	Encoding.java ErrorHandler.java Field.java FileReader.java 
	Message.java MessageHandler.java MessageWriter.java 
	Parser.java 
Removed Files:
	HTTPEncoding.java HTTPErrorHandler.java HTTPField.java 
	HTTPFileReader.java HTTPHandler.java HTTPMessage.java 
	HTTPMessageWriter.java HTTPParser.java 
Log Message:
remove the HTTP prefix from nearly every class and interface. Less typing, cleaner reading :-D

--- HTTPMessageWriter.java DELETED ---

--- HTTPMessage.java DELETED ---

--- NEW FILE: MessageWriter.java ---
/* ====================================================================
 The Jicarilla Software License

 Copyright (c) 2003 Leo Simons.
 All rights reserved.

 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to
 permit persons to whom the Software is furnished to do so, subject to
 the following conditions:

 The above copyright notice and this permission notice shall be
 included in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
==================================================================== */
package org.jicarilla.http;

import java.io.IOException;
import java.nio.channels.WritableByteChannel;

/**
 *
 *
 * @author <a href="lsimons at jicarilla dot org">Leo Simons</a>
 * @version $Id: MessageWriter.java,v 1.1 2004/04/09 15:52:09 lsimons Exp $
 */
public interface MessageWriter
{
    void write( Message message, WritableByteChannel channel )
            throws HTTPException, IOException;
    void write( Message message, WritableByteChannel channel, boolean close )
            throws HTTPException, IOException;
}

--- NEW FILE: Encoding.java ---
/* ====================================================================
 The Jicarilla Software License

 Copyright (c) 2003 Leo Simons.
 All rights reserved.

 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to
 permit persons to whom the Software is furnished to do so, subject to
 the following conditions:

 The above copyright notice and this permission notice shall be
 included in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
==================================================================== */
package org.jicarilla.http;

import org.jicarilla.http.util.Iso646;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * This class provides basic encoding information for the HTTP 1.1
 * specification,
 * <a href=""http://www.ietf.org/rfc/rfc2616.txt>RFC 2616</a>.
 * The HTTP specifications are published by the
 * <a href="http://www.ietf.org/">Internet Engineering Taskforce</a>.
 *
 * Note that this class contains some documentation snippets from the
 * mentioned standard.
 *
 * @todo chunked transfer coding specification
 * @todo media types spec
 * @todo product tokens spec
 * @todo quality values spec
 * @todo language tags spec
 * @todo entity tags spec
 * @todo range units
 * @todo common headers
 * @todo rest of the spec
 * @todo clean up and document the utility methods
 *
 * @author <a href="mailto: lsimons at jicarilla dot org">Leo Simons</a>
 * @version $Id: Encoding.java,v 1.1 2004/04/09 15:52:08 lsimons Exp $
 */
public class Encoding
{
    //
    // SIMPLE CHARACTER CLASS SHORTHANDS
    //

    /** carriage return */
    public final static char CR = Iso646.CARRIAGE_RETURN;
    /** linefeed */
    public final static char LF = Iso646.LINE_FEED;
    /** space */
    public final static char SP = Iso646.SPACE;
    /** tab */
    public final static char HT = Iso646.HORIZONTAL_TABULATION;
    /** double quote (") */
    public final static char DQ = Iso646.QUOTATION_MARK;

    /** all ASCII characters */
    public final static char[] CHAR = Iso646.CHAR;
    /** all ASCII uppercase letters */
    public final static char[] UPALPHA = Iso646.UPALPHA;
    /** all ASCII lowercase letters */
    public final static char[] LOALPHA = Iso646.LOALPHA;
    /** all ASCII letters */
    public final static char[] ALPHA = Iso646.ALPHA;
    /** all ASCII digits */
    public final static char[] DIGIT = Iso646.DIGIT;
    /** all ASCII control characters */
    public final static char[] CTL = Iso646.CTL;

    //
    // CHARACTER CLASSES CONTAINING THE ALLOWED CHARACTERS
    // FOR THE VARIOUS ENTITIES IN RFC2616
    //

    /**
     * carriage return and line feed characters.
     *
     * HTTP/1.1 defines the sequence CR LF as the end-of-line
     * marker for all protocol elements except the entity-body
     * (see appendix 19.3 of RFC2616 for tolerant applications).
     * The end-of-line marker within an entity-body is defined
     * by its associated media type, as described in section 3.7
     * of RFC2616.
     *
     * note: doesn't encode that a new line is only defined when
     * CR & LF appear in sequence.
     */
    public final static char[] CRLF = new char[] { CR, LF };

    /**
     * lineair whitespace characters. note: doesn't encode that
     * CR & LF may only appear once,
     * at the beginning, and in sequence.
     *
     * HTTP/1.1 header field values can be folded onto multiple
     * lines if the continuation line begins with a space or
     * horizontal tab. All linear white space, including folding,
     * has the same semantics as SP. A recipient MAY replace any
     * linear white space with a single SP before interpreting the
     * field value or forwarding the message downstream.
     */
    public final static char[] LWS = new char[] { CR, LF, SP, HT };

    /**
     *  The TEXT rule is only used for descriptive field contents and
     * values that are not intended to be interpreted by the message
     * parser. Words of *TEXT MAY contain characters from character
     * sets other than ISO-8859-1 only when encoded according
     * to the rules of
     * <a href="http://www.ietf.org/rfc/rfc2047.txt">RFC 2047</a>.
     *
     * A CRLF is allowed in the definition of TEXT only as part of a
     * header field continuation. It is expected that the folding LWS
     * will be replaced with a single SP before interpretation of the
     * TEXT value.
     *
     * @see org.jicarilla.http.util.Iso8859_1
     * @see http://www.ietf.org
     */
    public final static char[] TEXT;

    /**
     * Hexadecimal numeric characters are used in several protocol
     * elements.
     */
    public final static char[] HEX;

    /**
     * Many HTTP/1.1 header field values consist of words separated by
     * LWS or special characters. These special characters MUST be in a
     * quoted string to be used within a parameter value (as defined in
     * section 3.6 of RFC2616).
     */
    public final static char[] separators = new char[] {
        Iso646.LEFT_PARENTHESIS,
        Iso646.RIGHT_PARENTHESIS,
        Iso646.GREATER_THAN_SIGN,
        Iso646.LESS_THAN_SIGN,
        Iso646.COMMERCIAL_AT,
        Iso646.COMMA,
        Iso646.SEMICOLON,
        Iso646.COLON,
        Iso646.SOLIDUS,
        Iso646.LEFT_SQUARE_BRACKET,
        Iso646.RIGHT_SQUARE_BRACKET,
        Iso646.QUESTION_MARK,
        Iso646.EQUALS_SIGN,
        Iso646.LEFT_CURLY_BRACKET,
        Iso646.RIGHT_CURLY_BRACKET,
        SP,
        HT
    };

    /**
     * A token is any character or sequence of characters which is not
     * a seperator or control character.
     */
    public final static char[] token;

    /**
     * Text contained in a comment. Can be any TEXT except the
     * comment boundary characters '(' and ')'.
     */
    public final static char[] ctext;

    /**
     * Comments can be included in some HTTP header fields by surrounding
     * the comment text with parentheses. Comments are only allowed in
     * fields containing "comment" as part of their field value definition.
     * In all other fields, parentheses are considered part of the field
     * value.
     *
     * note: doesn't encode that the string must begin with '(' and
     * end with ')' and cannot contain ')' anywhere but as the last
     * character.
     */
    public final static char[] comment;

    /**
     * Text contained in a quote. Can be any TEXT except the
     * quote boundary character '"'.
     */
    public final static char[] qdtext;

    /**
     * A string of text is parsed as a single word if it is quoted using
     * double-quote marks.
     *
     * note: doesn't encode that the string must begin with '"' and
     * end with '"', and cannot contain '"' anywhere but as the last
     * character or when escaped by a '\', and can contain non-TEXT
     * characters only when preceeded a '\'.
     */
    public final static char[] quoted_string;

    /**
     * The backslash character ("\") MAY be used as a single-character
     * quoting mechanism only within quoted-string and comment constructs.
     *
     * note: doesn't encode that the string must consist of a
     * backslash as the first character and any other character as
     * the second character.
     */
    public final static char[] quoted_pair;

    /**
     * HTTP uses a "<major>.<minor>" numbering scheme to indicate
     * versions of the protocol.
     *
     * note: doesn't encode the specific sequence of the HTTP
     * version string.
     */
    public final static char[] VERSION;

    /**
     * Note the absence of an URI property here. This is because the
     * URI spec currently potentially allows *any* character (in any
     * character set) to be a valid part of an URI.
     */

    /**
     * HTTP applications have historically allowed three different formats
     * for the representation of date/time stamps.
     *
     * note: doesn't encode the actual requirment as to how the date
     * is to be encoded, just lists the acceptable characters.
     */
    public final static char[] DATE;

    /**
     * HTTP character sets are identified by case-insensitive tokens.
     * The complete set of tokens is defined by the IANA Character Set
     * registry.
     */
    public final static char[] charset;

    /**
     * Content coding values indicate an encoding transformation that has
     * been or can be applied to an entity.  All content-coding values are
     * case-insensitive.
     */
    public final static char[] content_coding;

    /**
     * Transfer-coding values are used to indicate an encoding
     * transformation that has been, can be, or may need to be applied to an
     * entity-body in order to ensure "safe transport" through the network.
     */
    public final static char[] transfer_coding;

    public final static int OFFSET_OF_NORMAL_CHARACTERS_IN_ASCII = 0x20;
    public final static int NUMBER_OF_TEXT_CHARACTERS = 127-32;
    public final static int NUMBER_OF_HEX_CHARACTERS = 6+6+10;
    public final static int NUMBER_OF_VERSION_CHARACTERS = 15;
    public final static int NUMBER_OF_TOKEN_CHARACTERS = 80;
    // fill in the above character classes
    static
    {
        int index;

        TEXT = new char[NUMBER_OF_TEXT_CHARACTERS];
        for( int i = 0; i < TEXT.length; i++ )
        {
            TEXT[i] = (char) (i + OFFSET_OF_NORMAL_CHARACTERS_IN_ASCII);
        }
        Arrays.sort(TEXT);

        HEX = new char[NUMBER_OF_HEX_CHARACTERS];
        for( int i = 0; i < 7; i++ )
            HEX[i] = UPALPHA[i];
        for( int i = 0; i < 7; i++ )
            HEX[i+6] = LOALPHA[i];
        for( int i = 0; i < 10; i++ )
            HEX[i+6+6] = DIGIT[i];
        Arrays.sort(HEX);

        Arrays.sort(separators);

        // won't work:
        // token = new char[(CHAR.length-CTL.length)-separators.length-2];
        token = new char[NUMBER_OF_TOKEN_CHARACTERS];
        index = 0;
        for( int i = 0; i < CHAR.length; i++)
        {
            if( Arrays.binarySearch( separators, CHAR[i] ) >= 0 )
                continue;
            if( Arrays.binarySearch( CTL, CHAR[i] ) >= 0 )
                continue;

            token[index] = CHAR[i];
            index++;
        }
        Arrays.sort(token);

        ctext = new char[TEXT.length-2];
        index = 0;
        for( int i = 0; i < TEXT.length; i++ )
        {
            if( TEXT[i] == Iso646.LEFT_PARENTHESIS ||
                    TEXT[i] == Iso646.RIGHT_PARENTHESIS )
                continue;
            ctext[index++] = TEXT[i];
        }
        Arrays.sort(ctext);

        qdtext = new char[TEXT.length-1];
        index = 0;
        for( int i = 0; i < TEXT.length; i++ )
        {
            if( TEXT[i] == Iso646.QUOTATION_MARK )
                continue;
            qdtext[index++] = TEXT[i];
        }
        Arrays.sort(qdtext);

        comment = TEXT;
        quoted_string = CHAR;
        quoted_pair = CHAR;

        VERSION = new char[NUMBER_OF_VERSION_CHARACTERS];
        VERSION[0] = Iso646.LATIN_CAPITAL_LETTER_H;
        VERSION[1] = Iso646.LATIN_CAPITAL_LETTER_T;
        VERSION[2] = Iso646.LATIN_CAPITAL_LETTER_P;
        VERSION[3] = Iso646.SOLIDUS;
        VERSION[4] = Iso646.FULL_STOP;

        for( int i = 0; i < DIGIT.length; i++ )
            VERSION[5+i] = DIGIT[i];
        Arrays.sort(VERSION);

        DATE = new char[] {
            Iso646.DIGIT_ONE,
            Iso646.DIGIT_TWO,
            Iso646.DIGIT_THREE,
            Iso646.DIGIT_FOUR,
            Iso646.DIGIT_FIVE,
            Iso646.DIGIT_SIX,
            Iso646.DIGIT_SEVEN,
            Iso646.DIGIT_EIGHT,
            Iso646.DIGIT_NINE,
            Iso646.DIGIT_ZERO,
            Iso646.LATIN_CAPITAL_LETTER_M,
            Iso646.LATIN_CAPITAL_LETTER_T,
            Iso646.LATIN_CAPITAL_LETTER_W,
            Iso646.LATIN_CAPITAL_LETTER_F,
            Iso646.LATIN_CAPITAL_LETTER_S,
            Iso646.LATIN_CAPITAL_LETTER_J,
            Iso646.LATIN_CAPITAL_LETTER_A,
            Iso646.LATIN_CAPITAL_LETTER_O,
            Iso646.LATIN_CAPITAL_LETTER_N,
            Iso646.LATIN_SMALL_LETTER_O,
            Iso646.LATIN_SMALL_LETTER_N,
            Iso646.LATIN_SMALL_LETTER_U,
            Iso646.LATIN_SMALL_LETTER_E,
            Iso646.LATIN_SMALL_LETTER_D,
            Iso646.LATIN_SMALL_LETTER_H,
            Iso646.LATIN_SMALL_LETTER_R,
            Iso646.LATIN_SMALL_LETTER_I,
            Iso646.LATIN_SMALL_LETTER_A,
            Iso646.LATIN_SMALL_LETTER_T,
            Iso646.LATIN_SMALL_LETTER_Y,
            Iso646.LATIN_SMALL_LETTER_B,
            Iso646.LATIN_SMALL_LETTER_P,
            Iso646.LATIN_SMALL_LETTER_L,
            Iso646.LATIN_SMALL_LETTER_G,
            Iso646.LATIN_SMALL_LETTER_C,
            Iso646.LATIN_SMALL_LETTER_V,
            Iso646.COLON,
            Iso646.HYPHEN_MINUS,
            Iso646.SPACE,
            Iso646.LATIN_CAPITAL_LETTER_G
        };
        Arrays.sort(DATE);

        charset = token;
        content_coding = token;
        transfer_coding = CHAR;
    }

    //
    // COMMONLY USED HTTP VERSIONS
    //
    public final static String VERSION_10 = "HTTP/1.0";
    public final static String VERSION_11 = "HTTP/1.1";

    //
    // COMMONLY USED HTTP METHODS
    //
    public final static String METHOD_OPTIONS = "OPTIONS";
    public final static String METHOD_GET = "GET";
    public final static String METHOD_HEAD = "HEAD";
    public final static String METHOD_POST = "POST";
    public final static String METHOD_PUT = "PUT";
    public final static String METHOD_DELETE = "DELETE";
    public final static String METHOD_TRACE = "TRACE";
    public final static String METHOD_CONNECT = "CONNECT";

    //
    // COMMONLY USED CONTENT CODINGS
    //
    public final static String CONTENT_CODING = "content-coding";
    public final static String CONTENT_CODING_GZIP = "gzip";
    public final static String CONTENT_CODING_COMPRESS = "compress";
    public final static String CONTENT_CODING_DEFLATE = "deflate";
    public final static String CONTENT_CODING_IDENTITY = "identity";

    //
    // COMMONLY USED TRANSFER CODINGS
    //
    public final static String TRANSFER_CODING = "transfer-coding";
    public final static String TRANSFER_CODING_CHUNKED = "chunked";
    public final static String TRANSFER_CODING_GZIP = "gzip";
    public final static String TRANSFER_CODING_COMPRESS = "compress";
    public final static String TRANSFER_CODING_DEFLATE = "deflate";
    public final static String TRANSFER_CODING_IDENTITY = "identity";

    //
    // HTTP ERROR CODES
    //
    public final static int
        STATUS_100_Continue = 100,
        STATUS_101_Switching_Protocols = 101,
        STATUS_102_Processing = 102,
        STATUS_200_OK = 200,
        STATUS_201_Created = 201,
        STATUS_202_Accepted = 202,
        STATUS_203_Non_Authoritative_Information = 203,
        STATUS_204_No_Content = 204,
        STATUS_205_Reset_Content = 205,
        STATUS_206_Partial_Content = 206,
        STATUS_207_Multi_Status = 207,
        STATUS_300_Multiple_Choices = 300,
        STATUS_301_Moved_Permanently = 301,
        STATUS_302_Moved_Temporarily = 302,
        STATUS_303_See_Other = 303,
        STATUS_304_Not_Modified = 304,
        STATUS_305_Use_Proxy = 305,
        STATUS_400_Bad_Request = 400,
        STATUS_401_Unauthorized = 401,
        STATUS_402_Payment_Required = 402,
        STATUS_403_Forbidden = 403,
        STATUS_404_Not_Found = 404,
        STATUS_405_Method_Not_Allowed = 405,
        STATUS_406_Not_Acceptable = 406,
        STATUS_407_Proxy_Authentication_Required = 407,
        STATUS_408_Request_Timeout = 408,
        STATUS_409_Conflict = 409,
        STATUS_410_Gone = 410,
        STATUS_411_Length_Required = 411,
        STATUS_412_Precondition_Failed = 412,
        STATUS_413_Request_Entity_Too_Large = 413,
        STATUS_414_Request_URI_Too_Large = 414,
        STATUS_415_Unsupported_Media_Type = 415,
        STATUS_416_Requested_Range_Not_Satisfiable = 416,
        STATUS_417_Expectation_Failed = 417,
        STATUS_422_Unprocessable_Entity = 422,
        STATUS_423_Locked = 423,
        STATUS_424_Failed_Dependency = 424,
        STATUS_500_Internal_Server_Error = 500,
        STATUS_501_Not_Implemented = 501,
        STATUS_502_Bad_Gateway = 502,
        STATUS_503_Service_Unavailable = 503,
        STATUS_504_Gateway_Timeout = 504,
        STATUS_505_HTTP_Version_Not_Supported = 505,
        STATUS_507_Insufficient_Storage = 507;

    public final static int STATUS_999_IO_Problem = 999;

    //
    // HTTP ERROR MESSAGES
    //
    public final static String
            STATUS_100_MSG = "Continue",
            STATUS_101_MSG = "Switching Protocols",
            STATUS_102_MSG = "Processing",
            STATUS_200_MSG = "OK",
            STATUS_201_MSG = "Created",
            STATUS_202_MSG = "Accepted",
            STATUS_203_MSG = "Non Authoritative Information",
            STATUS_204_MSG = "No Content",
            STATUS_205_MSG = "Reset Content",
            STATUS_206_MSG = "Partial Content",
            STATUS_207_MSG = "Multi Status",
            STATUS_300_MSG = "Multiple Choices",
            STATUS_301_MSG = "Moved Permanently",
            STATUS_302_MSG = "Moved Temporarily",
            STATUS_303_MSG = "See Other",
            STATUS_304_MSG = "Not Modified",
            STATUS_305_MSG = "Use Proxy",
            STATUS_400_MSG = "Bad Request",
            STATUS_401_MSG = "Unauthorized",
            STATUS_402_MSG = "Payment Required",
            STATUS_403_MSG = "Forbidden",
            STATUS_404_MSG = "Not Found",
            STATUS_405_MSG = "Method Not Allowed",
            STATUS_406_MSG = "Not Acceptable",
            STATUS_407_MSG = "Proxy Authentication Required",
            STATUS_408_MSG = "Request Timeout",
            STATUS_409_MSG = "Conflict",
            STATUS_410_MSG = "Gone",
            STATUS_411_MSG = "Length Required",
            STATUS_412_MSG = "Precondition Failed",
            STATUS_413_MSG = "Request Entity Too Large",
            STATUS_414_MSG = "Request URI Too Large",
            STATUS_415_MSG = "Unsupported Media Type",
            STATUS_416_MSG = "Requested Range Not Satisfiable",
            STATUS_417_MSG = "Expectation Failed",
            STATUS_422_MSG = "Unprocessable Entity",
            STATUS_423_MSG = "Locked",
            STATUS_424_MSG = "Failed Dependency",
            STATUS_500_MSG = "Internal Server Error",
            STATUS_501_MSG = "Not Implemented",
            STATUS_502_MSG = "Bad Gateway",
            STATUS_503_MSG = "Service Unavailable",
            STATUS_504_MSG = "Gateway Timeout",
            STATUS_505_MSG = "HTTP Version Not Supported",
            STATUS_507_MSG = "Insufficient Storage";

    public final static String STATUS_999_MSG = "IO Problem";

    public final static int NUMBER_OF_STATUS_MSG = 1000;
    public final static String[] STATUS_MSG = new String[NUMBER_OF_STATUS_MSG];
    static
    {
        // perform some runtime-introspection to getEntry all those
        // status messages listed above into the indexed array
        // STATUS_MSG
        final Field[] fields = Encoding.class.getFields();
        for( int i = 0; i < fields.length; i++ )
        {
            final Pattern pattern = Pattern.compile( "STATUS_([0-9][0-9][0-9])_MSG" );
            if(
                    Modifier.isStatic( fields[i].getModifiers() ) &&
                    Modifier.isFinal( fields[i].getModifiers() ) &&
                    Modifier.isPublic( fields[i].getModifiers() ) &&
                    fields[i].getType().equals( String.class ) )
            {
                final Matcher matcher = pattern.matcher( fields[i].getName() );
                if(matcher.matches())
                {
                    final String code = matcher.group(1);
                    final int num = (new Integer( code )).intValue();
                    try
                    {
                        STATUS_MSG[num] = (String)fields[i].get( null );
                    }
                    catch( IllegalAccessException iae ) {}
                }
            }
        }

        // fill 'er up with defaults
        /* actually, lets not...there might be apps
           with custom codes and messages...

        for( int i = 0; i < STATUS_MSG.length; i++ )
        {
            if( STATUS_MSG[i] == null )
                STATUS_MSG[i] = STATUS_500_MSG;
        }*/
    }

    //
    // CHARACTER CODINGS
    //
    /** Character set used to encode HTTP protocol elements */
    public static final String USASCII_CHARSET = "US-ASCII";

    /** Default content encoding chatset */
    public static final String ISO8859_1_CONTENT_CHARSET = "ISO-8859-1";

    //
    // COMMON HEADERS
    //
    public static final String HEADER_CONTENT_LENGTH = "content-length";
    public static final String HEADER_TRANSFER_ENCODING = "transfer-encoding";
    public static final String HEADER_TRAILER = "trailer";

    public static final ByteBuffer HEADER_CONTENT_LENGTH_BUFFER;

    static
    {
        final byte[] arr = HEADER_CONTENT_LENGTH.getBytes();
        HEADER_CONTENT_LENGTH_BUFFER = ByteBuffer.wrap( arr );
    }


    //
    // UTILITY METHODS
    //
    /**
     * Determine whether the specified character is a control
     * character.
     *
     * @param c the character to test
     * @return true if it is, false otherwise
     */
    public final static boolean isControlChar( final char c )
    {
        if( Arrays.binarySearch( CTL, c ) >= 0 )
            return true;

        return false;
    }
    /**
     * Determine whether the specified character is a separator
     * character.
     *
     * @param c the character to test
     * @return true if it is, false otherwise
     */
    public final static boolean isSeparatorChar( final char c )
    {
        if( Arrays.binarySearch( separators, c ) >= 0 )
            return true;

        return false;
    }
    /**
     * Determine whether the specified character is a token
     * character.
     *
     * @param c the character to test
     * @return true if it is, false otherwise
     */
    public final static boolean isTokenChar( final char c )
    {
        if( !isSeparatorChar( c ) && !isControlChar( c ) )
            return true;

        return false;
    }
    /**
     * Determine whether the specified character is a text
     * character.
     *
     * @param c the character to test
     * @return true if it is, false otherwise
     */
    public final static boolean isTextChar( final char c )
    {
        return !isControlChar( c );
    }
    /**
     * Determine whether the specified character is a method
     * character.
     *
     * @param c the character to test
     * @return true if it is, false otherwise
     */
    public final static boolean isMethodChar( final char c )
    {
        return isTokenChar( c );
    }
    /**
     * Determine whether the specified character is a linear
     * whitespace character.
     *
     * @param c the character to test
     * @return true if it is, false otherwise
     */
    public final static boolean isLWSChar( final char c )
    {
        return c == CR || c == LF || c == SP || c == HT;
    }
    /**
     * Determine whether the specified character is a status code
     * character.
     *
     * @param c the character to test
     * @return true if it is, false otherwise
     */
    public final static boolean isStatusCodeChar( final char c )
    {
        if( Arrays.binarySearch( DIGIT, c ) >= 0 )
            return true;

        return false;
    }
    /**
     * Determine whether the specified character is a reason phrase
     * character.
     *
     * @param c the character to test
     * @return true if it is, false otherwise
     */
    public final static boolean isReasonPhraseChar( final char c )
    {
        if( Arrays.binarySearch( TEXT, c ) < 0 )
            return false;
        if( c == CR || c == LF )
            return false;

        return true;
    }
    /**
     * Returns true if the character is allowed in a URI, false
     * otherwise. Note that it <i>does</i> allow "#" and "%", but
     * not " "!
     *
     * From RFC 2396:
     *
2.4.3. Excluded US-ASCII Characters

   Although they are disallowed within the URI syntax, we include here a
   description of those US-ASCII characters that have been excluded and
   the reasons for their exclusion.

   The control characters in the US-ASCII coded character set are not
   used within a URI, both because they are non-printable and because
   they are likely to be misinterpreted by some control mechanisms.

   control     = <US-ASCII coded characters 00-1F and 7F hexadecimal>

   The space character is excluded because significant spaces may
   disappear and insignificant spaces may be introduced when URI are
   transcribed or typeset or subjected to the treatment of word-
   processing programs.  Whitespace is also used to delimit URI in many
   contexts.

   space       = <US-ASCII coded character 20 hexadecimal>

   The angle-bracket "<" and ">" and double-quote (") characters are
   excluded because they are often used as the delimiters around URI in
   text documents and protocol fields.  The character "#" is excluded
   because it is used to delimit a URI from a fragment identifier in URI
   references (Section 4). The percent character "%" is excluded because
   it is used for the encoding of escaped characters.

   delims      = "<" | ">" | "#" | "%" | <">
     *
     * @param c the character to test
     * @return true if it is a valid URI char, false otherwise
     */
    public final static boolean isURIChar( final char c )
    {
        if( isControlChar( c ) )
            return false;
        if( c == Iso646.LESS_THAN_SIGN ||
                c == Iso646.GREATER_THAN_SIGN ||
                c == Iso646.QUOTATION_MARK ||
                c == SP )
            return false;

        return true;
    }
    /**
     * Determine whether the specified character is a version specifier
     * character.
     *
     * @param c the character to test
     * @return true if it is, false otherwise
     */
    public final static boolean isVersionChar( final char c )
    {
        final int contained = Arrays.binarySearch( VERSION, c );
        if( contained >= 0 )
            return true;

        return false;
    }
    /**
     * Nearly fully compliant verification of HTTP version
     * strings.
     *
     * @param s
     * @return
     */
    public final static boolean isVersionString( final String s )
    {
        if( s == null )
            return false;

        if( s.length() < 7)
            return false;

        if( s.charAt(0) != Iso646.LATIN_CAPITAL_LETTER_H |
            s.charAt(1) != Iso646.LATIN_CAPITAL_LETTER_T |
            s.charAt(2) != Iso646.LATIN_CAPITAL_LETTER_T |
            s.charAt(3) != Iso646.LATIN_CAPITAL_LETTER_P )
                return false;

        if( s.indexOf( Iso646.SOLIDUS ) < 5 )
                return false;

        for( int i = 4; i < s.length(); i++ )
            if( !isVersionChar( s.charAt(i) ) )
                return false;

        return true;
    }

    public final static int getMajorVersion( final String versionString )
    {
        if( !isVersionString(versionString) )
            throw new IllegalArgumentException( "Not a valid HTTP version string!" );

        final StringBuffer version = new StringBuffer();
        int index = 4;
        while(true)
        {
            final char c = versionString.charAt( index++ );
            if( c == Iso646.SOLIDUS ) break;

            version.append( c );
        }

        return new Integer( version.toString() ).intValue();
    }
    public final static int getMinorVersion( final String versionString )
    {
        if( !isVersionString(versionString) )
            throw new IllegalArgumentException( "Not a valid HTTP version string!" );

        return new Integer(
                versionString.substring( versionString.indexOf( Iso646.SOLIDUS ) ) ).intValue();
    }

    public final static int NUMBER_OF_CHARS_TO_SHIFT_ASCII_UPPER_TO_LOWER = 32;
    public final static char tokenCharToLowerCase( final char token )
    {
        if(     token >= Iso646.LATIN_CAPITAL_LETTER_A &&
                token <= Iso646.LATIN_CAPITAL_LETTER_Z)
            return (char)(token + NUMBER_OF_CHARS_TO_SHIFT_ASCII_UPPER_TO_LOWER);

        return token;
    }
}

--- NEW FILE: FileReader.java ---
/* ====================================================================
The Jicarilla Software License

Copyright (c) 2003 Leo Simons.
All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
==================================================================== */
package org.jicarilla.http;

import java.io.IOException;

/**
 * 
 *
 * @author <a href="lsimons at jicarilla dot org">Leo Simons</a>
 * @version $Id: FileReader.java,v 1.1 2004/04/09 15:52:08 lsimons Exp $
 */
public interface FileReader
{
    int readFile( String file, Message res )
            throws IOException;
}

--- NEW FILE: ErrorHandler.java ---
/* ====================================================================
 The Jicarilla Software License

 Copyright (c) 2003 Leo Simons.
 All rights reserved.

 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to
 permit persons to whom the Software is furnished to do so, subject to
 the following conditions:

 The above copyright notice and this permission notice shall be
 included in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
==================================================================== */
package org.jicarilla.http;

/**
 * The error handler gets notified whenever the parser finds something
 * it cannot parse; almost always this indicates a badly formatted
 * request or response or some kind of IO problem.
 *
 * @author <a href="lsimons at jicarilla dot org">Leo Simons</a>
 * @version $Id: ErrorHandler.java,v 1.1 2004/04/09 15:52:08 lsimons Exp $
 */
public interface ErrorHandler
{
    void exceptionOccurred( HTTPException he ) throws HTTPException;
}

--- HTTPHandler.java DELETED ---

--- HTTPErrorHandler.java DELETED ---

--- NEW FILE: MessageHandler.java ---
/* ====================================================================
 The Jicarilla Software License

 Copyright (c) 2003 Leo Simons.
 All rights reserved.

 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to
 permit persons to whom the Software is furnished to do so, subject to
 the following conditions:

 The above copyright notice and this permission notice shall be
 included in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
==================================================================== */
package org.jicarilla.http;

import java.nio.ByteBuffer;

/**
 * The handler gets notified whenever the parser finds a new
 * element of a message. Handlers do *not* need to be
 * threadsafe.
 *
 * @author <a href="lsimons at jicarilla dot org">Leo Simons</a>
 * @version $Id: MessageHandler.java,v 1.1 2004/04/09 15:52:09 lsimons Exp $
 */
public interface MessageHandler
{
    /**
     * This method will be called by the parser to signal that
     * it will start providing the data of a new message that
     * is being received.
     */
    void newMessage();

    /**
     * This will be the second method called. In the case of
     * a request, this field will container the request
     * method. In the case of a response, this will be the
     * HTTP version.
     *
     * @param firstField the value of the first field
     */
    void foundStartLineFirstField( ByteBuffer firstField );

    /**
     * This will be the third method called. In the case of
     * a request, this field will contain the request
     * URI. In the case of a response, this field will contain
     * the status code.
     *
     * @param secondField the value of the second field
     */
    void foundStartLineSecondField( ByteBuffer secondField );

    /**
     * this will be the fourth method called. In the case of a
     * request, this field will contain the version. In the case
     * of a response, this field will contain the reason phrase.
     *
     * @param thirdField the value of the third field
     */
    void foundStartLineThirdField( ByteBuffer thirdField );

    /**
     * This method will be called zero or more times, once
     * for each header name, after the start line
     * has been parsed. It will be followed by a call to the
     * <code>foundHeaderValue()</code> method.
     *
     * @param header the name of the header that was found
     */
    void foundHeaderName( ByteBuffer header );

    /**
     * This method will be called zero or more times, once
     * for each header value, after the start line
     * has been parsed. It will always follow immediately after
     * the <code>foundHeaderName()</code> has been called.
     *
     * @param value the value of the header that was found
     */
    void foundHeaderValue( ByteBuffer value );

    /**
     * This method will be called once by the parser, after
     * all the headers have been found. If the return value
     * is {@link Parser.BODY_TYPE_NONE}, it will be
     * followed by a call to {@link #endMessage()}. If the
     * return value is {@link Parser.BODY_TYPE_NORMAL}, it
     * will be followed by a call to {@link #getBodySize()}. If
     * the return value is {@link Parser.BODY_TYPE_CHUNKING},
     * it will be followed by one or more calls to
     * {@link #foundBody(ByteBuffer)}.
     * 
     * @return an integer representing the body type that the
     *     parser should attempt to retrieve. Valid values are
     *     {@link Parser.BODY_TYPE_NONE},
     *     {@link Parser.BODY_TYPE_NORMAL} and
     *     {@link Parser.BODY_TYPE_CHUNKING}.
     */ 
    int getBodyType();

    /**
     * This method will be caleld once by the parser to determine
     * the size of the expected body, if and only if the call to
     * {@link #getBodyType()} returned {@link Parser.BODY_TYPE_NORMAL}.
     * 
     * @return an integer indicating the expected size of the body,
     *     in bytes.
     */ 
    int getBodySize();

    /**
     * This method will be called zero or more times, after
     * the request or response line and the headers have been
     * parsed. It will always follow after a call to
     * <code>foundHeaderValue()</code>.
     *
     * @param buffer part of the body of the message. Note
     *      that decoding of any Chunked transfer codings will
     *      have been done already.
     */
    void foundBody( ByteBuffer buffer );

    /**
     * This method will be called by the parser if
     * {@link #getBodyType()} returns
     * {@link Parser.BODY_TYPE_CHUNKING} to determine whether
     * any trailers will be present. It will be followed by a call
     * to the <code>getTrailerNames()</code> method if and only if
     * this method returns true. It will be followed by a call to
     * the <code>endMessage()</code> method if and only if this
     * method returns false.
     * 
     * @return true if there are trailers present, false otherwise.
     */ 
    boolean hasTrailers();

    /**
     * This method will be called once by the parser directly after
     * {@link #hasTrailers()} if and only if that method returned
     * true.
     * 
     * @return a non-empty array of non-null strings representing
     *     the trailers that will be present. 
     */ 
    String[] getTrailerNames();

    /**
     * This method will be called one or more times, once
     * for each trailer name, after the body
     * has been parsed, if and only if {@link #hasTrailers()} returned
     * true. It will be followed by a call to the
     * <code>foundTrailerValue()</code> method. Only trailer
     * names that have been returned from the parser's call to
     * {@link #getTrailerNames()} will be provided.
     *
     * @param trailer the name of the trailer that was found.
     */
    void foundTrailerName( ByteBuffer trailer );

    /**
     * This method will be called one or more times, once
     * for each footer value, after the body has been parsed, if and
     * only if {@link #hasTrailers()} returned
     * true. It will always follow immediately after
     * the <code>foundTrailerName()</code> has been called.
     *
     * @param value the value of the trailer that was found.
     */
    void foundTrailerValue( ByteBuffer value );

    /**
     * This method will be called by the parser to signal that
     * the current message has ended. It will always be called
     * exactly once.
     */
    void endMessage();

}

Index: HTTPException.java
===================================================================
RCS file: /cvsroot/jicarilla/jicarilla-sandbox/platform/components/http/api/src/java/org/jicarilla/http/HTTPException.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- HTTPException.java	23 Mar 2004 13:37:48 -0000	1.5
+++ HTTPException.java	9 Apr 2004 15:52:08 -0000	1.6
@@ -48,8 +48,8 @@
     // ----------------------------------------------------------------------
     //  Properties
     // ----------------------------------------------------------------------
-    public final static String DEFAULT_MESSAGE = HTTPEncoding.STATUS_500_MSG;
-    public final static int DEFAULT_CODE = HTTPEncoding.STATUS_500_Internal_Server_Error;
+    public final static String DEFAULT_MESSAGE = Encoding.STATUS_500_MSG;
+    public final static int DEFAULT_CODE = Encoding.STATUS_500_Internal_Server_Error;
     protected int m_code = DEFAULT_CODE;
 
     // ----------------------------------------------------------------------
@@ -57,11 +57,11 @@
     // ----------------------------------------------------------------------
     public HTTPException()
     {
-        super( HTTPEncoding.STATUS_MSG[DEFAULT_CODE] );
+        super( Encoding.STATUS_MSG[DEFAULT_CODE] );
     }
     public HTTPException( final int code )
     {
-        super( HTTPEncoding.STATUS_MSG[code] );
+        super( Encoding.STATUS_MSG[code] );
 
         m_code = code;
     }
@@ -71,7 +71,7 @@
     }
     public HTTPException( final int code, final Throwable t )
     {
-        super( HTTPEncoding.STATUS_MSG[code], t );
+        super( Encoding.STATUS_MSG[code], t );
 
         m_code = code;
     }

--- HTTPParser.java DELETED ---

--- NEW FILE: Message.java ---
/* ====================================================================
 The Jicarilla Software License

 Copyright (c) 2003 Leo Simons.
 All rights reserved.

 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to
 permit persons to whom the Software is furnished to do so, subject to
 the following conditions:

 The above copyright notice and this permission notice shall be
 included in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
==================================================================== */
package org.jicarilla.http;

import org.jicarilla.http.util.NioUtil;
import org.jicarilla.lang.Recyclable;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * JavaBean modelling an HTTP protocol message. Doesn't provide
 * argument verification.
 *
 * Can be used either to model a request or a response.
 *
 * @author <a href="mailto: lsimons at jicarilla dot org">Leo Simons</a>
 * @version $Id: Message.java,v 1.1 2004/04/09 15:52:09 lsimons Exp $
 */
public class Message implements Recyclable
{
    // ----------------------------------------------------------------------
    //  Properties
    // ----------------------------------------------------------------------
    public final static boolean TYPE_REQUEST = true;
    public final static boolean TYPE_RESPONSE = false;

    protected boolean m_isRequest = true;
    protected boolean m_isComplete = false;

    protected ByteBuffer m_field1;
    protected ByteBuffer m_field2;
    protected ByteBuffer m_field3;

    protected List m_headers;
    protected List m_bodyParts;

    // ----------------------------------------------------------------------
    //  Constructors
    // ----------------------------------------------------------------------
    /**
     * Default constructor.
     */
    public Message()
    {
        m_field1 = null;
        m_field2 = null;
        m_field3 = null;

        m_headers = new ArrayList();
        m_bodyParts = new LinkedList();
    }

    // ----------------------------------------------------------------------
    //  Getters/Setters
    // ----------------------------------------------------------------------
    /**
     * Mark whether this message models a request or a response.
     *
     * @param isRequest true if the message should behave like a
     *     request, false if it should behave like a response
     */
    public void setMessageType( final boolean isRequest )
    {
        m_isRequest = isRequest;
    }

    /**
     * Determine whether this message represents a request or a
     * response.
     *
     * @return true if the message represents a
     *     request, false if it represents a response
     *
     * @return
     */
    public boolean getMessageType()
    {
        return m_isRequest;
    }

    public boolean isComplete()
    {
        return m_isComplete;
    }

    public void setComplete( final boolean complete )
    {
        m_isComplete = complete;
    }

    /**
     * Set the first HTTP header line field.
     *
     * @param field the first HTTP header line field
     */
    public void setField1( final ByteBuffer field )
    {
        m_field1 = field;
    }

    /**
     * Get the first HTTP header line field.
     *
     * @return the field, or null if it hasn't been set
     */
    public ByteBuffer getField1()
    {
        return m_field1;
    }

    /**
     * Get the first HTTP header line field as a string.
     *
     * @return the field, or null if it hasn't been set
     */
    public String getField1String()
    {
        getField1().rewind();
        return NioUtil.toString( getField1() );
    }

    public void setField1( final String field )
    {
        setField1( NioUtil.toByteBuffer( field ) );
    }

    /**
     * Set the second HTTP header line field.
     *
     * @param field2 the second HTTP header line field
     */
    public void setField2( final ByteBuffer field2 )
    {
        m_field2 = field2;
    }

    /**
     * Get the second HTTP header line field.
     *
     * @return the field, or null if it hasn't been set
     */
    public ByteBuffer getField2()
    {
        return m_field2;
    }

    /**
     * Get the second HTTP header line field as a string.
     *
     * @return the field, or null if it hasn't been set
     */
    public String getField2String()
    {
        getField2().rewind();
        return NioUtil.toString( getField2() );
    }

    public void setField2( final String field )
    {
        setField2( NioUtil.toByteBuffer( field ) );
    }
    /**
     * Set the third HTTP header line field.
     *
     * @param field the third HTTP header line field
     */
    public void setField3( final ByteBuffer field )
    {
        m_field3 = field;
    }

    /**
     * Get the third HTTP header line field.
     *
     * @return the field, or null if it hasn't been set
     */
    public ByteBuffer getField3()
    {
        return m_field3;
    }

    /**
     * Get the third HTTP header line field as a string.
     *
     * @return the field, or null if it hasn't been set
     */
    public String getField3String()
    {
        getField3().rewind();
        return NioUtil.toString( getField3() );
    }

    public void setField3( final String field )
    {
        setField3( NioUtil.toByteBuffer( field ) );
    }
    /**
     * Add a parsed HTTP header to the set of headers associated with this message.
     * No verification of the arguments is done.
     *
     * @param name The new header name
     * @param value The new header value
     */
    public void addHeader( final ByteBuffer name, final ByteBuffer value )
    {
        m_headers.add( new Field( name, value ) );
    }

    public void addHeader( final String name, final String value )
    {
        addHeader( NioUtil.toByteBuffer( name ), NioUtil.toByteBuffer( value ) );
    }
    /**
     * Get an unmodifiable map of the HTTP headers associated with this message.
     * No verification of the headers is done.
     *
     * @return an unmodifiable {@link List} of the HTTP headers, which might
     *     be empty
     */
    public List getHeaders()
    {
        return Collections.unmodifiableList( m_headers );
    }

    /**
     * Add a piece of the body associated with this message.
     * No verification of the buffer is done.
     *
     * @param buffer the body part to append
     */
    public void addBodyPart( final ByteBuffer buffer )
    {
        m_bodyParts.add( buffer );
    }

    public void addBodyPart( final String string )
    {
        m_bodyParts.add( NioUtil.toByteBuffer( string ) );
    }

    public void addBodyParts( final ByteBuffer[] buffers )
    {
        for( int i = 0; i < buffers.length; i++ )
            addBodyPart( buffers[i] );
    }
    /**
     * Get an ordered array of the body parts associated
     * with this message.
     *
     * @return the body parts of this message
     */
    public ByteBuffer[] getBodyParts()
    {
        return (ByteBuffer[])m_bodyParts.toArray( new ByteBuffer[0] );
    }

    public String getBodyAsString()
    {
        final ByteBuffer[] buf = getBodyParts();
        final String body = NioUtil.toString( buf ); // ouch!
        return body;
    }

    // ----------------------------------------------------------------------
    //  Convenience response methods
    // ----------------------------------------------------------------------

    public int getStatusCode()
    {
        //if( m_isRequest )
        //    throw new IllegalStateException( "We're not a response!" );

        // status code is the second field
        final String val = getField2String();
        return new Integer( val ).intValue();
    }
    public void setStatusCode( final ByteBuffer statusCode )
    {
        setField2( statusCode );
    }
    public void setStatusCode( final int code )
    {
        setStatusCode( NioUtil.toByteBuffer( code ) );
    }

    // ----------------------------------------------------------------------
    //  Work Interface: Recyclable
    // ----------------------------------------------------------------------
    public void recycle()
    {
        m_field1 = null;
        m_field2 = null;
        m_field3 = null;

        m_headers.clear();
        m_bodyParts.clear();
    }
}


--- NEW FILE: Field.java ---
/*
 * ====================================================================
 *
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Commons", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact [email protected].
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
/* ====================================================================
 The Jicarilla Software License

 Copyright (c) 2003 Leo Simons.
 All rights reserved.

 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to
 permit persons to whom the Software is furnished to do so, subject to
 the following conditions:

 The above copyright notice and this permission notice shall be
 included in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
==================================================================== */

package org.jicarilla.http;

import org.jicarilla.http.util.NioUtil;
import org.jicarilla.lang.Recyclable;

import java.io.Serializable;
import java.nio.ByteBuffer;

/**
 * <p>Simple JavaBean representing an HTTP header.</p>
 *
 * This class is originally from the
 * <a href="http://jakarta.apache.org/">Jakarta Commons</a> httpclient
 * libraries.
 *
 * @author <a href="mailto: lsimons at jicarilla dot org">Leo Simons</a>
 * @author <a href="mailto:remm at apache dot org">Remy Maucherat</a>
 * @author <a href="mailto:mbowler at GargoyleSoftware dot com">Mike Bowler</a>
 * @version $Id: Field.java,v 1.1 2004/04/09 15:52:08 lsimons Exp $
 */
public class Field implements Recyclable, Serializable
{
    // ----------------------------------------------------------------------
    //  Properties
    // ----------------------------------------------------------------------
    protected ByteBuffer m_name = null;
    protected ByteBuffer m_value = null;

    // ----------------------------------------------------------------------
    //  Constructors
    // ----------------------------------------------------------------------
    /** Default constructor. */
    public Field()
    {
        this( null, null );
    }

    /**
     * Constructor.
     *
     * @param name The name.
     * @param value The value.
     */
    public Field( final ByteBuffer name, final ByteBuffer value )
    {
        m_name = name;
        m_value = value;
    }

    // ----------------------------------------------------------------------
    //  Getters/Setters
    // ----------------------------------------------------------------------

    /**
     * Set the name.
     *
     * @param name The new name
     * @see #getName()
     */
    public void setName( final ByteBuffer name )
    {
        m_name = name;
    }

    /**
     * Return the name.
     *
     * @return String name The name
     * @see #setName(ByteBuffer)
     */
    public ByteBuffer getName()
    {
        return m_name;
    }

    public String getNameString()
    {
        return NioUtil.toString( m_name );
    }

    /**
     * Set the value.
     *
     * @param value The new value.
     */
    public void setValue( final ByteBuffer value )
    {
        m_value = value;
    }

    /**
     * Return the current value.
     *
     * @return String value The current value.
     */
    public ByteBuffer getValue()
    {
        return m_value;
    }

    public String getValueString()
    {
        return NioUtil.toString( m_value );
    }

    // ----------------------------------------------------------------------
    //  Utility methods
    // ----------------------------------------------------------------------

    /**
     * Test if the given <i>object</i> is equal to me. In this implementation,
     * an <i>object</i> is equal to me iff it has the same runtime type and the
     * <i>name</i> and <i>value</i> attributes are both <tt>equal</tt> (or
     * <tt>==</tt>).
     *
     * @param object the {@link java.lang.Object} to compare to
     * @return true if the objects are equal.
     */
    public boolean equals( final Object object )
    {
        if( this == object )
        {
            return true;
        } else if( this.getClass().equals( object.getClass() ) )
        {
            final Field pair = (Field) object;
            return (null == m_name ? null == pair.m_name : m_name.equals( pair.m_name ))
                    && (null == m_value ? null == pair.m_value : m_value.equals( pair.m_value ));
        } else
        {
            return false;
        }
    }

    /**
     * hashCode. Returns a hash code for this object such that if <tt>a.{@link
     * #equals equals}(b)</tt> then <tt>a.hashCode() == b.hashCode()</tt>.
     * @return The hash code.
     */
    public int hashCode()
    {
        return this.getClass().hashCode()
                ^ (null == m_name ? 0 : m_name.hashCode())
                ^ (null == m_value ? 0 : m_value.hashCode());
    }

    /**
     * Get a {@link java.lang.String} representation of me, suitable
     * for use in an HTTP head.
     *
     * @return string value for a HTTP HEAD
     */
    public String toExternalForm()
    {
        final StringBuffer buffer = new StringBuffer();
        NioUtil.append( buffer, m_name );
        buffer.append( ": " );
        NioUtil.append( buffer, m_value );
        buffer.append( "\r\n" );

        return buffer.toString();
    }

    /**
     * Returns a {@link java.lang.String} representation of me.
     *
     * @see #toExternalForm
     * @return String representation
     */
    public String toString()
    {
        return toExternalForm();
    }

    // ----------------------------------------------------------------------
    //  Work Interface: Recyclable
    // ----------------------------------------------------------------------
    public void recycle()
    {
        m_name = null;
        m_value = null;
    }
}

--- HTTPField.java DELETED ---

--- HTTPFileReader.java DELETED ---

--- HTTPEncoding.java DELETED ---

--- NEW FILE: Parser.java ---
/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1997-2003 The Apache Software Foundation. All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *    "This product includes software developed by the
 *    Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software
 *    itself, if and wherever such third-party acknowledgments
 *    normally appear.
 *
 * 4. The names "Avalon", and "Apache Software Foundation"
 *    must not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact [email protected].
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation. For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
package org.jicarilla.http;

import java.nio.ByteBuffer;

/**
 * A component that understands HTTP. Fires off events to a
 * handler similarly to the way SAX works.
 *
 * @author <a href="lsimons at jicarilla dot org">Leo Simons</a>
 * @version $Id: Parser.java,v 1.1 2004/04/09 15:52:09 lsimons Exp $
 */
public interface Parser
{
    // NOTE: important this starts with 1 as we add it
    // to c at some point!
    /**
     * Return this from Handler.getBodyType() if there is no
     * message body.
     */
    int BODY_TYPE_NONE = 1;
    /**
     * Return this from Handler.getBodyType() if the message
     * body is chunked.
     */
    int BODY_TYPE_CHUNKING = 2;
    /**
     * Return this from Handler.getBodyType() if the
     * message body is 'normal' (whatever that means).
     */
    int BODY_TYPE_NORMAL = 3;

    /**
     * Re-initialize the parser, throwing away all current parser state.
     */ 
    void reset();

    /**
     * <p>Parse a piece of an HTTP message. Equivalent to calling</p>
     *
     * <pre>
     * parse( source, source.limit() );
     * </pre>
     *
     * @param source the buffer to read from. Note that you should
     *   never modify this buffer after passing it to the parser!
     * @throws HTTPException
     */
    void parse( ByteBuffer source )
            throws HTTPException;

    /**
     * Parse a piece of an HTTP message. The buffer will be read
     * from its current position up to its limit. On return, the
     * buffers position will be at its end.
     *
     * @param source the buffer to read from. Note that you should
     *   never modify this buffer after passing it to the parser!
     * @param amount the number of bytes to read from the source
     * @throws HTTPException
     */
    void parse( ByteBuffer source, int amount )
            throws HTTPException;

    MessageHandler getHandler();

    void setHandler( MessageHandler handler );

    ErrorHandler getErrorHandler();

    void setErrorHandler( ErrorHandler errorHandler );
}



-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.