Package com.coherentlogic.wb.client.core.builders

Source Code of com.coherentlogic.wb.client.core.builders.QueryBuilder

package com.coherentlogic.wb.client.core.builders;

import static com.coherentlogic.wb.client.core.domain.Constants.COUNTRIES;
import static com.coherentlogic.wb.client.core.domain.Constants.DATA_CATALOG;
import static com.coherentlogic.wb.client.core.domain.Constants.FREQUENCY;
import static com.coherentlogic.wb.client.core.domain.Constants.GAP_FILL;
import static com.coherentlogic.wb.client.core.domain.Constants.INCOME_LEVEL;
import static com.coherentlogic.wb.client.core.domain.Constants.INCOME_LEVELS;
import static com.coherentlogic.wb.client.core.domain.Constants.INDICATOR;
import static com.coherentlogic.wb.client.core.domain.Constants.INDICATORS;
import static com.coherentlogic.wb.client.core.domain.Constants.LENDING_TYPE;
import static com.coherentlogic.wb.client.core.domain.Constants.LENDING_TYPES;
import static com.coherentlogic.wb.client.core.domain.Constants.METATYPES;
import static com.coherentlogic.wb.client.core.domain.Constants.MRV;
import static com.coherentlogic.wb.client.core.domain.Constants.NO;
import static com.coherentlogic.wb.client.core.domain.Constants.PAGE;
import static com.coherentlogic.wb.client.core.domain.Constants.PER_PAGE;
import static com.coherentlogic.wb.client.core.domain.Constants.REGION;
import static com.coherentlogic.wb.client.core.domain.Constants.SOURCE;
import static com.coherentlogic.wb.client.core.domain.Constants.SOURCES;
import static com.coherentlogic.wb.client.core.domain.Constants.TOPIC;
import static com.coherentlogic.wb.client.core.domain.Constants.TOPICS;
import static com.coherentlogic.wb.client.core.domain.Constants.YES;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.ws.rs.core.UriBuilder;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.client.RestTemplate;

import com.coherentlogic.coherent.data.model.core.builders.AbstractQueryBuilder;
import com.coherentlogic.coherent.data.model.core.util.Constants;
import com.coherentlogic.wb.client.core.domain.Frequency;
import com.coherentlogic.wb.client.core.domain.IncomeLevelCodes;
import com.coherentlogic.wb.client.core.domain.LendingTypeCodes;
import com.coherentlogic.wb.client.core.domain.RegionCodes;
import com.coherentlogic.wb.client.core.exceptions.InvalidFromToFormatException;
import com.coherentlogic.wb.client.core.exceptions.InvalidMetatypesException;
import com.coherentlogic.wb.client.core.exceptions.InvalidParameterValueException;

/**
* Class that allows the developer to construct and execute a query to the
* World Bank web services.
* <p>
* Note that this class is <b>not</b> thread-safe and cannot be used as a member
* -level property -- if this is required, use the
* {@link com.coherentlogic.fred.client.core.builders#RequestBuilderFactory
* QueryBuilderFactory} class.
* <p>
* In order to facilitate method-chaining each setter method returns a reference
* to this object.
* <p>
* For examples, refer to the {@link
* com.coherentlogic.wb.client.core.builders#QueryBuilderTest
* RequestBuilderTest} class.
*
* @see http://data.worldbank.org
* @see http://data.worldbank.org/developers/data-catalog-api
* @see http://data.worldbank.org/querybuilder
*
* @author <a href="mailto:support@coherentlogic.com">Support</a>
*
* @todo Refactor this class as some of the logic needs to be shared between
*  this class and the fred client.
*/
public class QueryBuilder extends AbstractQueryBuilder {

    private static final Logger log =
        LoggerFactory.getLogger(QueryBuilder.class);

    static {
      log.warn("***********************************************************");
        log.warn("*** Welcome to the Coherent Logic World Bank Client     ***");
        log.warn("***                Version 0.8.4.                       ***");
        log.warn("***                                                     ***");
        log.warn("***    Please take a moment to follow us on Twitter:    ***");
        log.warn("***                                                     ***");
        log.warn("***         https://twitter.com/CoherentMktData         ***");
        log.warn("***                                                     ***");
        log.warn("***********************************************************");
    }

    /**
     * The year pattern -- ie. YYYY.
     */
    private static final String YEAR_PATTERN = "\\d{4}";

    /**
     * The from/to constant -- ie. YYYY:YYYY.
     */
    private static final String FROM_TO_PATTERN =
        YEAR_PATTERN + ":" + YEAR_PATTERN;

    /**
     * The from/to pattern is used to ensure that from/to strings have the
     * proper format.
     */
    private static final Pattern fromToPattern =
        Pattern.compile(FROM_TO_PATTERN);

    /**
     * @see {@link AbstractQueryBuilder}.
     */
    public QueryBuilder (
        RestTemplate restTemplate,
        String uri
    ) {
        super (restTemplate, uri);
    }

    /**
     * @see {@link AbstractQueryBuilder}.
     */
    public QueryBuilder (
        RestTemplate restTemplate,
        UriBuilder uriBuilder
    ) {
        super (restTemplate, uriBuilder);
    }

    /**
     * Extends the path to include countries -- for example:
     *
     * http://api.worldbank.org/countries
     */
    public QueryBuilder countries () {
        return countries ((String[]) null);
    }

    /**
     * Extends the path to include countries -- for example:
     *
     * http://api.worldbank.org/countries
     */
    public QueryBuilder countries (String... countries) {
        super.extendPathWith(COUNTRIES);

        if (countries != null)
            extendPathWith(
                combine (countries)
            );

        return this;
    }

    /**
     * Extends the path to include source -- for example:
     *
     * http://api.worldbank.org/source/11
     *
     * @todo Consider adding a topic method that takes a numeric topic
     *  parameter.
     */
    public QueryBuilder source (String source) {

        assertNotNull("source", source);

        super.extendPathWith(SOURCE);

        if (source != null)
            super.extendPathWith(source);

        return this;
    }

    /**
     * Extends the path to include sources -- for example:
     *
     * http://api.worldbank.org/sources
     */
    public QueryBuilder sources () {
        super.extendPathWith(SOURCES);

        return this;
    }

    /**
     * Extends the path to include incomeLevel -- for example:
     *
     * http://api.worldbank.org/incomeLevel/LIC?per_page=10
     */
    public QueryBuilder incomeLevel (IncomeLevelCodes incomeLevelCode) {
        super.extendPathWith(INCOME_LEVEL);
        super.extendPathWith(incomeLevelCode.name());

        return this;
    }

    /**
     * Extends the path to include incomeLevels -- for example:
     *
     * http://api.worldbank.org/incomelevels
     */
    public QueryBuilder incomeLevels () {
        super.extendPathWith(INCOME_LEVELS);

        return this;
    }

    /**
     * Extends the path to include indicators -- for example:
     *
     * http://api.worldbank.org/indicators
     */
    public QueryBuilder indicators () {
        return indicators ((String[]) null);
    }

    /**
     * Extends the path to include indicators -- for example:
     *
     * http://api.worldbank.org/indicators
     */
    public QueryBuilder indicators (String... indicators) {
        super.extendPathWith(INDICATORS);

        if (indicators != null)
            extendPathWith(
                combine(indicators));

        return this;
    }

    /**
     * Extends the path to include indicator -- for example:
     *
     * http://api.worldbank.org/indicator
     */
    public QueryBuilder indicator () {
        return indicator(null);
    }

    /**
     * Extends the path to include indicator -- for example:
     *
     * http://api.worldbank.org/indicator
     */
    public QueryBuilder indicator (String indicator) {
        super.extendPathWith(INDICATOR);

        if (indicator != null)
            super.extendPathWith(indicator);

        return this;
    }

    /**
     * Extends the path to include lending types -- for example:
     *
     * http://api.worldbank.org/lendingTypes
     */
    public QueryBuilder lendingTypes () {
        super.extendPathWith(LENDING_TYPES);

        return this;
    }

