Package org.apache.http

Source Code of org.apache.http.NameValuePair

/*
* $HeadURL: https://svn.apache.org/repos/asf/jakarta/httpcomponents/httpcore/tags/4.0-alpha2/src/java/org/apache/http/NameValuePair.java $
* $Revision: 376961 $
* $Date: 2006-02-11 11:32:50 +0100 (Sat, 11 Feb 2006) $
*
* ====================================================================
*
*  Copyright 1999-2006 The Apache Software Foundation
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation.  For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/

package org.apache.http;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.io.CharArrayBuffer;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.LangUtils;

/**
* A simple class encapsulating an attribute/value pair.
* <p>
*  This class comforms to the generic grammar and formatting rules outlined in the
*  <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2">Section 2.2</a>
*  and 
*  <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6">Section 3.6</a>
*  of <a href="http://www.w3.org/Protocols/rfc2616/rfc2616.txt">RFC 2616</a>
* </p>
* <h>2.2 Basic Rules</h>
* <p>
*  The following rules are used throughout this specification to describe basic parsing constructs.
*  The US-ASCII coded character set is defined by ANSI X3.4-1986.
* </p>
* <pre>
*     OCTET          = <any 8-bit sequence of data>
*     CHAR           = <any US-ASCII character (octets 0 - 127)>
*     UPALPHA        = <any US-ASCII uppercase letter "A".."Z">
*     LOALPHA        = <any US-ASCII lowercase letter "a".."z">
*     ALPHA          = UPALPHA | LOALPHA
*     DIGIT          = <any US-ASCII digit "0".."9">
*     CTL            = <any US-ASCII control character
*                      (octets 0 - 31) and DEL (127)>
*     CR             = <US-ASCII CR, carriage return (13)>
*     LF             = <US-ASCII LF, linefeed (10)>
*     SP             = <US-ASCII SP, space (32)>
*     HT             = <US-ASCII HT, horizontal-tab (9)>
*     <">            = <US-ASCII double-quote mark (34)>
* </pre>
* <p>
*  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).
* <p>
* <pre>
* token          = 1*<any CHAR except CTLs or separators>
* separators     = "(" | ")" | "<" | ">" | "@"
*                | "," | ";" | ":" | "\" | <">
*                | "/" | "[" | "]" | "?" | "="
*                | "{" | "}" | SP | HT
* </pre>
* <p>
*  A string of text is parsed as a single word if it is quoted using double-quote marks.
* </p>
* <pre>
* quoted-string  = ( <"> *(qdtext | quoted-pair ) <"> )
* qdtext         = <any TEXT except <">>
* </pre>
* <p>
*  The backslash character ("\") MAY be used as a single-character quoting mechanism only
*  within quoted-string and comment constructs.
* </p>
* <pre>
* quoted-pair    = "\" CHAR
* </pre>
* <h>3.6 Transfer Codings</h>
* <p>
*  Parameters are in the form of attribute/value pairs.
* </p>
* <pre>
* parameter               = attribute "=" value
* attribute               = token
* value                   = token | quoted-string
* </pre>
*
* @author <a href="mailto:oleg at ural.com">Oleg Kalnichevski</a>
*
*/
public class NameValuePair {

    private final String name;
    private final String value;

    /**
     * Default Constructor taking a name and a value. The value may be null.
     *
     * @param name The name.
     * @param value The value.
     */
    public NameValuePair(final String name, final String value) {
        super();
        if (name == null) {
            throw new IllegalArgumentException("Name may not be null");
        }
        this.name = name;
        this.value = value;
    }

    /**
     * Returns the name.
     *
     * @return String name The name
     */
    public String getName() {
        return this.name;
    }

    /**
     * Returns the value.
     *
     * @return String value The current value.
     */
    public String getValue() {
        return this.value;
    }

