com.google.resting.RestingBuilder.java Source code

Java tutorial

Introduction

Here is the source code for com.google.resting.RestingBuilder.java

Source

/*
* Copyright (C) 2013 Google Code.
*
* 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.google.resting;

import java.util.List;
import java.util.Map;

import org.apache.http.Header;
import org.apache.http.auth.AuthScope;

import com.google.resting.component.Alias;
import com.google.resting.component.EncodingTypes;
import com.google.resting.component.RequestParams;
import com.google.resting.component.Verb;
import com.google.resting.component.impl.ServiceResponse;
import com.google.resting.component.impl.json.JSONAlias;
import com.google.resting.helper.RestingHelper;
import com.google.resting.rest.client.HttpContext;
import com.google.resting.transform.TransformationType;

/**
  * <p>Use this builder to make a REST invocation, get the response and create entities when you need to set configuration
 * options other than the default. For {@link Resting} with default configuration, it is simpler to
 * use {@code Resting.<method>}. {@code RestingBuilder} is best used by creating it, and then invoking its
 * various configuration methods, and finally calling build/invoke.</p>
 * 
 * <p>The following is an example shows how to use the {@code RestingBuilder}:
 * <pre>
 * <code>
 * List<Product> entities = new RestingBuilder("http://http://local.myapis.com/HellosService/V1/productInput",Product.class)
 *     .setPort(8080)
 *     .setVerb(Verb.POST)
 *     .setTransformationType(TransformationType.XML)
 *     .setConnectionTimeout(3000)
 *     .build();
 * </code>
 * </pre> 
 * </p>
 * 
 * <p>{@code RestingBuilder} can also be used to simply invoke the service and get {@code ServiceResponse} (without transforming the response into entities):
 * <pre>
 * <code>
 * ServiceResponse response=new RestingBuilder("http://api.zappos.com/Search")
 *      .setAlias(alias)
 *      .setRequestParams(jsonParams)
 *      .setProxy("proxy.abcd.ac.in", 3128,"user","@password")
 *      .invoke();
 * </code>
 * </pre> 
 * </p>
 * <p>{@code RestingBuilder} can be used to enable proxy and basic authentication:
 * <pre>
 * <code>
 * List<Product> entities = new RestingBuilder("http://http://local.myapis.com/HellosService/V1/productInput",Product.class)
 *     .setProxy("proxyhost", proxyport, "proxyuser","proxypassword")
 *     .build();
 * </code>
 * </pre> 
 * <pre>
 * <code>
 * List<Product> entities = new RestingBuilder("http://http://local.myapis.com/HellosService/V1/productInput",Product.class)
 *     .enableBasicAuthentication("user","password")
 *     .build();
 * </code>
 * </pre> 
 * </p>
 * <p>NOTE: The default parameters for {@code RestingBuilder} are: 
 * 
 * <pre>
 *      {@code Verb}= Verb.GET
 *      Port= 80
 *      {@code TransformationType}= TransformationType.JSON
 *      {@code EncodingTypes}= EncodingTypes.UTF8
 * </pre>
 * 
 * Non-default parameters will have to be set explicitly.
 * 
 * <p>NOTE: The order of invocation of configuration methods does not matter.</p>
 * 
 * @author sujata.de
 * @since resting 0.7
 *
 * @param <T> Type of the target entities
 */

public final class RestingBuilder<T> {
    private String uri;
    private int port;
    private Verb verb;
    private EncodingTypes encoding;
    private TransformationType transformationType;
    private Class<T> targetType;
    private List<Header> additionalHeaders;
    private RequestParams requestParams;
    private Alias alias;
    private HttpContext httpContext;

    /**
      * Creates a RestingBuilder instance that can be used to build a Resting request with various configuration
      * settings. RestingBuilder follows the builder pattern, and it is typically used by first
      * invoking various configuration methods to set desired options, and finally calling
      * {@link #build()}.
      */
    public RestingBuilder(String uri, Class<T> targetType) {
        this.targetType = targetType;
        this.uri = uri;
        setDefaultData();
    }//RestingBuilder

