public GeneratedHttpRequest apply()

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;
   }