    public static final NameValuePair[] parseAll(
            final CharArrayBuffer buffer, final int indexFrom, final int indexTo) {
        if (buffer == null) {
            throw new IllegalArgumentException("Char array buffer may not be null");
        }
        if (indexFrom < 0) {
            throw new IndexOutOfBoundsException();
        }
        if (indexTo > buffer.length()) {
            throw new IndexOutOfBoundsException();
        }
        if (indexFrom > indexTo) {
            throw new IndexOutOfBoundsException();
        }
        List params = new ArrayList();
        int cur = indexFrom;
        int from = indexFrom;
        boolean qouted = false;
        boolean escaped = false;
        while (cur < indexTo) {
            char ch = buffer.charAt(cur);
            if (ch == '"' && !escaped) {
                qouted = !qouted;
            }
            NameValuePair param = null;
            if (!qouted && ch == ';') {
                param = parse(buffer, from, cur);
                from = cur + 1;
            } else if (cur == indexTo - 1) {
                param = parse(buffer, from, indexTo);
            }
            if (param != null && !(param.getName().equals("") && param.getValue() == null)) {
                params.add(param);
            }
            if (escaped) {
                escaped = false;
            } else {
                escaped = qouted && ch == '\\';
            }
            cur++;
        }
        return (NameValuePair[]) params.toArray(new NameValuePair[params.size()]);
    }
   
    public static final NameValuePair[] parseAll(final String s) {
        if (s == null) {
            throw new IllegalArgumentException("String may not be null");
        }
        CharArrayBuffer buffer = new CharArrayBuffer(s.length());
        buffer.append(s);
        return parseAll(buffer, 0, buffer.length());
    }

    public static NameValuePair parse(
            final CharArrayBuffer buffer, final int indexFrom, final int indexTo) {
        if (buffer == null) {
            throw new IllegalArgumentException("Char array buffer may not be null");
        }
        if (indexFrom < 0) {
            throw new IndexOutOfBoundsException();
        }
        if (indexTo > buffer.length()) {
            throw new IndexOutOfBoundsException();
        }
        if (indexFrom > indexTo) {
            throw new IndexOutOfBoundsException();
        }
        int eq = buffer.indexOf('=', indexFrom, indexTo);
        if (eq < 0) {
            return new NameValuePair(buffer.substringTrimmed(indexFrom, indexTo), null);
        }
        String name = buffer.substringTrimmed(indexFrom, eq);
        int i1 = eq + 1;
        int i2 = indexTo;
        // Trim leading white spaces
        while (i1 < i2 && (HTTP.isWhitespace(buffer.charAt(i1)))) {
            i1++;
        }
        // Trim trailing white spaces
        while ((i2 > i1) && (HTTP.isWhitespace(buffer.charAt(i2 - 1)))) {
            i2--;
        }
        // Strip away quotes if necessary
        if (((i2 - i1) >= 2)
            && (buffer.charAt(i1) == '"')
            && (buffer.charAt(i2 - 1) == '"')) {
            i1++;
            i2--;
        }
        String value = buffer.substring(i1, i2);
        return new NameValuePair(name, value);
    }

    public static final NameValuePair parse(final String s) {
        if (s == null) {
            throw new IllegalArgumentException("String may not be null");
        }
        CharArrayBuffer buffer = new CharArrayBuffer(s.length());
        buffer.append(s);
        return parse(buffer, 0, buffer.length());
    }

    /**
     * Special characters that can be used as separators in HTTP parameters.
     * These special characters MUST be in a quoted string to be used within
     * a parameter value
     */
    private static final char[] SEPARATORS   = {
            '(', ')', '<', '>', '@',
            ',', ';', ':', '\\', '"',
            '/', '[', ']', '?', '=',
            '{', '}', ' ', '\t'
            };
   
    /**
     * Unsafe special characters that must be escaped using the backslash
     * character
     */
    private static final char[] UNSAFE_CHARS = {
            '"', '\\'
            };
   
    private static boolean isOneOf(char[] chars, char ch) {
        for (int i = 0; i < chars.length; i++) {
            if (ch == chars[i]) {
                return true;
            }
        }
        return false;
    }
   
    private static boolean isUnsafeChar(char ch) {
        return isOneOf(UNSAFE_CHARS, ch);
    }
   
    private static boolean isSeparator(char ch) {
        return isOneOf(SEPARATORS, ch);
    }

    private static void format(
            final CharArrayBuffer buffer,
            final String value,
            boolean alwaysUseQuotes) {
        boolean unsafe = false;
        if (alwaysUseQuotes) {
            unsafe = true;
        } else {
            for (int i = 0; i < value.length(); i++) {
                if (isSeparator(value.charAt(i))) {
                    unsafe = true;
                    break;
                }
            }
        }
        if (unsafe) buffer.append('"');
        for (int i = 0; i < value.length(); i++) {
            char ch = value.charAt(i);
            if (isUnsafeChar(ch)) {
                buffer.append('\\');
            }
            buffer.append(ch);
        }
        if (unsafe) buffer.append('"');
    }
   