    /**
      * Creates a RestingBuilder instance that can be used to invoke service and get {@code ServiceResponse} containing raw response (in String or Binary), response headers status code etc. with various configuration
      * settings. This constructor should not be used if the response is being transformed into objects. RestingBuilder follows the builder pattern, and it is typically used by first
      * invoking various configuration methods to set desired options, and finally calling
      * {@link #invoke()}.
      */
    public RestingBuilder(String uri) {
        this.targetType = null;
        this.uri = uri;
        setDefaultData();
    }//RestingBuilder   

    /**
     * Invokes REST service and returns the response encapsulated in <code>ServiceResponse</code>. This method is free of
     * side-effects to this {@code RestingBuilder} instance and hence can be called multiple times.
     *
     * @return {@code ServiceResponse} object encapsulating the response from the REST service.
     */
    public ServiceResponse invoke() {
        return RestingHelper.execute(uri, port, requestParams, verb, encoding, additionalHeaders, httpContext);
    }//build

    /**
     * Invokes REST service and creates a {@link List} of target entities based on the current configuration. This method is free of
     * side-effects to this {@code RestingBuilder} instance and hence can be called multiple times.
     *
     * @return a list of target configured with the options currently set in this builder
     */
    public List<T> build() {
        return RestingHelper.executeAndTransform(uri, port, requestParams, verb, transformationType, targetType,
                alias, encoding, additionalHeaders, httpContext);
    }//build

    /**
       * Invokes REST service and creates a {@link Map} of target entities based on the current configuration. This method is free of
       * side-effects to this {@code RestingBuilder} instance and hence can be called multiple times.
       *
       * @return a map of target configured with the options currently set in this builder
    */
    public Map<String, List> build(Map<String, Class> aliasTypeMap) {
        if (transformationType == TransformationType.JSON) {
            if (aliasTypeMap != null) {
                JSONAlias aliases = new JSONAlias(aliasTypeMap);
                return RestingHelper.executeAndTransform(uri, port, requestParams, verb, transformationType,
                        aliases, encoding, additionalHeaders, httpContext);
            } //if aliasTypeMap
        } //if JSON 
        return null;
    }

    /**
     * Sets the connection timeout. Default value is 0, indicating infinite timeout.
     * 
     * @param connectionTimeout
     * @return a reference to this {@code RestingBuilder} object to fulfill the "Builder" pattern
     */
    public RestingBuilder setConnectionTimeout(int connectionTimeout) {
        httpContext.setConnectionTimeout(connectionTimeout);
        return this;
    }//setConnectionTimeout

    /**
     * Sets the socket timeout. Default value is 0, indicating infinite timeout.
     * 
     * @param socketTimeout
     * @return a reference to this {@code RestingBuilder} object to fulfill the "Builder" pattern
     */
    public RestingBuilder setSocketTimeout(int socketTimeout) {
        httpContext.setSocketTimeout(socketTimeout);
        return this;
    }//setSocketTimeout

    /**
     * Sets the port. Default value is 80.
     * 
     * @param port
     * @return a reference to this {@code RestingBuilder} object to fulfill the "Builder" pattern
     */
    public RestingBuilder setPort(int port) {
        this.port = port;
        return this;
    }//setPort

    /**
     * Sets the Verb. Default value is GET.
     * 
     * @param verb
     * @return a reference to this {@code RestingBuilder} object to fulfill the "Builder" pattern
     */
    public RestingBuilder setVerb(Verb verb) {
        this.verb = verb;
        return this;
    }//setVerb

    /**
     * Sets the encoding tyoe. Default value is UTF-8.
     * 
     * @param connectionTimeout
     * @return a reference to this {@code RestingBuilder} object to fulfill the "Builder" pattern
     */
    public RestingBuilder setEncodingType(EncodingTypes encodingType) {
        this.encoding = encodingType;
        return this;
    }//setEncodingType

    /**
     * Sets the transformation type. Default value is JSON.
     * 
     * @param transformationType
     * @return a reference to this {@code RestingBuilder} object to fulfill the "Builder" pattern
     */
    public RestingBuilder setTransformationType(TransformationType transformationType) {
        this.transformationType = transformationType;
        return this;
    }//setTransformationType

    /**
     * Sets the additional headers. Default value is null.
     * 
     * @param additionalHeaders
     * @return a reference to this {@code RestingBuilder} object to fulfill the "Builder" pattern
     */
    public RestingBuilder setAdditionalHeaders(List<Header> additionalHeaders) {
        this.additionalHeaders = additionalHeaders;
        return this;
    }//setAdditionalHeaders

    /**
     * Sets the request params. Default value is null.
     * 
     * @param requestParams
     * @return a reference to this {@code RestingBuilder} object to fulfill the "Builder" pattern
     */
    public RestingBuilder setRequestParams(RequestParams requestParams) {
        this.requestParams = requestParams;
        return this;
    }//setRequestParams

    /**
     * Sets preemptive authentication
     * 
     * @param preemptiveAuthentication
     * @return a reference to this {@code RestingBuilder} object to fulfill the "Builder" pattern
     */
    public RestingBuilder setPreemptiveAuthentication(boolean preemptiveAuthentication) {
        httpContext.setPreemptiveAuthentication(preemptiveAuthentication);
        return this;
    }//setPreemptiveAuthentication

    /**
     * Enables basic authentication with username and password
     * 
     * @param user
     * @param password
     * @return a reference to this {@code RestingBuilder} object to fulfill the "Builder" pattern
     */
    public RestingBuilder enableBasicAuthentication(String user, String password) {
        httpContext.setCredentials(user, password).setAuthScope(AuthScope.ANY);
        return this;
    }//setCredentials

    /**
     * Enables basic authentication with username, password and realm
     * 
     * @param user
     * @param password
     * @param host
     * @param port
     * @param realm
     * @return a reference to this {@code RestingBuilder} object to fulfill the "Builder" pattern
     */
    public RestingBuilder enableBasicAuthentication(String user, String password, String host, int port,
            String realm) {
        httpContext.setCredentials(user, password).setAuthScope(host, port, realm);
        return this;
    }//setAuthScope

    /**
     * Enables proxy based invocation
     * 
     * @param proxyHost
     * @param proxyPort
     * @return a reference to this {@code RestingBuilder} object to fulfill the "Builder" pattern
     */
    public RestingBuilder setProxy(String proxyHost, int proxyPort) {
        httpContext.setProxy(proxyHost, proxyPort);
        return this;
    }//setProxy

    /**
     * Enables proxy based invocation
     * 
     * @param proxyHost
     * @param proxyPort
     * @param proxyUser Proxy user
     * @params proxyPassword Proxy password
     * @return a reference to this {@code RestingBuilder} object to fulfill the "Builder" pattern
     */
    public RestingBuilder setProxy(String proxyHost, int proxyPort, String proxyUser, String proxyPassword) {
        httpContext.setProxy(proxyHost, proxyPort, proxyUser, proxyPassword);
        return this;
    }//setProxy

    /**
     * Sets the alias
     * 
     * @param alias
     * @return a reference to this {@code RestingBuilder} object to fulfill the "Builder" pattern
     */
    public RestingBuilder setAlias(Alias alias) {
        this.alias = alias;
        return this;
    }//setAlias

    private void setDefaultData() {
        this.port = 80;
        this.verb = Verb.GET;
        this.encoding = EncodingTypes.UTF8;
        this.transformationType = TransformationType.JSON;
        this.additionalHeaders = null;
        this.requestParams = null;
        this.alias = null;
        this.httpContext = new HttpContext();
    }

}//RestingBuilder