/*
* QueryCombiner.java May 2003
*
* Copyright (C) 2003, Niall Gallagher <niallg@users.sf.net>
*
* 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.
*/
package org.simpleframework.http.core;
import java.util.List;
import java.util.Set;
import org.simpleframework.http.Query;
import org.simpleframework.http.parse.QueryParser;
/**
* The <code>QueryCombimer</code> is used to parse several strings as a complete
* URL encoded parameter string. This will do the following concatenations.
*
* <pre>
* null + "a=b&c=d&e=f" = "a=b&c=d&e=f"
* "a=b" + "e=f&g=h" = "a=b&e=f&g=h";
* "a=b&c=d&e=f" + "" = "a=b&c=d&e=f"
* </pre>
*
* This ensures that the <code>QueryForm</code> can parse the list of strings as
* a single URL encoded parameter string. This can parse any number of parameter
* strings.
*
* @author Niall Gallagher
*/
class QueryCombiner extends QueryParser {
/**
* Constructor that allows a list of string objects to be parsed as a single
* parameter string. This will check each string to see if it is empty, that
* is, is either null or the zero length string.
*
* @param list
* this is a list of query values to be used
*/
public QueryCombiner(String... list) {
this.parse(list);
}
/**
* Constructor that allows an array of string objects to be parsed as a
* single parameter string. This will check each string to see if it is
* empty, that is, is either null or the zero length string.
*
* @param query
* this is the query from the HTTP header
* @param list
* this is the list of strings to be parsed
*/
public QueryCombiner(Query query, String... list) {
this.add(query);
this.parse(list);
}
/**
* Constructor that allows an array of string objects to be parsed as a
* single parameter string. This will check each string to see if it is
* empty, that is, is either null or the zero length string.
*
* @param query
* this is the query from the HTTP header
* @param post
* this is the query from the HTTP post body
*/
public QueryCombiner(Query query, Query post) {
this.add(query);
this.add(post);
}
/**
* This will concatenate the list of parameter strings as a single parameter
* string, before handing it to be parsed by the <code>parse(String)</code>
* method. This method will ignore any null or zero length strings in the
* array.
*
* @param list
* this is the list of strings to be parsed
*/
public void parse(String[] list) {
StringBuilder text = new StringBuilder();
for (int i = 0; i < list.length; i++) {
if (list[i] == null) {
continue;
} else if (list[i].length() == 0) {
continue;
} else if (text.length() > 0) {
text.append("&");
}
text.append(list[i]);
}
this.parse(text);
}
/**
* This is used to perform a parse of the form data that is in the provided
* string builder. This will simply convert the data in to a string and
* parse it in the normal fashion.
*
* @param text
* this is the buffer to be converted to a string
*/
private void parse(StringBuilder text) {
if (text != null) {
this.ensureCapacity(text.length());
this.count = text.length();
text.getChars(0, this.count, this.buf, 0);
this.parse();
}
}
/**
* This method is used to insert a collection of tokens into the parsers
* map. This is used when another source of tokens is required to populate
* the connection currently maintained within this parsers internal map. Any
* tokens that currently exist with similar names will be overwritten by
* this.
*
* @param query
* this is the collection of tokens to be added
*/
private void add(Query query) {
Set<String> keySet = query.keySet();
for (String key : keySet) {
List<String> list = query.getAll(key);
String first = query.get(key);
if (first != null) {
this.all.put(key, list);
this.map.put(key, first);
}
}
}
}