    /**
     * Produces textual representaion of the attribute/value pair using
     * formatting rules defined in RFC 2616
     * 
     * @param buffer output buffer
     * @param param the parameter to be formatted
     * @param alwaysUseQuotes <tt>true</tt> if the parameter values must
     * always be enclosed in quotation marks, <tt>false</tt> otherwise
     */
    public static void format(
            final CharArrayBuffer buffer,
            final NameValuePair param,
            boolean alwaysUseQuotes) {
        if (buffer == null) {
            throw new IllegalArgumentException("String buffer may not be null");
        }
        if (param == null) {
            throw new IllegalArgumentException("Parameter may not be null");
        }
        buffer.append(param.getName());
        String value = param.getValue();
        if (value != null) {
            buffer.append("=");
            format(buffer, value, alwaysUseQuotes);
        }
    }
   
    /**
     * Produces textual representaion of the attribute/value pairs using
     * formatting rules defined in RFC 2616
     * 
     * @param buffer output buffer
     * @param params the parameters to be formatted
     * @param alwaysUseQuotes <tt>true</tt> if the parameter values must
     * always be enclosed in quotation marks, <tt>false</tt> otherwise
     */
    public static void formatAll(
            final CharArrayBuffer buffer,
            final NameValuePair[] params,
            boolean alwaysUseQuotes) {
        if (buffer == null) {
            throw new IllegalArgumentException("String buffer may not be null");
        }
        if (params == null) {
            throw new IllegalArgumentException("Array of parameter may not be null");
        }
        for (int i = 0; i < params.length; i++) {
            if (i > 0) {
                buffer.append("; ");
            }
            format(buffer, params[i], alwaysUseQuotes);
        }
    }
   
    /**
     * Produces textual representaion of the attribute/value pair using
     * formatting rules defined in RFC 2616
     * 
     * @param param the parameter to be formatted
     * @param alwaysUseQuotes <tt>true</tt> if the parameter values must
     * always be enclosed in quotation marks, <tt>false</tt> otherwise
     *
     * @return RFC 2616 conformant textual representaion of the
     * attribute/value pair
     */
    public static String format(final NameValuePair param, boolean alwaysUseQuotes) {
        CharArrayBuffer buffer = new CharArrayBuffer(16);
        format(buffer, param, alwaysUseQuotes);
        return buffer.toString();
    }
   
    /**
     * Produces textual representaion of the attribute/value pair using
     * formatting rules defined in RFC 2616
     * 
     * @param params the parameters to be formatted
     * @param alwaysUseQuotes <tt>true</tt> if the parameter values must
     * always be enclosed in quotation marks, <tt>false</tt> otherwise
     *
     * @return RFC 2616 conformant textual representaion of the
     * attribute/value pair
     */
    public static String formatAll(final NameValuePair[] params, boolean alwaysUseQuotes) {
        CharArrayBuffer buffer = new CharArrayBuffer(16);
        formatAll(buffer, params, alwaysUseQuotes);
        return buffer.toString();
    }
   
    /**
     * Get a string representation of this pair.
     *
     * @return A string representation.
     */
    public String toString() {
        CharArrayBuffer buffer = new CharArrayBuffer(16);
        buffer.append(this.name);
        if (this.value != null) {
            buffer.append("=");
            format(buffer, this.value, false);
        }
        return buffer.toString();
    }

    public boolean equals(final Object object) {
        if (object == null) return false;
        if (this == object) return true;
        if (object instanceof NameValuePair) {
            NameValuePair that = (NameValuePair) object;
            return this.name.equals(that.name)
                  && LangUtils.equals(this.value, that.value);
        } else {
            return false;
        }
    }

    public int hashCode() {
        int hash = LangUtils.HASH_SEED;
        hash = LangUtils.hashCode(hash, this.name);
        hash = LangUtils.hashCode(hash, this.value);
        return hash;
    }
   
}
TOP

Related Classes of org.apache.http.NameValuePair

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.