All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.okta.commons.http.QueryString Maven / Gradle / Ivy

There is a newer version: 2.0.1
Show newest version
/*
 * Copyright 2014 Stormpath, Inc.
 * Modifications Copyright 2018 Okta, Inc.
 *
 * 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.okta.commons.http;

import com.okta.commons.lang.Collections;
import com.okta.commons.lang.Strings;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

/**
 * @since 0.5.0
 */
public class QueryString extends TreeMap {

    private static final long serialVersionUID = 42L;

    public QueryString(){}

    public QueryString(Map source) {
        super();

        if (!Collections.isEmpty(source)) {
            for (Map.Entry entry : source.entrySet()) {
                put(entry.getKey(), getFormattedValue(entry.getValue()));
            }
        }
    }

    public String put(String key, Object value) {
        if (value != null) {
            return super.put(key, getFormattedValue(value));
        }
        return null;
    }

    private String getFormattedValue(Object value) {
        String result = null;

        if (value != null) {
            if (value instanceof Date) {
                result = RequestUtils.getFormattedDate((Date) value);
            } else {
                result = String.valueOf(value);
            }
        }

        return result;
    }

    public String toString() {
        return toString(false);
    }

    /**
     * The canonicalized query string is formed by first sorting all the query
     * string parameters, then URI encoding both the key and value and then
     * joining them, in order, separating key value pairs with an '&'.
     *
     * @param canonical whether or not the string should be canonicalized
     * @return the canonical query string
     */
    public String toString(boolean canonical) {
        if (isEmpty()) {
            return "";
        }
        StringBuilder sb = new StringBuilder();

        for (Map.Entry entry : entrySet()) {
            String key = RequestUtils.encodeUrl(entry.getKey(), false, canonical);
            String value = RequestUtils.encodeUrl(entry.getValue(), false, canonical);

            if (sb.length() > 0) {
                sb.append('&');
            }

            sb.append(key).append("=").append(value);
        }

        return sb.toString();
    }

    public static QueryString create(String query) {
        if (!Strings.hasLength(query)) {
            return null;
        }

        QueryString queryString = new QueryString();

        // only returns null if string is null
        String[] tokens = Strings.tokenizeToStringArray(query, "&", false, false);
        for( String token : tokens) {
            applyKeyValuePair(queryString, token);
        }

        return queryString;
    }

    private static void applyKeyValuePair(QueryString qs, String kv) {

        String[] pair = Strings.split(kv, "=");

        if (pair != null) {
            String key = pair[0];
            String value = pair[1] != null ? pair[1] : "";
            try {
                qs.put(URLDecoder.decode(key, "UTF-8"), URLDecoder.decode(value, "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                // should never happen
                qs.put(key, value);
            }
        } else {
            //no equals sign, it's just a key:
            qs.put(kv, null);
        }
    }

    /**
     * Build an href with query string. Only appends it queryArgs is NOT empty.
     * @param href URL path
     * @param qs query string to append to href
     * @return href + query string if query string is NOT empty, otherwise, just returns the href
     */
    public static String buildHref(String href, QueryString qs) {
        StringBuilder sb = new StringBuilder(href);
        String query = qs.toString();
        if (!Strings.isEmpty(query)) {
            sb.append('?').append(query);
        }
        return sb.toString();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy