}
private <T> Response<T> request(final String requestUrl, final Class<T> type, final Action<? super T> validator) {
final URI requestUri = toUri(requestUrl, "plugin request");
HttpResponseResource response = null;
try {
response = resourceAccessor.getRawResource(requestUri);
final int statusCode = response.getStatusCode();
String contentType = response.getContentType();
if (contentType == null || !contentType.equalsIgnoreCase(JSON)) {
final String message = String.format("content type is '%s', expected '%s'", contentType == null ? "" : contentType, JSON);
throw new OutOfProtocolException(requestUrl, message);
}
final String clientStatusChecksum = response.getHeaderValue(CLIENT_STATUS_CHECKSUM_HEADER);
return response.withContent(new Transformer<Response<T>, InputStream>() {
public Response<T> transform(InputStream inputStream) {
Reader reader;
try {
reader = new InputStreamReader(inputStream, "utf-8");
} catch (UnsupportedEncodingException e) {
throw new AssertionError(e);
}
try {
if (statusCode == 200) {
T payload = new Gson().fromJson(reader, type);
validator.execute(payload);
return new SuccessResponse<T>(payload, statusCode, requestUrl, clientStatusChecksum);
} else if (statusCode >= 400 && statusCode < 600) {
ErrorResponse errorResponse = validate(requestUrl, new Gson().fromJson(reader, ErrorResponse.class));
return new ErrorResponseResponse<T>(errorResponse, statusCode, requestUrl, clientStatusChecksum);
} else {
throw new OutOfProtocolException(requestUrl, "unexpected HTTP response status " + statusCode);
}
} catch (JsonSyntaxException e) {
throw new OutOfProtocolException(requestUrl, "could not parse response JSON", e);
} catch (JsonIOException e) {
throw new OutOfProtocolException(requestUrl, "could not parse response JSON", e);
}
}
});
} catch (IOException e) {
throw new org.gradle.api.UncheckedIOException(e);
} finally {
try {
if (response != null) {
response.close();
}
} catch (IOException e) {
LOGGER.warn("Error closing HTTP resource", e);
}
}