package br.com.ingenieux.picloud;
import static java.lang.String.format;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.TimeZone;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
import org.codehaus.jackson.map.ObjectMapper;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
import com.sun.jersey.client.apache4.ApacheHttpClient4;
public class ClientBase implements PiCloudConstants {
protected static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
static {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
OBJECT_MAPPER.setDateFormat(sdf);
}
protected enum HttpMethod {
GET,
POST
}
protected static class ResourceRef {
final WebResource.Builder resource;
final String path;
final HttpMethod method;
ResourceRef(WebResource.Builder resource, String path, HttpMethod method) {
super();
this.resource = resource;
this.path = path;
this.method = method;
}
}
protected Client client;
protected Client getClient(PiCloudCreds credsToUse) {
ClientConfig cc = new DefaultClientConfig();
cc.getClasses().add(JacksonJsonProvider.class);
Client client = ApacheHttpClient4.create(cc);
client.setFollowRedirects(Boolean.TRUE);
client.addFilter(new HTTPBasicAuthFilter(credsToUse.getKey(), credsToUse.getSecretKey()));
return client;
}
protected <T> T handleResponse(ResourceRef ref, ResponseHandler<T> responseHandler) {
return handleResponse(ref, null, responseHandler);
}
protected <T> T handleResponse(ResourceRef ref, Object request, ResponseHandler<T> responseHandler) {
String path = ref.path;
ClientResponse response = null;
if (ref.method.equals(HttpMethod.GET)) {
response = ref.resource.get(ClientResponse.class);
} else {
if (null != request) {
String entityText = getEntityText(request);
response = ref.resource.entity(entityText).post(ClientResponse.class);
} else {
response = ref.resource.post(ClientResponse.class);
}
}
if (response.getStatus() != 200)
throw new PiCloudClientException(path, "Invalid Result Code: " + response.getStatus());
try {
return responseHandler.onResponse(response);
} catch (Exception exc) {
throw new PiCloudClientException(path, exc);
}
}
private String getEntityText(Object request) {
try {
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) OBJECT_MAPPER.convertValue(request, Map.class);
List<String> entryList = new ArrayList<String>();
for (Map.Entry<String, Object> entry : map.entrySet()) {
entryList.add(format("%s=%s", entry.getKey(), URLEncoder.encode(OBJECT_MAPPER.writeValueAsString(entry.getValue()), "UTF-8")));
}
entryList.add("_jsonized=True");
StringBuilder builder = new StringBuilder();
ListIterator<String> listIterator = entryList.listIterator();
while (listIterator.hasNext()) {
String entry = listIterator.next();
builder.append(entry);
if (listIterator.hasNext()) {
builder.append("&");
}
}
return builder.toString();
} catch (Exception exc) {
throw new PiCloudClientException("When marshaling request", exc);
}
}
protected ResourceRef resource(String path) {
return resource(path, HttpMethod.GET);
}
protected ResourceRef resource(String path, HttpMethod method) {
WebResource.Builder resource = client.resource(CLIENT_URI + path).accept("*/*");
return new ResourceRef(resource, path, method);
}
}