in core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java [191:365]
public GeneratedHttpRequest apply(Invocation invocation) {
checkNotNull(invocation, "invocation");
inputParamValidator.validateMethodParametersOrThrow(invocation, getInvokableParameters(invocation.getInvokable()));
Optional<URI> endpoint = Optional.absent();
HttpRequest r = findOrNull(invocation.getArgs(), HttpRequest.class);
if (r != null) {
endpoint = Optional.fromNullable(r.getEndpoint());
if (endpoint.isPresent())
logger.trace("using endpoint %s from invocation.getArgs() for %s", endpoint, invocation);
} else {
// If there is no explicit HttpRequest parameter, try to find the endpoint. When using
// delegate apis, the endpoint defined in the callee takes precedence
endpoint = getEndpointFor(invocation);
if (!endpoint.isPresent()) {
if (caller != null) {
endpoint = getEndpointFor(caller);
if (endpoint.isPresent())
logger.trace("using endpoint %s from caller %s for %s", endpoint, caller, invocation);
else
endpoint = findEndpoint(invocation);
} else {
endpoint = findEndpoint(invocation);
}
}
}
if (!endpoint.isPresent())
throw new NoSuchElementException(format("no endpoint found for %s", invocation));
GeneratedHttpRequest.Builder requestBuilder = GeneratedHttpRequest.builder().invocation(invocation)
.caller(caller);
String requestMethod = null;
if (r != null) {
requestMethod = r.getMethod();
requestBuilder.fromHttpRequest(r);
} else {
requestMethod = tryFindHttpMethod(invocation.getInvokable()).get();
requestBuilder.method(requestMethod);
}
requestBuilder.filters(getFiltersIfAnnotated(invocation));
if (stripExpectHeader) {
requestBuilder.filter(new StripExpectHeader());
}
if (connectionCloseHeader) {
requestBuilder.filter(new ConnectionCloseHeader());
}
Multimap<String, Object> tokenValues = LinkedHashMultimap.create();
tokenValues.put(Constants.PROPERTY_IDENTITY, credentials.get().identity);
tokenValues.put(Constants.PROPERTY_API_VERSION, apiVersion);
tokenValues.put(Constants.PROPERTY_BUILD_VERSION, buildVersion);
// URI template in rfc6570 form
UriBuilder uriBuilder = uriBuilder(endpoint.get().toString());
overridePathEncoding(uriBuilder, invocation);
boolean encodeFullPath = !isEncodedUsed(invocation);
if (caller != null)
tokenValues.putAll(addPathAndGetTokens(caller, uriBuilder, encodeFullPath));
tokenValues.putAll(addPathAndGetTokens(invocation, uriBuilder, encodeFullPath));
Multimap<String, Object> formParams;
if (caller != null) {
formParams = addFormParams(tokenValues, caller);
formParams.putAll(addFormParams(tokenValues, invocation));
} else {
formParams = addFormParams(tokenValues, invocation);
}
Multimap<String, Object> queryParams = addQueryParams(tokenValues, invocation);
Multimap<String, String> headers;
if (caller != null) {
headers = buildHeaders(tokenValues, caller);
headers.putAll(buildHeaders(tokenValues, invocation));
} else {
headers = buildHeaders(tokenValues, invocation);
}
if (r != null)
headers.putAll(r.getHeaders());
if (shouldAddHostHeader(invocation)) {
StringBuilder hostHeader = new StringBuilder(endpoint.get().getHost());
if (endpoint.get().getPort() != -1)
hostHeader.append(":").append(endpoint.get().getPort());
headers.put(HOST, hostHeader.toString());
}
Payload payload = null;
for (HttpRequestOptions options : findOptionsIn(invocation)) {
injector.injectMembers(options); // TODO test case
for (Entry<String, String> header : options.buildRequestHeaders().entries()) {
headers.put(header.getKey(), replaceTokens(header.getValue(), tokenValues));
}
for (Entry<String, String> query : options.buildQueryParameters().entries()) {
queryParams.put(urlEncode(query.getKey(), '/', ','),
new QueryValue(replaceTokens(query.getValue(), tokenValues), false));
}
for (Entry<String, String> form : options.buildFormParameters().entries()) {
formParams.put(form.getKey(), replaceTokens(form.getValue(), tokenValues));
}
String pathSuffix = options.buildPathSuffix();
if (pathSuffix != null) {
uriBuilder.appendPath(pathSuffix);
}
String stringPayload = options.buildStringPayload();
if (stringPayload != null)
payload = Payloads.newStringPayload(stringPayload);
}
if (!queryParams.isEmpty()) {
uriBuilder.query(queryParams);
}
requestBuilder.headers(filterOutContentHeaders(headers));
// Query parameter encoding is handled in the annotation processor
requestBuilder.endpoint(uriBuilder.build(convertUnsafe(tokenValues), /*encodePath=*/encodeFullPath));
if (payload == null) {
PayloadEnclosing payloadEnclosing = findOrNull(invocation.getArgs(), PayloadEnclosing.class);
payload = (payloadEnclosing != null) ? payloadEnclosing.getPayload() : findOrNull(invocation.getArgs(),
Payload.class);
}
List<? extends Part> parts = getParts(invocation, ImmutableMultimap.<String, Object> builder()
.putAll(tokenValues).putAll(formParams).build());
if (!parts.isEmpty()) {
if (!formParams.isEmpty()) {
parts = newLinkedList(concat(transform(formParams.entries(), ENTRY_TO_PART), parts));
}
payload = new MultipartForm(MultipartForm.BOUNDARY, parts);
} else if (!formParams.isEmpty()) {
payload = Payloads.newUrlEncodedFormPayload(transformValues(formParams, NullableToStringFunction.INSTANCE));
} else if (headers.containsKey(CONTENT_TYPE) && !HttpRequest.NON_PAYLOAD_METHODS.contains(requestMethod)) {
if (payload == null)
payload = Payloads.newByteArrayPayload(new byte[] {});
payload.getContentMetadata().setContentType(get(headers.get(CONTENT_TYPE), 0));
}
if (payload != null) {
requestBuilder.payload(payload);
}
GeneratedHttpRequest request = requestBuilder.build();
org.jclouds.rest.MapBinder mapBinder = getMapPayloadBinderOrNull(invocation);
if (mapBinder != null) {
Map<String, Object> mapParams;
if (caller != null) {
mapParams = buildPayloadParams(caller);
mapParams.putAll(buildPayloadParams(invocation));
} else {
mapParams = buildPayloadParams(invocation);
}
if (invocation.getInvokable().isAnnotationPresent(PayloadParams.class)) {
PayloadParams params = invocation.getInvokable().getAnnotation(PayloadParams.class);
addMapPayload(mapParams, params, headers, tokenValues);
}
request = mapBinder.bindToRequest(request, mapParams);
} else {
request = decorateRequest(request);
}
if (request.getPayload() != null) {
contentMetadataCodec.fromHeaders(request.getPayload().getContentMetadata(), headers);
}
request = stripExpectHeaderIfContentZero(request);
utils.checkRequestHasRequiredProperties(request);
return request;
}