package com.urbanairship.digitalwallet.client;
import com.google.common.base.Preconditions;
import com.urbanairship.digitalwallet.client.exception.*;
import org.apache.http.HttpMessage;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
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.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.json.simple.JSONAware;
import org.json.simple.JSONObject;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.net.URLEncoder;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;
public abstract class PassToolsClient {
private static void handleAPIError(String responseBody, int responseCode) throws PassToolsException {
switch (responseCode) {
case 400:
throw new InvalidRequestException(responseBody);
case 401:
throw new AuthenticationException(responseBody);
case 406:
throw new InvalidRequestException(responseBody);
case 429:
throw new TooManyRequestsException(responseBody);
case 500:
throw new InternalServerException(responseBody);
default:
throw new ApiException(responseBody);
}
}
protected static void apiKeyCheck() throws AuthenticationException {
if ((PassTools.apiKey == null || PassTools.apiKey.length() == 0) && (PassTools.apiKey == null || PassTools.apiKey.length() == 0)) {
throw new AuthenticationException("No API secret key provided.");
}
}
protected static String addApiKey(String url) throws Exception {
if (url.indexOf('?') < 0) {
return url + "?api_key=" + URLEncoder.encode(PassTools.apiKey, "UTF-8");
} else {
return url + "&api_key=" + URLEncoder.encode(PassTools.apiKey, "UTF-8");
}
}
protected static void handleError(HttpResponse response) throws IOException, PassToolsException {
int responseCode = response.getStatusLine().getStatusCode();
if (responseCode < 200 || responseCode >= 300) {
String responseStr = EntityUtils.toString(response.getEntity());
handleAPIError(responseStr, responseCode);
}
}
protected static HttpClient getHttpClient() throws Exception {
if (PassTools.client != null) {
return PassTools.client;
}
HttpClient base = new DefaultHttpClient();
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[]{tm}, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx);
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = base.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", ssf, 443));
return new DefaultHttpClient(ccm, base.getParams());
}
protected static PassToolsResponse _rawGet(String url) throws Exception {
HttpClient httpclient = getHttpClient();
HttpGet get = new HttpGet(url);
HttpResponse response = httpclient.execute(get);
handleError(response);
return new PassToolsResponse(response);
}
public static PassToolsResponse get(String url) throws Exception {
apiKeyCheck();
HttpClient httpclient = getHttpClient();
HttpGet get = new HttpGet(addApiKey(url));
setHeaders(get, defaultHeaders());
HttpResponse response = httpclient.execute(get);
handleError(response);
return new PassToolsResponse(response);
}
protected static Map defaultHeaders() {
Map<String, String> headers = new HashMap<String, String>();
headers.put("Accept", "application/json");
headers.put("Api-Revision", PassTools.VERSION);
return headers;
}
private static void setHeaders(HttpMessage message, Map headers) {
if (headers != null && headers.size() > 0) {
for (Object o : headers.keySet()) {
String key = (String) o;
String value = (String) headers.get(key);
message.setHeader(key, value);
}
}
}
protected static PassToolsResponse post(String url, Map formFields, Map headers) throws Exception {
apiKeyCheck();
HttpClient httpclient = getHttpClient();
HttpPost post = new HttpPost(url);
setHeaders(post, headers);
List<NameValuePair> postParams = new ArrayList<NameValuePair>();
Object o = formFields.get("json");
if (o instanceof JSONAware) {
postParams.add(new BasicNameValuePair("json", ((JSONAware) o).toJSONString()));
} else {
throw new IllegalArgumentException("please pass a JSONObject or JSONArray value into the form fields");
}
postParams.add(new BasicNameValuePair("api_key", URLEncoder.encode(PassTools.apiKey, "UTF-8")));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(postParams);
entity.setContentEncoding(HTTP.UTF_8);
post.setEntity(entity);
HttpResponse response = httpclient.execute(post);
handleError(response);
return new PassToolsResponse(response);
}
protected static PassToolsResponse post(String url, Map formFields) throws Exception {
return post(url, formFields, defaultHeaders());
}
protected static PassToolsResponse put(String url, Map formFields, Map headers) throws Exception {
apiKeyCheck();
HttpClient httpclient = getHttpClient();
HttpPut put = new HttpPut(url);
setHeaders(put, headers);
List<NameValuePair> postParams = new ArrayList<NameValuePair>();
if (!formFields.isEmpty()) {
JSONObject jsonObj = (JSONObject) formFields.get("json");
postParams.add(new BasicNameValuePair("json", jsonObj.toJSONString()));
}
postParams.add(new BasicNameValuePair("api_key", URLEncoder.encode(PassTools.apiKey, "UTF-8")));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(postParams);
entity.setContentEncoding(HTTP.UTF_8);
put.setEntity(entity);
HttpResponse response = httpclient.execute(put);
handleError(response);
return new PassToolsResponse(response);
}
protected static PassToolsResponse put(String url, Map formFields) throws Exception {
return put(url, formFields, defaultHeaders());
}
protected static PassToolsResponse delete(String url) throws Exception {
return delete(url, defaultHeaders());
}
protected static PassToolsResponse delete(String url, Map headers) throws Exception {
apiKeyCheck();
HttpClient httpclient = getHttpClient();
HttpDelete delete = new HttpDelete(addApiKey(url));
setHeaders(delete, headers);
HttpResponse response = httpclient.execute(delete);
handleError(response);
return new PassToolsResponse(response);
}
protected static void checkNotNull(Object o, String message) {
try {
Preconditions.checkNotNull(o, message);
} catch (NullPointerException e) {
throw new InvalidParameterException(e.getMessage());
}
}
protected Date toTime(String time) {
DateTimeFormatter fmt = ISODateTimeFormat.dateTimeParser();
org.joda.time.DateTime dt = fmt.parseDateTime(time);
if (dt != null) {
return dt.toDate();
}
return null;
}
protected Boolean toBool(Object o) {
Boolean b = false;
if (o != null) {
if (o instanceof Boolean) {
b = (Boolean) o;
} else if (o instanceof Long) {
b = (0 != (Long) o);
} else if (o instanceof Integer) {
b = (0 != (Integer) o);
} else if (o instanceof Double) {
b = (0. != (Double) o);
} else if (o instanceof String) {
String str = (String) o;
b = str.equalsIgnoreCase("true") || str.equals("1");
}
}
return b;
}
protected Long toLong(Object o) {
Long l = null;
if (o != null) {
if (o instanceof Long) {
l = (Long) o;
} else {
try {
l = Long.valueOf(o.toString());
} catch (NumberFormatException e) {
l = null;
}
}
}
return l;
}
}