package co.gem.round.patchboard; import co.gem.round.patchboard.definition.*; import co.gem.round.util.Strings; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; import com.squareup.okhttp.RequestBody; import com.squareup.okhttp.Response; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Created by julian on 11/25/14. */ public class Client { static final String AUTHORIZATION_HEADER = "Authorization"; static final String ACCEPT_HEADER = "Accept"; static final String CONTENT_TYPE_HEADER = "Content-Type"; private OkHttpClient httpClient; private AuthorizerInterface authorizer; private Patchboard patchboard; public Client(Patchboard patchboard, OkHttpClient httpClient, AuthorizerInterface authorizer) { this.patchboard = patchboard; this.httpClient = httpClient; this.authorizer = authorizer; } public Resource resources(String name) { return resources(name, null, null, null); } public Resource resources(String name, Map<String, String> query) { return resources(name, null, null, query); } public Resource resources(String name, String url) { return resources(name, url, null, null); } public Resource resources(String name, String url, String schemaId) { return resources(name, url, schemaId, null); } public Resource resources(String name, String url, String schemaId, Map<String, String> query) { SchemaSpec schemaSpec = null; if (schemaId != null) { schemaSpec = patchboard.definition().schemaById(schemaId); } MappingSpec mappingSpec = patchboard.definition().mapping(name); ResourceSpec resourceSpec = null; if (schemaSpec != null) { resourceSpec = schemaSpec.resourceSpec(); } else { resourceSpec = mappingSpec.resourceSpec(); } if (url == null) url = mappingSpec.url(); if (query != null) url = url + "?" + queryStringFromObject(query); return new Resource(url, resourceSpec, this); } public String queryStringFromObject(Map<String, String> query) { List<String> params = new ArrayList<String>(); for(Map.Entry<String, String> entry : query.entrySet()) { String param = Strings.urlEncode(entry.getKey()) + "=" + Strings.urlEncode(entry.getValue()); params.add(param); } return Strings.join("&", params); } public String performRawRequest(String url, ActionSpec actionSpec, JsonElement requestBody) throws IOException, UnexpectedStatusCodeException { com.squareup.okhttp.Request.Builder builder = new Request.Builder().url(url); RequestBody body = null; if (requestBody != null) body = RequestBody.create(null, requestBody.toString()); builder.method(actionSpec.method(), body); String authorization = null; for (String scheme : actionSpec.request().authorizations()) { if (authorizer.isAuthorized(scheme)) { authorization = authorizer.getCredentials(scheme); break; } } if (authorization != null) builder.header(AUTHORIZATION_HEADER, authorization); if (actionSpec.response().type() != null) builder.header(ACCEPT_HEADER, actionSpec.response().type()); if (actionSpec.request().type() != null) builder.header(CONTENT_TYPE_HEADER, actionSpec.request().type()); Request request = builder.build(); Response response = httpClient.newCall(request).execute(); int statusCode = response.code(); String responseContent = response.body().string(); if (statusCode != actionSpec.response().status()) throw new UnexpectedStatusCodeException(responseContent, statusCode, response); return responseContent; } public JsonElement performRequest(String url, ActionSpec actionSpec, JsonElement requestBody) throws IOException, UnexpectedStatusCodeException { String responseContent = performRawRequest(url, actionSpec, requestBody); JsonElement attributes = new JsonParser().parse(responseContent); return attributes; } public class UnexpectedStatusCodeException extends Exception { private static final long serialVersionUID = 1L; public int statusCode; public Response response; public UnexpectedStatusCodeException(String message, int statusCode, Response response) { super(message); this.statusCode = statusCode; this.response = response; } public String getMessage() { return "Unexpected status code: " + this.statusCode + "\n" + super.getMessage(); } } public Definition definition() { return patchboard.definition(); } public AuthorizerInterface authorizer() { return authorizer; } }