    /**
     * Extends the path to include a region and region code.
     *
     * @param regionCode The regionCode value; note that if the value is null
     *  nothing will be added to the URL.
     */
    public QueryBuilder region (RegionCodes regionCode) {
        super.extendPathWith(REGION);

        if (regionCode != null)
            super.extendPathWith(regionCode.name());

        return this;
    }

    /**
     * Extends the path to include topics -- for example:
     *
     * http://api.worldbank.org/topics
     */
    public QueryBuilder topics () {
        super.extendPathWith(TOPICS);

        return this;
    }

    /**
     * Extends the path to include topic -- for example:
     *
     * http://api.worldbank.org/topic
     */
    public QueryBuilder topic () {
        return topic (null);
    }

    /**
     * Extends the path to include a topic and topic value-- for example:
     *
     * http://api.worldbank.org/topic/5?per_page=10
     *
     * @param topic The topic value; note that if the value is null nothing will
     *  be added to the URL.
     *
     * @todo Consider adding a topic method that takes a numeric topic
     *  parameter.
     */
    public QueryBuilder topic (String topic) {
        super.extendPathWith(TOPIC);

        if (topic != null)
            super.extendPathWith(topic);

        return this;
    }

    /**
     * Extends the path to include data catalog -- for example:
     *
     * http://api.worldbank.org/datacatalog
     */
    public QueryBuilder dataCatalog () {
        super.extendPathWith(DATA_CATALOG);

        return this;
    }

    /**
     * Method checks that the fromTo format is correct and, if it isn't, an
     * exception will be thrown.
     *
     * @param fromTo A string which should be in the format YYYY:YYYY.
     *
     * @throws InvalidFromToFormatException when the string is not valid.
     */
    private void reviewFromToFormat (String fromTo) {
        Matcher fromToMatcher = fromToPattern.matcher(fromTo);

        if (!fromToMatcher.matches())
            throw new InvalidFromToFormatException("The fromTo value is " +
                "not valid -- this value must be in the format YYYYY:YYYY" +
                "-- ie. '2001:2005'. (fromTo: " + fromTo + ").");
    }

    /**
     * Setter method for the from/to date, which should be in the format
     * YYYY:YYYY.
     *
     * @param fromTo The date range -- ie. 1998:2006.
     */
    public QueryBuilder setDate (String fromTo) {

        reviewFromToFormat (fromTo);

        addParameter(Constants.DATE, fromTo);

        return this;
    }

    /**
     * Setter method for the from/to date.
     *
     * @param from For example, 1999.
     *
     * @param to For example, 2002.
     */
    public QueryBuilder setDate (String from, String to) {
        return setDate (from + ":" + to);
    }

    /**
     * Method throws an exception if the actual value is less than or equal to
     * the target value.
     *
     * @todo Consider moving this class to the Utils class.
     */
    static void assertNotLessThanEqualTo (
        String param, int target, int actual) {
        if (actual <= target)
            throw new InvalidParameterValueException("The value of the " +
                "parameter named '" + param + "' is " + actual + " and this " +
                "is less than or equal to the expected target value of " +
                target);
    }

    /**
     * Method throws an exception if the actual value is less than or equal to
     * the target value.
     *
     * @todo Consider moving this class to the Utils class.
     */
    static void assertNotNull (
        String param, String value) {
        if (value == null)
            throw new NullPointerException ("The value of the " +
                "parameter named '" + param + "' is null.");
    }

    /**
     * Setter method for the page parameter.
     *
     * @param page The page value.
     */
    public QueryBuilder setPage (int page) {

        assertNotLessThanEqualTo ("page", 0, page);

        addParameter (PAGE, Integer.toString(page));

        return this;
    }

    /**
     * Setter method for the perPage value, which indicates how many results
     * should be shown on each page.
     *
     * @param perPage The perPage value.
     */
    public QueryBuilder setPerPage (int perPage) {

        assertNotLessThanEqualTo ("perPage", 0, perPage);

        addParameter (PER_PAGE, Integer.toString(perPage));

        return this;
    }

    /**
     * Setter method for the most recent values based on the number specified.
     *
     * @param mrv The most recent values.
     *
     * @see http://data.worldbank.org/node/11
     *
     * @todo Should this be an int?
     * @todo We need to check for zero and negative values.
     */
    public QueryBuilder setMRV (int mrv) {

        addParameter (MRV, Integer.toString(mrv));

        return this;
    }

    /**
     * Method sets the gapFill value to either 'yes' or 'no'.
     *
     * @param yesNo True equated to 'yes', 'no' otherwise.
     */
    public QueryBuilder setGapFill (boolean yesNo) {

        String value = yesNo == true ? YES : NO;

        setGapFill (value);

        return this;
    }

    /**
     * Setter method for the gapFill value. The yesNo value must be either
     * 'yes' or 'no'.
     *
     * @todo Check that the string is either yes or no.
     */
    QueryBuilder setGapFill (String yesNo) {

        addParameter (GAP_FILL, yesNo);

        return this;
    }

    /**
     * Setter method for the frequency.
     */
    public QueryBuilder setFrequency (Frequency frequency) {

        if (frequency == null)
            throw new InvalidParameterValueException("The frequency is null.");

        addParameter (FREQUENCY, frequency.toString());

        return this;
    }

    /**
     * Setter method for the lending type.
     */
    public QueryBuilder setLendingType (LendingTypeCodes lendingTypeCode) {

        if (lendingTypeCode == null)
            throw new InvalidParameterValueException(
                "The lendingTypeCode is null.");

        return setLendingType(lendingTypeCode.name());
    }

    /**
     * Setter method for the lending type.
     */
    QueryBuilder setLendingType (String lendingType) {

        addParameter (LENDING_TYPE, lendingType);

        return this;
    }

    /**
     * Setter method for the region.
     */
    public QueryBuilder setRegion (RegionCodes regionCode) {

        addParameter (REGION, regionCode.name());

        return this;
    }

    /**
     * Setter method for the income level.
     */
    QueryBuilder setIncomeLevel (String incomeLevel) {

        addParameter (INCOME_LEVEL, incomeLevel);

        return this;
    }

    /**
     * Setter method for the income level.
     */
    public QueryBuilder setIncomeLevel (IncomeLevelCodes incomeLevelCode) {

        if (incomeLevelCode == null)
            throw new InvalidParameterValueException(
                "The incomeLevelCode is null.");

        return setIncomeLevel(incomeLevelCode.name());
    }

    /**
     * Method combines the array of values into a single string separated by
     * semicolons.
     */
    static String combine (String... values) {
        if (values == null || values.length == 0)
            throw new InvalidMetatypesException(
                "The values passed to the combine method are invalid -- " +
                "these values include: " +
                ToStringBuilder.reflectionToString(values));

        String result = "";

        int ctr = (values.length - 1);

        for (String value : values) {

            result += value;

            if (0 < ctr--)
                result += ";";
        }
        return result;
    }

    /**
     * Sets the isoCode in the URI.
     *
     * http://api.worldbank.org/countries/isoCode/
     *
     * @param isoCodes The isoCode.
     *
     * @see http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
     * @see http://en.wikipedia.org/wiki/ISO_3166-1_alpha-3
     * @see http://data.worldbank.org/node/18
     */
    QueryBuilder setIsoCodes (String... isoCodes) {

        String combinedIsoCodes = combine(isoCodes);

        super.extendPathWith(combinedIsoCodes);

        return this;
    }

    /**
     * Setter method for the metatypes parameter.
     *
     * @see http://data.worldbank.org/developers/data-catalog-api
     */
    public QueryBuilder setMetatypes (String... values) {

        String metatypes = combine (values);

        addParameter (METATYPES, metatypes);

        return this;
    }
}
TOP

Related Classes of com.coherentlogic.wb.client.core.builders.QueryBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.