com.ocpsoft.pretty.faces.url.QueryString.java Source code

Java tutorial

Introduction

Here is the source code for com.ocpsoft.pretty.faces.url.QueryString.java

Source

/*
 * Copyright 2010 Lincoln Baxter, III
 * 
 * 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 com.ocpsoft.pretty.faces.url;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

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

import com.ocpsoft.pretty.PrettyException;
import com.ocpsoft.pretty.faces.config.mapping.RequestParameter;

/**
 * @author Lincoln Baxter, III <lincoln@ocpsoft.com>
 */
public class QueryString {

    private final static Log log = LogFactory.getLog(QueryString.class);

    private final Map<String, List<String>> parameters = new LinkedHashMap<String, List<String>>();

    /**
     * Build a query string from the given map of name=value pairs. For parameters with more than one value, each value
     * will be appended using the same name.
     */
    public static QueryString build(final Map<String, String[]> params) {
        QueryString queryString = new QueryString();
        queryString.addParameters(params);
        return queryString;
    }

    /**
     * Build a query string from the given list of {@link RequestParameter} objects.
     */
    public static <T extends RequestParameter> QueryString build(final List<T> params) {
        QueryString queryString = new QueryString();
        queryString.addParameters(params);
        return queryString;
    }

    /**
     * Build a query string from the given URL. If a '?' character is encountered in the URL, the any characters up to
     * and including the first '?' will be ignored.
     */
    public static QueryString build(final String url) {
        QueryString queryString = new QueryString();
        queryString.addParameters(url);
        return queryString;
    }

    /*
     * Utility Methods
     */
    /**
     * Return true if this query string currently contains no parameters.
     */
    public boolean isEmpty() {
        return parameters.isEmpty();
    }

    /*
     * Work methods
     */
    /**
     * Get the first value of given parameter name.
     * 
     * @return The value of the parameter, null if the parameter does not exist, or "" if the parameter exists but has no
     *         values.
     */
    public String getParameter(final String name) {
        List<String> values = parameters.get(name);
        if (values == null) {
            return null;
        }

        if (values.size() == 0) {
            return "";
        }

        return values.get(0);
    }

    /**
     * Get the array of values for a given parameter name.
     * 
     * @return The values of the parameter, null if the parameter does not exist.
     */
    public String[] getParameterValues(final String name) {
        List<String> values = parameters.get(name);
        if (values == null) {
            return null;
        }

        return values.toArray(new String[values.size()]);
    }

    /**
     * Get the list of parameter names currently stored in this query string..
     */
    public Enumeration<String> getParameterNames() {
        return Collections.enumeration(parameters.keySet());
    }

    /**
     * Get the name, values[] map representing this query string.
     */
    public Map<String, String[]> getParameterMap() {
        Map<String, String[]> map = new TreeMap<String, String[]>();
        for (Map.Entry<String, List<String>> entry : parameters.entrySet()) {
            List<String> list = entry.getValue();
            String[] values;
            if (list == null) {
                values = null;
            } else {
                values = list.toArray(new String[list.size()]);
            }
            map.put(entry.getKey(), values);
        }
        return map;
    }

    /*
     * Add Parameters
     */

    /**
     * Add query parameters from the given list of {@link RequestParameter} objects. If a parameter already exists,
     * append new values to the existing list of values for that parameter.
     */
    public <T extends RequestParameter> void addParameters(final List<T> params) {
        for (RequestParameter rp : params) {
            String value = rp.getValue();
            String name = rp.getName();

            if (!parameters.containsKey(name)) {
                ArrayList<String> values = new ArrayList<String>();
                if (value != null) {
                    values.add(value);
                }
                parameters.put(name, values);
            } else {
                parameters.get(name).add(value);
            }
        }
    }

    /**
     * Add parameters from the given map of name=value pairs. For parameters with more than one value, each value will be
     * appended using the same name. If a parameter already exists, append new values to the existing list of values for
     * that parameter.
     */
    public void addParameters(final Map<String, String[]> params) {
        if (params != null) {
            for (Entry<String, String[]> entry : params.entrySet()) {
                List<String> values = null;
                if (entry.getValue() != null) {
                    values = Arrays.asList(entry.getValue());
                }
                parameters.put(entry.getKey(), values);
            }
        }
    }

    /**
     * Add parameters from the given URL. If a '?' character is encountered in the URL, the any characters up to and
     * including the first '?' will be ignored. If a parameter already exists, append new values to the existing list of
     * values for that parameter.
     */
    public void addParameters(String url) {
        if ((url != null) && !"".equals(url)) {
            url = url.trim();
            if (url.length() > 1) {
                if (url.contains("?")) {
                    url = url.substring(url.indexOf('?') + 1);
                }

                String pairs[] = url.split("&(amp;)?");
                for (String pair : pairs) {
                    String name;
                    String value;
                    int pos = pair.indexOf('=');
                    // for "n=", the value is "", for "n", the value is null
                    if (pos == -1) {
                        name = pair;
                        value = null;
                    } else {
                        try {
                            // FIXME This probably shouldn't be happening here.
                            name = URLDecoder.decode(pair.substring(0, pos), "UTF-8");
                            value = URLDecoder.decode(pair.substring(pos + 1, pair.length()), "UTF-8");
                        } catch (IllegalArgumentException e) {
                            // thrown by URLDecoder if character decoding fails
                            log.warn("Ignoring invalid query parameter: " + pair);
                            continue;
                        } catch (UnsupportedEncodingException e) {
                            throw new PrettyException(
                                    "UTF-8 encoding not supported. Something is seriously wrong with your environment.");
                        }
                    }
                    List<String> list = parameters.get(name);
                    if (list == null) {
                        list = new ArrayList<String>();
                        parameters.put(name, list);
                    }
                    list.add(value);
                }
            }
        }
        return;
    }

    /**
     * Convert the current parameters to a valid query string, including the leading '?' character. This method
     * automatically URLEncodes query-parameter values
     * <p>
     * 
     * For example, a {@link QueryString} with the values [key=>value, name=>value1,value2,value3] will become:
     * 
     * <pre>
     * 
     * ?key=value&name=value1&name=value2&name=value3
     * </pre>
     * 
     * @return If parameters exist, return a valid query string with leading '?' character. If no parameters exist,
     *         return an empty string.
     */
    public String toQueryString() {
        try {
            StringBuffer result = new StringBuffer();

            if ((null != parameters) && !parameters.isEmpty()) {
                result.append("?");
                Iterator<Entry<String, List<String>>> iterator = parameters.entrySet().iterator();
                while (iterator.hasNext()) {
                    Entry<String, List<String>> entry = iterator.next();
                    String key = entry.getKey();
                    List<String> values = entry.getValue();

                    if ((key != null) && !"".equals(key)) {
                        key = URLEncoder.encode(key, "UTF-8");
                        result.append(key);

                        if ((values != null) && !values.isEmpty()) {
                            for (int i = 0; i < values.size(); i++) {
                                String value = values.get(i);
                                if ((value != null) && !"".equals(value)) {
                                    value = URLEncoder.encode(value, "UTF-8");
                                    result.append("=" + value);
                                } else if ((value != null) && "".equals(value)) {
                                    result.append("=");
                                }

                                if (i < values.size() - 1) {
                                    result.append("&" + key);
                                }
                            }
                        }
                    }

                    if (iterator.hasNext()) {
                        result.append("&");
                    }
                }
            }

            return result.toString();
        } catch (UnsupportedEncodingException e) {
            throw new PrettyException("Error building query string.", e);
        }
    }

    @Override
    public String toString() {
        return toQueryString();
    }

    public List<String> removeParameter(final String string) {
        return parameters.remove(string);
    }
}