package co.mwater.clientapp.dbsync;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
public class RESTClient {
String baseUrl;
String charset = "UTF-8";
String userAgent;
public RESTClient(String baseUrl, String userAgent) {
this.baseUrl = baseUrl;
this.userAgent = userAgent;
}
String createQuery(String... args) {
StringBuilder query = new StringBuilder();
for (int i = 0; i < args.length; i += 2) {
if (query.length() > 0)
query.append("&");
query.append(args[i]);
query.append("=");
try {
query.append(URLEncoder.encode(args[i + 1], charset));
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException(e);
}
}
return query.toString();
}
public String get(String command, String... args) throws RESTClientException {
// Construct url
URL url;
try {
url = new URL(baseUrl + command + "?" + createQuery(args));
} catch (MalformedURLException e) {
throw new IllegalArgumentException(e);
}
HttpURLConnection connection;
try {
connection = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
throw new RESTClientException(e);
}
try {
if (userAgent != null)
connection.setRequestProperty("User-Agent", userAgent);
return readStreamString(connection.getInputStream());
} catch (IOException ioex) {
int code;
try {
code = connection.getResponseCode();
String errorString = readStreamString(connection.getErrorStream());
throw new RESTClientException(code, errorString, ioex);
} catch (IOException e) {
throw new RESTClientException(e);
}
} finally {
connection.disconnect();
}
}
public String post(String command, String... args) throws RESTClientException {
// Construct url
URL url;
try {
url = new URL(baseUrl + command);
} catch (MalformedURLException e) {
throw new IllegalArgumentException(e);
}
HttpURLConnection connection;
try {
connection = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
throw new RESTClientException(e);
}
try {
if (userAgent != null)
connection.setRequestProperty("User-Agent", userAgent);
connection.setDoOutput(true); // Triggers POST
String query = createQuery(args);
connection.setFixedLengthStreamingMode(query.length());
connection.setRequestProperty("Accept-Charset", charset);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + charset);
OutputStream output = null;
try {
output = connection.getOutputStream();
output.write(query.toString().getBytes(charset));
} finally {
if (output != null)
try {
output.close();
} catch (IOException logOrIgnore) {
// Ignore since on close only
}
}
return readStreamString(connection.getInputStream());
} catch (IOException ioex) {
int code;
try {
code = connection.getResponseCode();
String errorString = readStreamString(connection.getErrorStream());
throw new RESTClientException(code, errorString, ioex);
} catch (IOException e) {
throw new RESTClientException(e);
}
} finally {
connection.disconnect();
}
}
public String postBlob(String command, byte[] blob, RequestProgress status, String... args) throws RESTClientException {
// Construct url
URL url;
try {
url = new URL(baseUrl + command + "?" + createQuery(args));
} catch (MalformedURLException e) {
throw new IllegalArgumentException(e);
}
HttpURLConnection connection;
try {
connection = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
throw new RESTClientException(e);
}
try {
if (userAgent != null)
connection.setRequestProperty("User-Agent", userAgent);
connection.setDoOutput(true); // Triggers POST
connection.setFixedLengthStreamingMode(blob.length);
connection.setRequestProperty("Accept-Charset", charset);
connection.setRequestProperty("Content-Type", "application/octet-stream");
int chunkSize = 1024;
OutputStream output = null;
try {
output = connection.getOutputStream();
for (int pos = 0; pos < blob.length; pos += chunkSize)
output.write(blob, pos, (blob.length - pos > chunkSize) ? chunkSize : (blob.length - pos));
} finally {
if (output != null)
try {
output.close();
} catch (IOException logOrIgnore) {
// Ignore since on close only
}
}
return readStreamString(connection.getInputStream());
} catch (IOException ioex) {
int code;
try {
code = connection.getResponseCode();
String errorString = readStreamString(connection.getErrorStream());
throw new RESTClientException(code, errorString, ioex);
} catch (IOException e) {
throw new RESTClientException(e);
}
} finally {
connection.disconnect();
}
}
public String postFile(String command, File file, RequestProgress progress, String... args) throws RESTClientException {
// Construct url
URL url;
try {
url = new URL(baseUrl + command + "?" + createQuery(args));
} catch (MalformedURLException e) {
throw new IllegalArgumentException(e);
}
HttpURLConnection connection;
try {
connection = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
throw new RESTClientException(e);
}
try {
if (userAgent != null)
connection.setRequestProperty("User-Agent", userAgent);
connection.setDoOutput(true); // Triggers POST
int len = (int) file.length();
connection.setFixedLengthStreamingMode(len);
connection.setRequestProperty("Accept-Charset", charset);
connection.setRequestProperty("Content-Type", "application/octet-stream");
int chunkSize = 1024 * 20;
byte[] buffer = new byte[chunkSize];
OutputStream output = null;
try {
output = connection.getOutputStream();
FileInputStream fis = new FileInputStream(file);
try {
// Read in the bytes
int numRead = 0;
int total = 0;
while ((numRead = fis.read(buffer)) > 0) {
if (progress != null && progress.isCancelled())
throw new RESTClientCancelledException();
output.write(buffer, 0, numRead);
total += numRead;
progress.progress(total, len);
}
} finally {
fis.close();
}
} finally {
if (output != null)
try {
output.close();
} catch (IOException logOrIgnore) {
// Ignore since on close only
}
}
return readStreamString(connection.getInputStream());
} catch (IOException ioex) {
int code;
try {
code = connection.getResponseCode();
String errorString = readStreamString(connection.getErrorStream());
throw new RESTClientException(code, errorString, ioex);
} catch (IOException e) {
throw new RESTClientException(e);
}
} finally {
connection.disconnect();
}
}
public byte[] getBytes(String command, RequestProgress progress, String... args) throws RESTClientException {
// TODO implement progress
// Construct url
URL url;
try {
url = new URL(baseUrl + command + "?" + createQuery(args));
} catch (MalformedURLException e) {
throw new IllegalArgumentException(e);
}
HttpURLConnection connection;
try {
connection = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
throw new RESTClientException(e);
}
try {
if (userAgent != null)
connection.setRequestProperty("User-Agent", userAgent);
return readStreamBytes(connection.getInputStream());
} catch (IOException ioex) {
int code;
try {
code = connection.getResponseCode();
String errorString = readStreamString(connection.getErrorStream());
throw new RESTClientException(code, errorString, ioex);
} catch (IOException e) {
throw new RESTClientException(e);
}
} finally {
connection.disconnect();
}
}
public void getBytesToFile(String command, RequestProgress progress, File file, String... args) throws RESTClientException {
// TODO implement progress
// Construct url
URL url;
try {
url = new URL(baseUrl + command + "?" + createQuery(args));
} catch (MalformedURLException e) {
throw new IllegalArgumentException(e);
}
HttpURLConnection connection;
try {
connection = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
throw new RESTClientException(e);
}
try {
if (userAgent != null)
connection.setRequestProperty("User-Agent", userAgent);
int chunkSize = 1024 * 20;
byte[] buffer = new byte[chunkSize];
InputStream input = null;
try {
input = connection.getInputStream();
int contentLength = connection.getContentLength();
FileOutputStream fos = new FileOutputStream(file);
try {
// Read in the bytes
int numRead = 0;
int total = 0;
while ((numRead = input.read(buffer)) > 0) {
if (progress != null && progress.isCancelled())
throw new RESTClientCancelledException();
fos.write(buffer, 0, numRead);
total += numRead;
if (contentLength > 0 && progress != null)
progress.progress(total, contentLength);
}
} finally {
fos.close();
}
} finally {
if (input != null)
try {
input.close();
} catch (IOException logOrIgnore) {
// Ignore since on close only
}
}
} catch (IOException ioex) {
int code;
try {
code = connection.getResponseCode();
String errorString = readStreamString(connection.getErrorStream());
throw new RESTClientException(code, errorString, ioex);
} catch (IOException e) {
throw new RESTClientException(e);
}
} finally {
connection.disconnect();
}
}
public interface RequestProgress {
boolean isCancelled();
void progress(long completed, long total);
}
String readStreamString(InputStream inputStream) throws IOException {
if (inputStream == null)
return "";
final char[] buffer = new char[8 * 1024];
StringBuilder out = new StringBuilder();
Reader in;
try {
in = new InputStreamReader(inputStream, charset);
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException(e);
}
try {
int read;
do {
read = in.read(buffer, 0, buffer.length);
if (read > 0) {
out.append(buffer, 0, read);
}
} while (read >= 0);
} finally {
in.close();
}
return out.toString();
}
private byte[] readStreamBytes(InputStream inputStream) throws IOException {
if (inputStream == null)
return null;
final byte[] buffer = new byte[8 * 1024];
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
int read;
do {
read = inputStream.read(buffer, 0, buffer.length);
if (read > 0) {
out.write(buffer, 0, read);
}
} while (read >= 0);
} finally {
inputStream.close();
}
return out.toByteArray();
}
}