/* ********************************************************************
Appropriate copyright notice
*/
package org.bedework.bwcli.bwcmd;
/**
* User: mike
* Date: 3/7/17
* Time: 18:05
*/
import org.bedework.bwcli.JsonMapper;
import org.bedework.calfacade.responses.Response;
import org.bedework.util.http.BasicHttpClient;
import org.bedework.util.misc.Util;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.Header;
import org.apache.http.NameValuePair;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.net.URI;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import static org.bedework.calfacade.responses.Response.Status.failed;
import static org.bedework.calfacade.responses.Response.Status.ok;
/** Carry out all communications with web service
*
*/
public class HttpClient {
private final BasicHttpClient http;
private final ObjectMapper om;
public HttpClient(final URI uri) throws Exception {
om = new JsonMapper();
try {
http = new BasicHttpClient(30000);
http.setBaseURI(uri);
} catch (final Throwable t) {
throw new Exception(t);
}
}
public <T> T getJson(final String request,
final TypeReference valueTypeRef) throws Exception {
try {
final InputStream is = http.get(request, "application/json",
getHeaders());
if (is == null) {
return null;
}
return om.readValue(is, valueTypeRef);
} catch (final Throwable t) {
throw new Exception(t);
} finally {
try {
http.release();
} catch (final Throwable ignored) {}
}
}
public <T> T getJson(final String request,
final Class<T> valueType) throws Exception {
try {
final InputStream is = http.get(request, "application/json",
getHeaders());
if (is == null) {
return null;
}
return om.readValue(is, valueType);
} catch (final Throwable t) {
throw new Exception(t);
} finally {
try {
http.release();
} catch (final Throwable ignored) {}
}
}
public Long getLong(final String request) throws Exception {
try {
final InputStream is = http.get(request, "text/text",
getHeaders());
if (is == null) {
return null;
}
final int bufSize = 2048;
final byte[] buf = new byte[bufSize];
int pos = 0;
while (true) {
final int len = is.read(buf, pos, bufSize - pos);
if (len == -1) {
break;
}
pos += len;
if (pos >= bufSize) {
return null;
}
}
return Long.valueOf(new String(buf, 0, pos));
} catch (final Throwable t) {
throw new Exception(t);
} finally {
try {
http.release();
} catch (final Throwable ignored) {}
}
}
public boolean getBinary(final String request,
final OutputStream out) throws Exception {
try {
final InputStream is = http.get(request,
"application/binary",
getHeaders());
if (is == null) {
return false;
}
final int bufSize = 2048;
final byte[] buf = new byte[bufSize];
while (true) {
final int len = is.read(buf, 0, bufSize);
if (len == -1) {
break;
}
out.write(buf, 0, len);
}
return true;
} catch (final Throwable t) {
throw new Exception(t);
} finally {
try {
http.release();
} catch (final Throwable ignored) {}
}
}
public String getString(final String request,
final String contentType) throws Exception {
try {
final InputStream is = http.get(request,
contentType,
getHeaders());
if (is == null) {
return null;
}
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final int bufSize = 2048;
final byte[] buf = new byte[bufSize];
while (true) {
final int len = is.read(buf, 0, bufSize);
if (len == -1) {
break;
}
baos.write(buf, 0, len);
}
return baos.toString("UTF-8");
} catch (final Throwable t) {
throw new Exception(t);
} finally {
try {
http.release();
} catch (final Throwable ignored) {}
}
}
public <T> T post(final String path,
final String content,
final Class<T> resultType) throws Exception {
try {
final int len;
final byte[] bytes;
if (content != null) {
bytes = content.getBytes();
len = bytes.length;
} else {
bytes = null;
len = 0;
}
final int status = http.sendRequest("POST", path,
getHeaders(),
"application/json",
len,
bytes);
if (status != HttpServletResponse.SC_OK) {
return null;
}
return om.readValue(http.getResponseBodyAsStream(),
resultType);
} catch (final Throwable t) {
throw new Exception(t);
} finally {
try {
http.release();
} catch (final Throwable ignored) {}
}
}
public <T> T post(final String path,
final String content,
final TypeReference resultType) throws Exception {
try {
final int len;
final byte[] bytes;
if (content != null) {
bytes = content.getBytes();
len = bytes.length;
} else {
bytes = null;
len = 0;
}
final int status = http.sendRequest("POST", path,
getHeaders(),
"application/json",
len,
bytes);
if (status != HttpServletResponse.SC_OK) {
return null;
}
return om.readValue(http.getResponseBodyAsStream(),
resultType);
} catch (final Throwable t) {
throw new Exception(t);
} finally {
try {
http.release();
} catch (final Throwable ignored) {}
}
}
public int post(final String path,
final String content) throws Exception {
try {
final byte[] bytes = content.getBytes();
return http.sendRequest("POST", path,
getHeaders(),
"application/json",
bytes.length,
bytes);
} catch (final Throwable t) {
throw new Exception(t);
} finally {
try {
http.release();
} catch (final Throwable ignored) {}
}
}
public int post(final String path,
final Object val) throws Exception {
try {
final StringWriter sw = new StringWriter();
om.writeValue(sw, val);
return post(path, sw.toString());
} catch (final Throwable t) {
throw new Exception(t);
} finally {
try {
http.release();
} catch (final Throwable ignored) {}
}
}
public <T extends Response> T postForm(final String path,
final List<NameValuePair> nvps,
final Class<T> resultType) throws Exception {
try {
String delim = "";
final byte[] bytes;
final int len;
if (!Util.isEmpty(nvps)) {
final StringBuilder content = new StringBuilder();
for (final NameValuePair nvp: nvps) {
content.append(delim);
delim = "&";
content.append(nvp.getName());
content.append("=");
content.append(encode(nvp.getValue()));
}
bytes = content.toString().getBytes();
len = bytes.length;
} else {
bytes = null;
len = 0;
}
final int status = http.sendRequest("POST", path,
getHeaders(),
"application/x-www-form-urlencoded",
len,
bytes);
if (status != HttpServletResponse.SC_OK) {
final T response = resultType.newInstance();
response.setStatus(failed);
response.setMessage("Failed response from server: " + status);
return response;
}
return om.readValue(http.getResponseBodyAsStream(),
resultType);
} catch (final Throwable t) {
throw new Exception(t);
} finally {
try {
http.release();
} catch (final Throwable ignored) {}
}
}
public Response delete(final String path) throws Exception {
if (path == null) {
return null;
}
try {
final int status = http.delete(path, getHeaders());
final Response response = new Response();
if (status != HttpServletResponse.SC_OK) {
response.setStatus(failed);
response.setMessage("Failed response from server: " + status);
} else {
response.setStatus(ok);
}
return response;
} catch (final Throwable t) {
throw new Exception(t);
} finally {
try {
http.release();
} catch (final Throwable ignored) {}
}
}
public void release() throws Exception {
try {
http.release();
} catch (final Throwable t) {
throw new Exception(t);
}
}
private List<Header> getHeaders() {
final List<Header> hdrs = new ArrayList<>();
return hdrs;
}
private String encode(final String val) throws Throwable {
return URLEncoder.encode(val, "UTF-8");
}
private static class ReqBldr {
final StringBuilder req = new StringBuilder();
String delim = "?";
ReqBldr(final String path) {
req.append(path);
}
void par(final String name,
final String value) {
req.append(delim);
delim = "&";
req.append(name);
req.append("=");
req.append(value);
}
void par(final String name,
final int value) {
par(name, String.valueOf(value));
}
void par(final String name,
final boolean value) {
par(name, String.valueOf(value));
}
void multiPar(final String name,
final String[] value) throws Throwable {
if ((value == null) || (value.length == 0)) {
return;
}
for (final String s: value) {
par(name, s);
}
}
void multiPar(final String name,
final List<String> value) throws Throwable {
if (Util.isEmpty(value)) {
return;
}
for (final String s: value) {
par(name, encode(s));
}
}
void par(final String name,
final List<String> value) throws Throwable {
if (Util.isEmpty(value)) {
return;
}
req.append(delim);
delim = "&";
req.append(name);
req.append("=");
String listDelim = "";
final StringBuilder sb = new StringBuilder();
for (final String s: value) {
sb.append(listDelim);
sb.append(s);
listDelim = ",";
}
req.append(URLEncoder.encode(sb.toString(), "UTF-8"));
}
public String toString() {
return req.toString();
}
private static String encode(final String val) throws Throwable {
return URLEncoder.encode(val, "UTF-8");
}
}
}