Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.monarchapis.client.rest.BaseClient Maven / Gradle / Ivy
Go to download
A Fluent API wrapper around Apache HTTP Client that handles both synchronous and asynchronous REST calls.
/*
* Copyright (C) 2015 CapTech Ventures, Inc.
* (http://www.captechconsulting.com) All Rights Reserved.
*
* 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.monarchapis.client.rest;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.FileEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.joda.time.DateTime;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
public abstract class BaseClient> {
private static final Function TO_STRINGS = new Function() {
@Override
public String apply(Object value) {
return String.valueOf(value);
}
};
protected static final String CHARSET = "UTF-8";
/** The HTTP method. */
private final String method;
/** URL that request will be sent to. */
private final String url;
/** Http headers to send. */
private final Map paths;
/** Http headers to send. */
private final Map> headers;
/** Http general parameters to send. */
private final Map> parameters;
/** Http query parameters to send. */
private final Map> query;
/** Http form parameters to send. */
private final Map> form;
protected HttpEntity body;
private String bodyString;
/**
* Internal method used to build an APIResponse using the specified
* HttpResponse object.
*
* @param response
* response wrapped inside an APIResponse object
* @return api response
*/
RestResponse buildResponse(HttpResponse response) throws RestException {
try {
int statusCode = response.getStatusLine().getStatusCode();
String rb = "";
if (response.getEntity() != null) {
rb = EntityUtils.toString(response.getEntity());
}
HttpHeader[] headers = buildHeaders(response);
return new RestResponse(statusCode, rb, headers);
} catch (IOException ioe) {
throw new RestException(ioe);
}
}
/**
* Given an HttpResponse object, this method generates an array of HTTP
* headers.
*
* @param httpResponse
* used for building HTTP headers
* @return array of http headers
*/
private static HttpHeader[] buildHeaders(final HttpResponse httpResponse) {
final Header[] headers = httpResponse.getAllHeaders();
HttpHeader[] httpHeaders = new HttpHeader[headers.length];
for (int i = 0; i < headers.length; ++i) {
final Header header = headers[i];
final String name = header.getName();
final String value = header.getValue();
final HttpHeader httpHeader = new HttpHeader(name, value);
httpHeaders[i] = httpHeader;
}
return httpHeaders;
}
/**
* Sets headers to the http message.
*
* @param request
* http message to set headers for
*/
protected void addInternalHeaders(HttpRequestBase request) {
if (headers.isEmpty()) {
return;
}
final Set keySet = headers.keySet();
for (final String key : keySet) {
final List values = headers.get(key);
for (final String value : values) {
request.addHeader(key, value);
}
}
}
public String getMethod() {
return method;
}
public String getPath() {
String url = this.url;
for (Entry entry : this.paths.entrySet()) {
url = StringUtils.replace(url, "{" + entry.getKey() + "}", entry.getValue());
}
return url;
}
/**
* Builds the query part of a URL using the UTF-8 encoding.
*
* @return query
*/
public String getQuery() {
StringBuilder sb = new StringBuilder();
try {
if ("POST".equals(method) || "PUT".equals(method)) {
appendParameters(sb, this.parameters);
}
appendParameters(sb, this.query);
} catch (UnsupportedEncodingException e) {
// UTF-8 is a Java supported encoding.
// This should not occur unless the Java VM is not functioning
// properly.
throw new IllegalStateException();
}
return sb.toString();
}
public String getUrl() {
String query = "";
String builtQuery = getQuery();
if (StringUtils.isNotEmpty(builtQuery)) {
query = "?" + builtQuery;
}
return getPath() + query;
}
/**
* Builds the form part of a URL using the UTF-8 encoding.
*
* @return query
*/
protected String buildForm() {
StringBuilder sb = new StringBuilder();
try {
appendParameters(sb, this.parameters);
appendParameters(sb, this.form);
} catch (UnsupportedEncodingException e) {
// UTF-8 is a Java supported encoding.
// This should not occur unless the Java VM is not functioning
// properly.
throw new IllegalStateException();
}
return sb.toString();
}
private static void appendParameters(StringBuilder sb, Map> parameters)
throws UnsupportedEncodingException {
for (Entry> entry : parameters.entrySet()) {
if (sb.length() > 0) {
sb.append("&");
}
final String name = entry.getKey();
final List values = entry.getValue();
for (final String value : values) {
sb.append(URLEncoder.encode(name, CHARSET));
sb.append("=");
sb.append(URLEncoder.encode(value, CHARSET));
}
}
}
/**
* Creates a BaseClient with the BaseClient object.
*
* @param url
* The URL to send request to
*/
public BaseClient(String method, String url) {
this.paths = new HashMap();
this.headers = new HashMap>();
this.parameters = new HashMap>();
this.query = new HashMap>();
this.form = new HashMap>();
this.method = method;
this.url = url;
}
public T setPath(String variable, String value) {
this.paths.put(variable, value);
return me();
}
public T setPath(String name, DateTime dateTime) {
return setPath(name, (String) (dateTime != null ? dateTime.toString() : null));
}
public T setPath(String name, Object value) {
return setPath(name, (String) (value != null ? String.valueOf(value) : null));
}
/**
* Adds general parameter to be sent during http request.
*
*
* Does not remove any parameters with the same name, thus allowing
* duplicates.
*
*
* @param name
* name of parameter
* @param value
* value of parameter
* @return a reference to 'this', which can be used for method chaining
*/
public T addParameter(String name, String value) {
if (value == null) {
return me();
}
if (!parameters.containsKey(name)) {
parameters.put(name, new ArrayList());
}
List values = parameters.get(name);
values.add(value);
return me();
}
public T addParameter(String name, DateTime dateTime) {
return addParameter(name, (String) (dateTime != null ? dateTime.toString() : null));
}
public T addParameter(String name, Object value) {
return addParameter(name, (String) (value != null ? String.valueOf(value) : null));
}
/**
* Sets general parameter to be sent during http request.
*
*
* Removes any parameters with the same name, thus disallowing duplicates.
*
*
* @param name
* name of parameter
* @param value
* value of parameter
* @return a reference to 'this', which can be used for method chaining
*/
public T setParameter(String name, String value) {
if (parameters.containsKey(name)) {
parameters.get(name).clear();
}
return addParameter(name, value);
}
public T setParameter(String name, DateTime dateTime) {
return setParameter(name, (String) (dateTime != null ? dateTime.toString() : null));
}
public T setParameter(String name, Object value) {
return setParameter(name, (String) (value != null ? String.valueOf(value) : null));
}
/**
* Adds query parameter to be sent during http request.
*
*
* Does not remove any parameters with the same name, thus allowing
* duplicates.
*
*
* @param name
* name of parameter
* @param value
* value of parameter
* @return a reference to 'this', which can be used for method chaining
*/
public T addQuery(String name, String value) {
if (value == null) {
return me();
}
if (!query.containsKey(name)) {
query.put(name, new ArrayList());
}
List values = query.get(name);
values.add(value);
return me();
}
public T addQuery(String name, DateTime dateTime) {
return addQuery(name, (String) (dateTime != null ? dateTime.toString() : null));
}
public T addQuery(String name, Object value) {
return addQuery(name, (String) (value != null ? String.valueOf(value) : null));
}
/**
* Sets query parameter to be sent during http request.
*
*
* Removes any parameters with the same name, thus disallowing duplicates.
*
*
* @param name
* name of parameter
* @param value
* value of parameter
* @return a reference to 'this', which can be used for method chaining
*/
public T setQuery(String name, String value) {
if (query.containsKey(name)) {
query.get(name).clear();
}
return addQuery(name, value);
}
public T setQuery(String name, DateTime dateTime) {
return setQuery(name, (String) (dateTime != null ? dateTime.toString() : null));
}
public T setQuery(String name, Object value) {
return setQuery(name, (String) (value != null ? String.valueOf(value) : null));
}
public T addQueryCollection(String name, Collection> values, CollectionFormat format) {
if (values != null && !values.isEmpty()) {
char delimiter = format.getDelimiter();
if (delimiter == (char) 0) {
for (Object value : values) {
addQuery(name, value);
}
} else {
String value = StringUtils.join(Collections2.transform(values, TO_STRINGS), delimiter);
addQuery(name, value);
}
}
return me();
}
/**
* Adds form parameter to be sent during http request.
*
*
* Does not remove any parameters with the same name, thus allowing
* duplicates.
*
*
* @param name
* name of parameter
* @param value
* value of parameter
* @return a reference to 'this', which can be used for method chaining
*/
public T addForm(String name, String value) {
if (value == null) {
return me();
}
if (!form.containsKey(name)) {
form.put(name, new ArrayList());
}
List values = form.get(name);
values.add(value);
return me();
}
public T addForm(String name, DateTime dateTime) {
return addForm(name, (String) (dateTime != null ? dateTime.toString() : null));
}
public T addForm(String name, Object value) {
return addForm(name, (String) (value != null ? String.valueOf(value) : null));
}
public T addForm(String name, InputStream value) {
throw new UnsupportedOperationException("adding files is not supported");
}
/**
* Sets query parameter to be sent during http request.
*
*
* Removes any parameters with the same name, thus disallowing duplicates.
*
*
* @param name
* name of parameter
* @param value
* value of parameter
* @return a reference to 'this', which can be used for method chaining
*/
public T setForm(String name, String value) {
if (form.containsKey(name)) {
form.get(name).clear();
}
return addForm(name, value);
}
public T setForm(String name, DateTime dateTime) {
return setForm(name, (String) (dateTime != null ? dateTime.toString() : null));
}
public T setForm(String name, Object value) {
return setForm(name, (String) (value != null ? String.valueOf(value) : null));
}
public T setForm(String name, InputStream value) {
throw new UnsupportedOperationException("setting files is not supported");
}
/**
* Adds http header to be sent during http request.
*
*
* Does not remove any headers with the same name, thus allowing duplicates.
*
*
* @param name
* name of header
* @param value
* value of header
* @return a reference to 'this', which can be used for method chaining
*/
public T addHeader(String name, String value) {
if (value == null) {
return me();
}
if (!headers.containsKey(name)) {
headers.put(name, new ArrayList());
}
List values = headers.get(name);
values.add(value);
return me();
}
public T addHeader(String name, DateTime dateTime) {
return addHeader(name, (String) (dateTime != null ? dateTime.toString() : null));
}
public T addHeader(String name, Object value) {
return addHeader(name, (String) (value != null ? String.valueOf(value) : null));
}
/**
* Sets http header to be sent during http request.
*
*
* Does not remove any headers with the same name, thus allowing duplicates.
*
*
* @param name
* name of header
* @param value
* value of header
* @return a reference to 'this', which can be used for method chaining
*/
public T setHeader(String name, String value) {
if (headers.containsKey(name)) {
headers.get(name).clear();
}
return addHeader(name, value);
}
public T setHeader(String name, DateTime dateTime) {
return addHeader(name, (String) (dateTime != null ? dateTime.toString() : null));
}
public T setHeader(String name, Object value) {
return addHeader(name, (String) (value != null ? String.valueOf(value) : null));
}
public String getHeader(String name) {
List list = headers.get(name);
return list != null ? list.get(0) : null;
}
public T setBody(String body) {
try {
if (StringUtils.isNotEmpty(body)) {
this.body = new StringEntity(body, CHARSET);
bodyString = body;
} else {
this.body = null;
bodyString = null;
}
} catch (Exception uee) {
throw new IllegalStateException();
}
return me();
}
public String getBody() throws IOException {
if (bodyString != null) {
return bodyString;
} else {
return buildForm();
}
}
@SuppressWarnings("deprecation")
public T setBody(File file, String contentType) throws RestException {
this.body = new FileEntity(file, contentType);
return me();
}
public T accepts(String mimeType) {
setHeader("Accept", mimeType);
return me();
}
public T contentType(String mimeType) {
setHeader("Content-Type", mimeType);
return me();
}
public String getContentType() {
String contentType = getHeader("Content-Type");
return contentType;
}
public T authorization(String authorization) {
setHeader("Authorization", authorization);
return me();
}
@SuppressWarnings("unchecked")
private T me() {
return (T) this;
}
protected HttpRequestBase prepareRequest() {
String method = getMethod();
String url = getUrl();
HttpRequestBase request = null;
if ("GET".equals(method)) {
request = new HttpGet(url);
} else if ("POST".equals(method)) {
HttpPost post = new HttpPost(url);
setEntity(post);
request = post;
} else if ("PUT".equals(method)) {
HttpPut put = new HttpPut(url);
setEntity(put);
request = put;
} else if ("DELETE".equals(method)) {
request = new HttpDelete(url);
}
addInternalHeaders(request);
return request;
}
protected void setEntity(HttpEntityEnclosingRequestBase request) {
if (body != null) {
request.setEntity(body);
} else {
String form = buildForm();
bodyString = form;
if (StringUtils.isNotBlank(form)) {
request.setEntity(new StringEntity(form, ContentType.APPLICATION_FORM_URLENCODED));
} else {
throw new RestException("No body was specified.");
}
}
}
public enum CollectionFormat {
CSV(','), SSV(' '), TSV('\t'), PIPES('|'), MULTI((char) 0);
private char delimiter;
CollectionFormat(char delimiter) {
this.delimiter = delimiter;
}
char getDelimiter() {
return delimiter;
}
}
}