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

com.comcast.drivethru.utils.URL Maven / Gradle / Ivy

There is a newer version: 2.0.7
Show newest version
/**
 * Copyright 2013 Comcast Cable Communications Management, LLC
 *
 * 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.comcast.drivethru.utils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import com.comcast.drivethru.exception.HttpException;

/**
 * Simple utility class for building up URLs.
 *
 * @author Clark Malmgren
 */
public class URL {

    private String baseUrl;
    private String path;
    private List query;

    /**
     * Default constructor with no fields filled out yet.
     */
    public URL() {
        this(null);
    }

    /**
     * Construct a URL starting with the given baseUrl.
     *
     * @param baseUrl
     *            the baseUrl to start with
     */
    public URL(String baseUrl) {
        this(baseUrl, null);
    }

    /**
     * Construct a URL starting with the given baseUrl and path.
     *
     * @param baseUrl
     *            the baseUrl to start with
     * @param path
     *            the path to use
     */
    public URL(String baseUrl, String path) {
        this.baseUrl = baseUrl;
        this.path = path;
        this.query = new ArrayList<>();
    }

    /**
     * Set the baseUrl for this fully built URL.
     *
     * @param baseUrl
     *            the base URL
     *
     * @return this
     */
    public URL setBaseUrl(String baseUrl) {
        this.baseUrl = baseUrl;
        return this;
    }

    /**
     * Set a baseUrl for this fully built URL if and only if this URL does not already have a
     * baseURL set.
     *
     * @param defaultBaseUrl
     *            the default base URL to use if there is no base URL already set.
     *
     * @return this
     */
    public URL setDefaultBaseUrl(String defaultBaseUrl) {
        if (null == baseUrl) {
            this.baseUrl = defaultBaseUrl;
        }
        return this;
    }

    /**
     * Get the base URL for this full built URL.
     *
     * @return the base URL
     */
    public String getBaseUrl() {
        return baseUrl;
    }

    /**
     * Returns true if this has a non-null baseUrl set, otherwise
     * false.
     *
     * @return true if this has a non-null baseUrl set, otherwise
     *         false
     */
    public boolean hasBaseUrl() {
        return (null != baseUrl);
    }

    /**
     * Set the relative path for this URL from the base URL.
     *
     * @param path
     *            the path
     *
     * @return this
     */
    public URL setPath(String path) {
        this.path = path;
        return this;
    }

    /**
     * Add a path element to the underlying path. This is effectively going to execute:
     * this.path += "/" + path;
     *
     * @param path
     *            the path to add to the existing path
     *
     * @return this
     */
    public URL addPath(String path) {
        if (null == this.path) {
            this.path = "/" + path;
        } else {
            this.path += "/" + path;
        }
        return this;
    }

    /**
     * Add the given key-value pair as a query parameter. This will simply call
     * value.toString() to convert the value to a string. This will URL-encode both the
     * key and value so that should NOT be done prior to calling this method. This method returns
     * this as a convenient way to chain adding parameters.
     *
     * @param key
     *            the key of the query parameter
     * @param value
     *            the value of that parameter
     *
     * @return this
     */
    public URL addQuery(String key, Object value) {
        return addQuery(key, value.toString());
    }

    /**
     * Add the given key-value pair as a query parameter. This will URL-encode both the key and
     * value so that should NOT be done prior to calling this method. This method returns
     * this as a convenient way to chain adding parameters.
     *
     * @param key
     *            the key of the query parameter
     * @param value
     *            the value of that parameter
     *
     * @return this
     */
    public URL addQuery(String key, String value) {
        String[] pair = new String[] { encode(key), encode(value) };
        query.add(pair);
        return this;
    }

    /**
     * Build the full URL.
     *
     * @return the full URL
     */
    public String build() throws HttpException {
        if (null == baseUrl) {
            throw new HttpException("URL must set a baseUrl");
        }

        StringBuilder sb = new StringBuilder(baseUrl);
        if (null != path) {
            /* If the baseUrl ends with a '/', don't use any beginning '/' from the path */
            if (baseUrl.endsWith("/")) {
                int index = 0;
                for (; index < path.length() && path.charAt(index) == '/'; index++);
                sb.append(path.substring(index));
            } else {
                sb.append(path);
            }
        }

        if (query.size() > 0) {
            String[] pair = query.get(0);
            sb.append('?');
            sb.append(pair[0]);
            sb.append('=');
            sb.append(pair[1]);
        }

        for (int i = 1; i < query.size(); i++) {
            String[] pair = query.get(i);
            sb.append('&');
            sb.append(pair[0]);
            sb.append('=');
            sb.append(pair[1]);
        }

        return sb.toString();
    }

    /**
     * URL encode the given string changing all spaces to %20, not +.
     *
     * @param val
     *            the string to encode
     *
     * @return the encoded string
     */
    public static String encode(String val) {
        try {
            return URLEncoder.encode(val, "UTF-8").replace("+", "%20");
        } catch (UnsupportedEncodingException ueex) {
            throw new RuntimeException("UTF-8 not supported on this machine", ueex);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy