com.threerings.servlet.util.QueryBuilder.java Source code

Java tutorial

Introduction

Here is the source code for com.threerings.servlet.util.QueryBuilder.java

Source

//
// ooo-util - a place for OOO utilities
// Copyright (C) 2011 Three Rings Design, Inc., All Rights Reserved
// http://github.com/threerings/ooo-util/blob/master/LICENSE

package com.threerings.servlet.util;

import java.util.Collection;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;

import com.samskivert.util.StringUtil;
import com.samskivert.util.Tuple;

public class QueryBuilder {
    /**
     * Build a query directly from the specified map.
     */
    public static String build(Map<?, ?> values) {
        return encode(new StringBuilder(), values.entrySet());
    }

    /**
     * Retrieve the only value for the given key, or null if it's not defined. If the key has more
     * than one value defined, an IllegalArgumentException will be thrown.
     */
    public String getOnly(String key) {
        return getOnly(key, null);
    }

    /**
     * Retrieve the only value for the given key, or the default value if it's not defined. If the
     * key has more than one value defined, an IllegalArgumentException will be thrown.
     */
    public String getOnly(String key, String defaultValue) {
        return Iterables.getOnlyElement(get(key), defaultValue);
    }

    /**
     * Retrieve the first value for the given key, or null if the key is not defined.
     */
    public String getFirst(String key) {
        Collection<String> values = get(key);
        return values.isEmpty() ? null : values.iterator().next();
    }

    /**
     * Returns the current values for key or an empty collection if there isn't a value.
     */
    public Collection<String> get(String key) {
        return _params.get(key);
    }

    /**
     * Adds the given value to the parameter mapping under key adding to any current value.
     * {@link String#valueOf} is called on <code>val</code> to turn it into a string.
     */
    public QueryBuilder add(String key, Object val) {
        _params.put(key, String.valueOf(val));
        return this;
    }

    /**
     * Adds all the parameters in <code>req</code> to the parameters being constructed.
     */
    public QueryBuilder addAll(HttpServletRequest req) {
        for (Tuple<String, String> entry : new Parameters(req).entries()) {
            add(entry.left, entry.right);
        }
        return this;
    }

    /**
     * Adds all the parameters in <code>map</code> to the parameters being constructed.
     */
    public QueryBuilder addAll(Map<?, ?> map) {
        for (Map.Entry<?, ?> entry : map.entrySet()) {
            add(String.valueOf(entry.getKey()), entry.getValue());
        }
        return this;
    }

    /**
     * Appends the query in this builder to the given StringBuilder with a question mark.
     */
    public String toUrl(StringBuilder base) {
        return _params.isEmpty() ? base.toString() : encode(base.append('?'), _params.entries());
    }

    /**
     * Appends the query in this builder to the given String with a question mark.
     */
    public String toUrl(String base) {
        return toUrl(new StringBuilder(base));
    }

    /**
     * Returns the query in this builder.
     */
    public String toString() {
        return encode(new StringBuilder(), _params.entries());
    }

    protected static String encode(StringBuilder out, Iterable<? extends Map.Entry<?, ?>> entries) {
        boolean appended = false;
        for (Map.Entry<?, ?> entry : entries) {
            out.append(StringUtil.encode(String.valueOf(entry.getKey()))).append('=')
                    .append(StringUtil.encode(String.valueOf(entry.getValue()))).append('&');
            appended = true;
        }
        if (appended) { // Drop the extra ampersand
            out.setLength(out.length() - 1);
        }
        return out.toString();
    }

    protected final Multimap<String, String> _params = ArrayListMultimap.create();
}