/*
 * ====================================================================
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.message;

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

import org.apache.http.HeaderElement;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.annotation.ThreadingBehavior;
import org.apache.http.annotation.Contract;
import org.apache.http.util.Args;
import org.apache.http.util.CharArrayBuffer;

Basic implementation for parsing header values into elements. Instances of this class are stateless and thread-safe. Derived classes are expected to maintain these properties.
Since:4.0
/** * Basic implementation for parsing header values into elements. * Instances of this class are stateless and thread-safe. * Derived classes are expected to maintain these properties. * * @since 4.0 */
@Contract(threading = ThreadingBehavior.IMMUTABLE) public class BasicHeaderValueParser implements HeaderValueParser {
A default instance of this class, for use as default or fallback. Note that BasicHeaderValueParser is not a singleton, there can be many instances of the class itself and of derived classes. The instance here provides non-customized, default behavior.
Deprecated:(4.3) use INSTANCE
/** * A default instance of this class, for use as default or fallback. * Note that {@link BasicHeaderValueParser} is not a singleton, there * can be many instances of the class itself and of derived classes. * The instance here provides non-customized, default behavior. * * @deprecated (4.3) use {@link #INSTANCE} */
@Deprecated public final static BasicHeaderValueParser DEFAULT = new BasicHeaderValueParser(); public final static BasicHeaderValueParser INSTANCE = new BasicHeaderValueParser(); private final static char PARAM_DELIMITER = ';'; private final static char ELEM_DELIMITER = ','; // IMPORTANT! // These private static variables must be treated as immutable and never exposed outside this class private static final BitSet TOKEN_DELIMS = TokenParser.INIT_BITSET('=', PARAM_DELIMITER, ELEM_DELIMITER); private static final BitSet VALUE_DELIMS = TokenParser.INIT_BITSET(PARAM_DELIMITER, ELEM_DELIMITER); private final TokenParser tokenParser; public BasicHeaderValueParser() { this.tokenParser = TokenParser.INSTANCE; }
Parses elements with the given parser.
Params:
  • value – the header value to parse
  • parser – the parser to use, or null for default
Throws:
Returns: array holding the header elements, never null
/** * Parses elements with the given parser. * * @param value the header value to parse * @param parser the parser to use, or {@code null} for default * * @return array holding the header elements, never {@code null} * @throws ParseException in case of a parsing error */
public static HeaderElement[] parseElements(final String value, final HeaderValueParser parser) throws ParseException { Args.notNull(value, "Value"); final CharArrayBuffer buffer = new CharArrayBuffer(value.length()); buffer.append(value); final ParserCursor cursor = new ParserCursor(0, value.length()); return (parser != null ? parser : BasicHeaderValueParser.INSTANCE) .parseElements(buffer, cursor); } // non-javadoc, see interface HeaderValueParser @Override public HeaderElement[] parseElements(final CharArrayBuffer buffer, final ParserCursor cursor) { Args.notNull(buffer, "Char array buffer"); Args.notNull(cursor, "Parser cursor"); final List<HeaderElement> elements = new ArrayList<HeaderElement>(); while (!cursor.atEnd()) { final HeaderElement element = parseHeaderElement(buffer, cursor); if (!(element.getName().isEmpty() && element.getValue() == null)) { elements.add(element); } } return elements.toArray(new HeaderElement[elements.size()]); }
Parses an element with the given parser.
Params:
  • value – the header element to parse
  • parser – the parser to use, or null for default
Returns: the parsed header element
/** * Parses an element with the given parser. * * @param value the header element to parse * @param parser the parser to use, or {@code null} for default * * @return the parsed header element */
public static HeaderElement parseHeaderElement(final String value, final HeaderValueParser parser) throws ParseException { Args.notNull(value, "Value"); final CharArrayBuffer buffer = new CharArrayBuffer(value.length()); buffer.append(value); final ParserCursor cursor = new ParserCursor(0, value.length()); return (parser != null ? parser : BasicHeaderValueParser.INSTANCE) .parseHeaderElement(buffer, cursor); } // non-javadoc, see interface HeaderValueParser @Override public HeaderElement parseHeaderElement(final CharArrayBuffer buffer, final ParserCursor cursor) { Args.notNull(buffer, "Char array buffer"); Args.notNull(cursor, "Parser cursor"); final NameValuePair nvp = parseNameValuePair(buffer, cursor); NameValuePair[] params = null; if (!cursor.atEnd()) { final char ch = buffer.charAt(cursor.getPos() - 1); if (ch != ELEM_DELIMITER) { params = parseParameters(buffer, cursor); } } return createHeaderElement(nvp.getName(), nvp.getValue(), params); }
Creates a header element. Called from parseHeaderElement.
Returns: a header element representing the argument
/** * Creates a header element. * Called from {@link #parseHeaderElement}. * * @return a header element representing the argument */
protected HeaderElement createHeaderElement( final String name, final String value, final NameValuePair[] params) { return new BasicHeaderElement(name, value, params); }
Parses parameters with the given parser.
Params:
  • value – the parameter list to parse
  • parser – the parser to use, or null for default
Returns: array holding the parameters, never null
/** * Parses parameters with the given parser. * * @param value the parameter list to parse * @param parser the parser to use, or {@code null} for default * * @return array holding the parameters, never {@code null} */
public static NameValuePair[] parseParameters(final String value, final HeaderValueParser parser) throws ParseException { Args.notNull(value, "Value"); final CharArrayBuffer buffer = new CharArrayBuffer(value.length()); buffer.append(value); final ParserCursor cursor = new ParserCursor(0, value.length()); return (parser != null ? parser : BasicHeaderValueParser.INSTANCE) .parseParameters(buffer, cursor); } // non-javadoc, see interface HeaderValueParser @Override public NameValuePair[] parseParameters(final CharArrayBuffer buffer, final ParserCursor cursor) { Args.notNull(buffer, "Char array buffer"); Args.notNull(cursor, "Parser cursor"); tokenParser.skipWhiteSpace(buffer, cursor); final List<NameValuePair> params = new ArrayList<NameValuePair>(); while (!cursor.atEnd()) { final NameValuePair param = parseNameValuePair(buffer, cursor); params.add(param); final char ch = buffer.charAt(cursor.getPos() - 1); if (ch == ELEM_DELIMITER) { break; } } return params.toArray(new NameValuePair[params.size()]); }
Parses a name-value-pair with the given parser.
Params:
  • value – the NVP to parse
  • parser – the parser to use, or null for default
Returns: the parsed name-value pair
/** * Parses a name-value-pair with the given parser. * * @param value the NVP to parse * @param parser the parser to use, or {@code null} for default * * @return the parsed name-value pair */
public static NameValuePair parseNameValuePair(final String value, final HeaderValueParser parser) throws ParseException { Args.notNull(value, "Value"); final CharArrayBuffer buffer = new CharArrayBuffer(value.length()); buffer.append(value); final ParserCursor cursor = new ParserCursor(0, value.length()); return (parser != null ? parser : BasicHeaderValueParser.INSTANCE) .parseNameValuePair(buffer, cursor); } // non-javadoc, see interface HeaderValueParser @Override public NameValuePair parseNameValuePair(final CharArrayBuffer buffer, final ParserCursor cursor) { Args.notNull(buffer, "Char array buffer"); Args.notNull(cursor, "Parser cursor"); final String name = tokenParser.parseToken(buffer, cursor, TOKEN_DELIMS); if (cursor.atEnd()) { return new BasicNameValuePair(name, null); } final int delim = buffer.charAt(cursor.getPos()); cursor.updatePos(cursor.getPos() + 1); if (delim != '=') { return createNameValuePair(name, null); } final String value = tokenParser.parseValue(buffer, cursor, VALUE_DELIMS); if (!cursor.atEnd()) { cursor.updatePos(cursor.getPos() + 1); } return createNameValuePair(name, value); }
Deprecated:(4.4) use TokenParser
/** * @deprecated (4.4) use {@link org.apache.http.message.TokenParser} */
@Deprecated public NameValuePair parseNameValuePair(final CharArrayBuffer buffer, final ParserCursor cursor, final char[] delimiters) { Args.notNull(buffer, "Char array buffer"); Args.notNull(cursor, "Parser cursor"); final BitSet delimSet = new BitSet(); if (delimiters != null) { for (final char delimiter: delimiters) { delimSet.set(delimiter); } } delimSet.set('='); final String name = tokenParser.parseToken(buffer, cursor, delimSet); if (cursor.atEnd()) { return new BasicNameValuePair(name, null); } final int delim = buffer.charAt(cursor.getPos()); cursor.updatePos(cursor.getPos() + 1); if (delim != '=') { return createNameValuePair(name, null); } delimSet.clear('='); final String value = tokenParser.parseValue(buffer, cursor, delimSet); if (!cursor.atEnd()) { cursor.updatePos(cursor.getPos() + 1); } return createNameValuePair(name, value); }
Creates a name-value pair. Called from parseNameValuePair.
Params:
  • name – the name
  • value – the value, or null
Returns: a name-value pair representing the arguments
/** * Creates a name-value pair. * Called from {@link #parseNameValuePair}. * * @param name the name * @param value the value, or {@code null} * * @return a name-value pair representing the arguments */
protected NameValuePair createNameValuePair(final String name, final String value) { return new BasicNameValuePair(name, value); } }