github.com/phrase/openapi@v0.0.0-20240514140800-49e8a106740e/openapi-generator/templates/java/libraries/resteasy/ApiClient.mustache (about)

     1  package {{invokerPackage}};
     2  
     3  import java.io.File;
     4  import java.io.FileInputStream;
     5  import java.io.FileNotFoundException;
     6  import java.io.IOException;
     7  import java.io.InputStream;
     8  import java.io.UnsupportedEncodingException;
     9  import java.net.URLEncoder;
    10  import java.nio.file.Files;
    11  import java.text.DateFormat;
    12  import java.text.SimpleDateFormat;
    13  import java.util.ArrayList;
    14  import java.util.Collection;
    15  import java.util.Collections;
    16  import java.util.Date;
    17  import java.util.HashMap;
    18  import java.util.List;
    19  import java.util.Locale;
    20  import java.util.Map;
    21  import java.util.Map.Entry;
    22  import java.util.TimeZone;
    23  import java.util.regex.Matcher;
    24  import java.util.regex.Pattern;
    25  
    26  import javax.ws.rs.client.Client;
    27  import javax.ws.rs.client.ClientBuilder;
    28  import javax.ws.rs.client.Entity;
    29  import javax.ws.rs.client.Invocation;
    30  import javax.ws.rs.client.WebTarget;
    31  import javax.ws.rs.core.Form;
    32  import javax.ws.rs.core.GenericType;
    33  import javax.ws.rs.core.MediaType;
    34  import javax.ws.rs.core.Response;
    35  import javax.ws.rs.core.Response.Status;
    36  
    37  import org.jboss.logging.Logger;
    38  import org.jboss.resteasy.client.jaxrs.internal.ClientConfiguration;
    39  import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataOutput;
    40  import org.jboss.resteasy.spi.ResteasyProviderFactory;
    41  
    42  import {{invokerPackage}}.auth.Authentication;
    43  import {{invokerPackage}}.auth.HttpBasicAuth;
    44  import {{invokerPackage}}.auth.HttpBearerAuth;
    45  import {{invokerPackage}}.auth.ApiKeyAuth;
    46  {{#hasOAuthMethods}}
    47  import {{invokerPackage}}.auth.OAuth;
    48  {{/hasOAuthMethods}}
    49  
    50  {{>generatedAnnotation}}
    51  public class ApiClient {
    52    private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
    53    private Map<String, String> defaultCookieMap = new HashMap<String, String>();
    54    private String basePath = "{{{basePath}}}";
    55    private boolean debugging = false;
    56  
    57    private Client httpClient;
    58    private JSON json;
    59    private String tempFolderPath = null;
    60  
    61    private Map<String, Authentication> authentications;
    62  
    63    private int statusCode;
    64    private Map<String, List<String>> responseHeaders;
    65  
    66    private DateFormat dateFormat;
    67  
    68    public ApiClient() {
    69      json = new JSON();
    70      httpClient = buildHttpClient(debugging);
    71  
    72      this.dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ROOT);
    73  
    74      // Use UTC as the default time zone.
    75      this.dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    76  
    77      this.json.setDateFormat((DateFormat) dateFormat.clone());
    78  
    79      // Set default User-Agent.
    80      setUserAgent("{{#httpUserAgent}}{{{.}}}{{/httpUserAgent}}{{^httpUserAgent}}OpenAPI-Generator/{{{artifactVersion}}}/java{{/httpUserAgent}}");
    81  
    82      // Setup authentications (key: authentication name, value: authentication).
    83      authentications = new HashMap<String, Authentication>();{{#authMethods}}{{#isBasic}}{{#isBasicBasic}}
    84      authentications.put("{{name}}", new HttpBasicAuth());{{/isBasicBasic}}{{^isBasicBasic}}
    85      authentications.put("{{name}}", new HttpBearerAuth("{{scheme}}"));{{/isBasicBasic}}{{/isBasic}}{{#isApiKey}}
    86      authentications.put("{{name}}", new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{#isKeyInQuery}}"query"{{/isKeyInQuery}}{{#isKeyInCookie}}"cookie"{{/isKeyInCookie}}, "{{keyParamName}}"));{{/isApiKey}}{{#isOAuth}}
    87      authentications.put("{{name}}", new OAuth());{{/isOAuth}}{{/authMethods}}
    88      // Prevent the authentications from being modified.
    89      authentications = Collections.unmodifiableMap(authentications);
    90    }
    91  
    92    /**
    93     * Gets the JSON instance to do JSON serialization and deserialization.
    94     * @return the JSON utility class
    95     */
    96    public JSON getJSON() {
    97      return json;
    98    }
    99  
   100    public Client getHttpClient() {
   101      return httpClient;
   102    }
   103  
   104    public ApiClient setHttpClient(Client httpClient) {
   105      this.httpClient = httpClient;
   106      return this;
   107    }
   108  
   109    public String getBasePath() {
   110      return basePath;
   111    }
   112  
   113    public ApiClient setBasePath(String basePath) {
   114      this.basePath = basePath;
   115      return this;
   116    }
   117  
   118    /**
   119     * Gets the status code of the previous request
   120     * @return the status code of the previous request
   121     */
   122    public int getStatusCode() {
   123      return statusCode;
   124    }
   125  
   126    /**
   127     * Gets the response headers of the previous request
   128     * @return the response headers of the previous request
   129     */
   130    public Map<String, List<String>> getResponseHeaders() {
   131      return responseHeaders;
   132    }
   133  
   134    /**
   135     * Get authentications (key: authentication name, value: authentication).
   136     * @return the authentications
   137     */
   138    public Map<String, Authentication> getAuthentications() {
   139      return authentications;
   140    }
   141  
   142    /**
   143     * Get authentication for the given name.
   144     *
   145     * @param authName The authentication name
   146     * @return The authentication, null if not found
   147     */
   148    public Authentication getAuthentication(String authName) {
   149      return authentications.get(authName);
   150    }
   151  
   152    /**
   153     * Helper method to set username for the first HTTP basic authentication.
   154     * @param username the username
   155     */
   156    public void setUsername(String username) {
   157      for (Authentication auth : authentications.values()) {
   158        if (auth instanceof HttpBasicAuth) {
   159          ((HttpBasicAuth) auth).setUsername(username);
   160          return;
   161        }
   162      }
   163      throw new RuntimeException("No HTTP basic authentication configured!");
   164    }
   165  
   166    /**
   167     * Helper method to set password for the first HTTP basic authentication.
   168     * @param password the password
   169     */
   170    public void setPassword(String password) {
   171      for (Authentication auth : authentications.values()) {
   172        if (auth instanceof HttpBasicAuth) {
   173          ((HttpBasicAuth) auth).setPassword(password);
   174          return;
   175        }
   176      }
   177      throw new RuntimeException("No HTTP basic authentication configured!");
   178    }
   179  
   180    /**
   181     * Helper method to set API key value for the first API key authentication.
   182     * @param apiKey the API key
   183     */
   184    public void setApiKey(String apiKey) {
   185      for (Authentication auth : authentications.values()) {
   186        if (auth instanceof ApiKeyAuth) {
   187          ((ApiKeyAuth) auth).setApiKey(apiKey);
   188          return;
   189        }
   190      }
   191      throw new RuntimeException("No API key authentication configured!");
   192    }
   193  
   194    /**
   195     * Helper method to set API key prefix for the first API key authentication.
   196     * @param apiKeyPrefix the API key prefix
   197     */
   198    public void setApiKeyPrefix(String apiKeyPrefix) {
   199      for (Authentication auth : authentications.values()) {
   200        if (auth instanceof ApiKeyAuth) {
   201          ((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix);
   202          return;
   203        }
   204      }
   205      throw new RuntimeException("No API key authentication configured!");
   206    }
   207  
   208    {{#hasOAuthMethods}}
   209    /**
   210     * Helper method to set access token for the first OAuth2 authentication.
   211     * @param accessToken the access token
   212     */
   213    public void setAccessToken(String accessToken) {
   214      for (Authentication auth : authentications.values()) {
   215        if (auth instanceof OAuth) {
   216          ((OAuth) auth).setAccessToken(accessToken);
   217          return;
   218        }
   219      }
   220      throw new RuntimeException("No OAuth2 authentication configured!");
   221    }
   222  
   223    {{/hasOAuthMethods}}
   224    /**
   225     * Set the User-Agent header's value (by adding to the default header map).
   226     * @param userAgent the User-Agent header value
   227     * @return this {@code ApiClient}
   228     */
   229    public ApiClient setUserAgent(String userAgent) {
   230      addDefaultHeader("User-Agent", userAgent);
   231      return this;
   232    }
   233  
   234    /**
   235     * Add a default header.
   236     *
   237     * @param key The header's key
   238     * @param value The header's value
   239     * @return this {@code ApiClient}
   240     */
   241    public ApiClient addDefaultHeader(String key, String value) {
   242      defaultHeaderMap.put(key, value);
   243      return this;
   244    }
   245  
   246    /**
   247     * Check that whether debugging is enabled for this API client.
   248     * @return {@code true} if debugging is enabled for this API client
   249     */
   250    public boolean isDebugging() {
   251      return debugging;
   252    }
   253  
   254    /**
   255     * Enable/disable debugging for this API client.
   256     *
   257     * @param debugging To enable (true) or disable (false) debugging
   258     * @return this {@code ApiClient}
   259     */
   260    public ApiClient setDebugging(boolean debugging) {
   261      this.debugging = debugging;
   262      // Rebuild HTTP Client according to the new "debugging" value.
   263      this.httpClient = buildHttpClient(debugging);
   264      return this;
   265    }
   266  
   267    /**
   268     * The path of temporary folder used to store downloaded files from endpoints
   269     * with file response. The default value is <code>null</code>, i.e. using
   270     * the system's default tempopary folder.
   271     *
   272     * @return the temporary folder path
   273     * @see <a href="https://docs.oracle.com/javase/7/docs/api/java/io/File.html#createTempFile(java.lang.String,%20java.lang.String,%20java.io.File)"></a>
   274     */
   275    public String getTempFolderPath() {
   276      return tempFolderPath;
   277    }
   278  
   279    public ApiClient setTempFolderPath(String tempFolderPath) {
   280      this.tempFolderPath = tempFolderPath;
   281      return this;
   282    }
   283  
   284    /**
   285     * Get the date format used to parse/format date parameters.
   286     * @return the date format used to parse/format date parameters
   287     */
   288    public DateFormat getDateFormat() {
   289      return dateFormat;
   290    }
   291  
   292    /**
   293     * Set the date format used to parse/format date parameters.
   294     * @param dateFormat a date format used to parse/format date parameters
   295     * @return this {@code ApiClient}
   296     */
   297    public ApiClient setDateFormat(DateFormat dateFormat) {
   298      this.dateFormat = dateFormat;
   299      // also set the date format for model (de)serialization with Date properties
   300      this.json.setDateFormat((DateFormat) dateFormat.clone());
   301      return this;
   302    }
   303  
   304    /**
   305     * Parse the given string into Date object.
   306     * @param str a string to parse
   307     * @return a {@code Date} object
   308     */
   309    public Date parseDate(String str) {
   310      try {
   311        return dateFormat.parse(str);
   312      } catch (java.text.ParseException e) {
   313        throw new RuntimeException(e);
   314      }
   315    }
   316  
   317    /**
   318     * Format the given Date object into string.
   319     * @param date a {@code Date} object to format
   320     * @return the {@code String} version of the {@code Date} object
   321     */
   322    public String formatDate(Date date) {
   323      return dateFormat.format(date);
   324    }
   325  
   326    /**
   327     * Format the given parameter object into string.
   328     * @param param an object to format
   329     * @return the {@code String} version of the object
   330     */
   331    public String parameterToString(Object param) {
   332      if (param == null) {
   333        return "";
   334      } else if (param instanceof Date) {
   335        return formatDate((Date) param);
   336      } else if (param instanceof Collection) {
   337        StringBuilder b = new StringBuilder();
   338        for(Object o : (Collection)param) {
   339          if(b.length() > 0) {
   340            b.append(",");
   341          }
   342          b.append(String.valueOf(o));
   343        }
   344        return b.toString();
   345      } else {
   346        return String.valueOf(param);
   347      }
   348    }
   349  
   350    /*
   351      Format to {@code Pair} objects.
   352    */
   353    public List<Pair> parameterToPairs(String collectionFormat, String name, Object value){
   354      List<Pair> params = new ArrayList<Pair>();
   355  
   356      // preconditions
   357      if (name == null || name.isEmpty() || value == null) return params;
   358  
   359      Collection valueCollection = null;
   360      if (value instanceof Collection) {
   361        valueCollection = (Collection) value;
   362      } else {
   363        params.add(new Pair(name, parameterToString(value)));
   364        return params;
   365      }
   366  
   367      if (valueCollection.isEmpty()){
   368        return params;
   369      }
   370  
   371      // get the collection format
   372      collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv
   373  
   374      // create the params based on the collection format
   375      if (collectionFormat.equals("multi")) {
   376        for (Object item : valueCollection) {
   377          params.add(new Pair(name, parameterToString(item)));
   378        }
   379  
   380        return params;
   381      }
   382  
   383      String delimiter = ",";
   384  
   385      if (collectionFormat.equals("csv")) {
   386        delimiter = ",";
   387      } else if (collectionFormat.equals("ssv")) {
   388        delimiter = " ";
   389      } else if (collectionFormat.equals("tsv")) {
   390        delimiter = "\t";
   391      } else if (collectionFormat.equals("pipes")) {
   392        delimiter = "|";
   393      }
   394  
   395      StringBuilder sb = new StringBuilder() ;
   396      for (Object item : valueCollection) {
   397        sb.append(delimiter);
   398        sb.append(parameterToString(item));
   399      }
   400  
   401      params.add(new Pair(name, sb.substring(1)));
   402  
   403      return params;
   404    }
   405  
   406    /**
   407     * Check if the given MIME is a JSON MIME.
   408     * JSON MIME examples:
   409     *   application/json
   410     *   application/json; charset=UTF8
   411     *   APPLICATION/JSON
   412     *   application/vnd.company+json
   413     * @param mime MIME (Multipurpose Internet Mail Extensions)
   414     * @return True if the given MIME is JSON, false otherwise.
   415     */
   416    public boolean isJsonMime(String mime) {
   417      String jsonMime = "(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$";
   418      return mime != null && (mime.matches(jsonMime) || mime.equals("*/*"));
   419    }
   420  
   421    /**
   422     * Select the Accept header's value from the given accepts array:
   423     *   if JSON exists in the given array, use it;
   424     *   otherwise use all of them (joining into a string)
   425     *
   426     * @param accepts The accepts array to select from
   427     * @return The Accept header to use. If the given array is empty,
   428     *   null will be returned (not to set the Accept header explicitly).
   429     */
   430    public String selectHeaderAccept(String[] accepts) {
   431      if (accepts.length == 0) {
   432        return null;
   433      }
   434      for (String accept : accepts) {
   435        if (isJsonMime(accept)) {
   436          return accept;
   437        }
   438      }
   439      return StringUtil.join(accepts, ",");
   440    }
   441  
   442    /**
   443     * Select the Content-Type header's value from the given array:
   444     *   if JSON exists in the given array, use it;
   445     *   otherwise use the first one of the array.
   446     *
   447     * @param contentTypes The Content-Type array to select from
   448     * @return The Content-Type header to use. If the given array is empty,
   449     *   JSON will be used.
   450     */
   451    public String selectHeaderContentType(String[] contentTypes) {
   452      if (contentTypes.length == 0) {
   453        return "application/json";
   454      }
   455      for (String contentType : contentTypes) {
   456        if (isJsonMime(contentType)) {
   457          return contentType;
   458        }
   459      }
   460      return contentTypes[0];
   461    }
   462  
   463    /**
   464     * Escape the given string to be used as URL query value.
   465     * @param str a {@code String} to escape
   466     * @return the escaped version of the {@code String}
   467     */
   468    public String escapeString(String str) {
   469      try {
   470        return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20");
   471      } catch (UnsupportedEncodingException e) {
   472        return str;
   473      }
   474    }
   475  
   476    /**
   477     * Serialize the given Java object into string entity according the given
   478     * Content-Type (only JSON is supported for now).
   479     * @param obj the object to serialize
   480     * @param formParams the form parameters
   481     * @param contentType the content type
   482     * @return an {@code Entity}
   483     * @throws ApiException on failure to serialize
   484     */
   485    public Entity<?> serialize(Object obj, Map<String, Object> formParams, String contentType) throws ApiException {
   486      Entity<?> entity = null;
   487      if (contentType.startsWith("multipart/form-data")) {
   488        MultipartFormDataOutput multipart = new MultipartFormDataOutput();
   489        //MultiPart multiPart = new MultiPart();
   490        for (Entry<String, Object> param: formParams.entrySet()) {
   491          if (param.getValue() instanceof File) {
   492            File file = (File) param.getValue();
   493            try {
   494              multipart.addFormData(param.getValue().toString(),new FileInputStream(file),MediaType.APPLICATION_OCTET_STREAM_TYPE);
   495            } catch (FileNotFoundException e) {
   496              throw new ApiException("Could not serialize multipart/form-data "+e.getMessage());
   497            }
   498          } else {
   499            multipart.addFormData(param.getValue().toString(),param.getValue().toString(),MediaType.APPLICATION_OCTET_STREAM_TYPE);
   500          }
   501        }
   502        entity = Entity.entity(multipart.getFormData(), MediaType.MULTIPART_FORM_DATA_TYPE);
   503      } else if (contentType.startsWith("application/x-www-form-urlencoded")) {
   504        Form form = new Form();
   505        for (Entry<String, Object> param: formParams.entrySet()) {
   506          form.param(param.getKey(), parameterToString(param.getValue()));
   507        }
   508        entity = Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE);
   509      } else {
   510        // We let jersey handle the serialization
   511        entity = Entity.entity(obj, contentType);
   512      }
   513      return entity;
   514    }
   515  
   516    /**
   517     * Deserialize response body to Java object according to the Content-Type.
   518     * @param <T> a Java type parameter
   519     * @param response the response body to deserialize
   520     * @param returnType a Java type to deserialize into
   521     * @return a deserialized Java object
   522     * @throws ApiException on failure to deserialize
   523     */
   524    public <T> T deserialize(Response response, GenericType<T> returnType) throws ApiException {
   525      if (response == null || returnType == null) {
   526        return null;
   527      }
   528  
   529      if ("byte[]".equals(returnType.toString())) {
   530        // Handle binary response (byte array).
   531        return (T) response.readEntity(byte[].class);
   532      } else if (returnType.equals(File.class)) {
   533        // Handle file downloading.
   534        @SuppressWarnings("unchecked")
   535        T file = (T) downloadFileFromResponse(response);
   536        return file;
   537      }
   538  
   539      String contentType = null;
   540      List<Object> contentTypes = response.getHeaders().get("Content-Type");
   541      if (contentTypes != null && !contentTypes.isEmpty())
   542        contentType = String.valueOf(contentTypes.get(0));
   543      if (contentType == null)
   544        throw new ApiException(500, "missing Content-Type in response");
   545  
   546      return response.readEntity(returnType);
   547    }
   548  
   549    /**
   550     * Download file from the given response.
   551     * @param response a response
   552     * @return a file from the given response
   553     * @throws ApiException If fail to read file content from response and write to disk
   554     */
   555    public File downloadFileFromResponse(Response response) throws ApiException {
   556      try {
   557        File file = prepareDownloadFile(response);
   558  {{^supportJava6}}
   559        Files.copy(response.readEntity(InputStream.class), file.toPath());
   560  {{/supportJava6}}
   561  {{#supportJava6}}
   562        // Java6 falls back to commons.io for file copying
   563        FileUtils.copyToFile(response.readEntity(InputStream.class), file);
   564  {{/supportJava6}}
   565        return file;
   566      } catch (IOException e) {
   567        throw new ApiException(e);
   568      }
   569    }
   570  
   571    public File prepareDownloadFile(Response response) throws IOException {
   572      String filename = null;
   573      String contentDisposition = (String) response.getHeaders().getFirst("Content-Disposition");
   574      if (contentDisposition != null && !"".equals(contentDisposition)) {
   575        // Get filename from the Content-Disposition header.
   576        Pattern pattern = Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?");
   577        Matcher matcher = pattern.matcher(contentDisposition);
   578        if (matcher.find())
   579          filename = matcher.group(1);
   580      }
   581  
   582      String prefix = null;
   583      String suffix = null;
   584      if (filename == null) {
   585        prefix = "download-";
   586        suffix = "";
   587      } else {
   588        int pos = filename.lastIndexOf(".");
   589        if (pos == -1) {
   590          prefix = filename + "-";
   591        } else {
   592          prefix = filename.substring(0, pos) + "-";
   593          suffix = filename.substring(pos);
   594        }
   595        // File.createTempFile requires the prefix to be at least three characters long
   596        if (prefix.length() < 3)
   597          prefix = "download-";
   598      }
   599  
   600      if (tempFolderPath == null)
   601        return File.createTempFile(prefix, suffix);
   602      else
   603        return File.createTempFile(prefix, suffix, new File(tempFolderPath));
   604    }
   605  
   606    /**
   607     * Invoke API by sending HTTP request with the given options.
   608     *
   609     * @param <T> a Java type parameter
   610     * @param path The sub-path of the HTTP URL
   611     * @param method The request method, one of "GET", "POST", "PUT", "HEAD" and "DELETE"
   612     * @param queryParams The query parameters
   613     * @param body The request body object
   614     * @param headerParams The header parameters
   615     * @param cookieParams The cookie parameters
   616     * @param formParams The form parameters
   617     * @param accept The request's Accept header
   618     * @param contentType The request's Content-Type header
   619     * @param authNames The authentications to apply
   620     * @param returnType The return type into which to deserialize the response
   621     * @return The response body in type of string
   622     * @throws ApiException if the invocation failed
   623     */
   624    public <T> T invokeAPI(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, String> cookieParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames, GenericType<T> returnType) throws ApiException {
   625      updateParamsForAuth(authNames, queryParams, headerParams, cookieParams);
   626  
   627      // Not using `.target(this.basePath).path(path)` below,
   628      // to support (constant) query string in `path`, e.g. "/posts?draft=1"
   629      WebTarget target = httpClient.target(this.basePath + path);
   630  
   631      if (queryParams != null) {
   632        for (Pair queryParam : queryParams) {
   633          if (queryParam.getValue() != null) {
   634            target = target.queryParam(queryParam.getName(), queryParam.getValue());
   635          }
   636        }
   637      }
   638  
   639      Invocation.Builder invocationBuilder = target.request().accept(accept);
   640  
   641      for (Entry<String, String> headerParamsEnrty : headerParams.entrySet()) {
   642        String value = headerParamsEnrty.getValue();
   643        if (value != null) {
   644          invocationBuilder = invocationBuilder.header(headerParamsEnrty.getKey(), value);
   645        }
   646      }
   647  
   648      for (Entry<String, String> defaultHeaderEnrty: defaultHeaderMap.entrySet()) {
   649        if (!headerParams.containsKey(defaultHeaderEnrty.getKey())) {
   650          String value = defaultHeaderEnrty.getValue();
   651          if (value != null) {
   652            invocationBuilder = invocationBuilder.header(defaultHeaderEnrty.getKey(), value);
   653          }
   654        }
   655      }
   656  
   657      for (Entry<String, String> cookieParamsEntry : cookieParams.entrySet()) {
   658        String value = cookieParamsEntry.getValue();
   659        if (value != null) {
   660          invocationBuilder = invocationBuilder.cookie(cookieParamsEntry.getKey(), value);
   661        }
   662      }
   663  
   664      for (Entry<String, String> defaultCookieEntry: defaultHeaderMap.entrySet()) {
   665        if (!cookieParams.containsKey(defaultCookieEntry.getKey())) {
   666          String value = defaultCookieEntry.getValue();
   667          if (value != null) {
   668            invocationBuilder = invocationBuilder.cookie(defaultCookieEntry.getKey(), value);
   669          }
   670        }
   671      }
   672  
   673      Entity<?> entity = serialize(body, formParams, contentType);
   674  
   675      Response response = null;
   676  
   677      if ("GET".equals(method)) {
   678        response = invocationBuilder.get();
   679      } else if ("POST".equals(method)) {
   680        response = invocationBuilder.post(entity);
   681      } else if ("PUT".equals(method)) {
   682        response = invocationBuilder.put(entity);
   683      } else if ("DELETE".equals(method)) {
   684        response = invocationBuilder.method("DELETE", entity);
   685      } else if ("PATCH".equals(method)) {
   686        response = invocationBuilder.method("PATCH", entity);
   687      } else if ("HEAD".equals(method)) {
   688        response = invocationBuilder.head();
   689      } else if ("OPTIONS".equals(method)) {
   690        response = invocationBuilder.options();
   691      } else if ("TRACE".equals(method)) {
   692        response = invocationBuilder.trace();
   693      } else {
   694        throw new ApiException(500, "unknown method type " + method);
   695      }
   696  
   697      statusCode = response.getStatusInfo().getStatusCode();
   698      responseHeaders = buildResponseHeaders(response);
   699  
   700      if (response.getStatus() == Status.NO_CONTENT.getStatusCode()) {
   701        return null;
   702      } else if (response.getStatusInfo().getFamily().equals(Status.Family.SUCCESSFUL)) {
   703        if (returnType == null)
   704          return null;
   705        else
   706          return deserialize(response, returnType);
   707      } else {
   708        String message = "error";
   709        String respBody = null;
   710        if (response.hasEntity()) {
   711          try {
   712            respBody = String.valueOf(response.readEntity(String.class));
   713            message = respBody;
   714          } catch (RuntimeException e) {
   715            // e.printStackTrace();
   716          }
   717        }
   718        throw new ApiException(
   719          response.getStatus(),
   720          message,
   721          buildResponseHeaders(response),
   722          respBody);
   723      }
   724    }
   725  
   726     /**
   727     * Build the Client used to make HTTP requests.
   728     */
   729    private Client buildHttpClient(boolean debugging) {
   730      final ClientConfiguration clientConfig = new ClientConfiguration(ResteasyProviderFactory.getInstance());
   731      clientConfig.register(json);
   732      if(debugging){
   733        clientConfig.register(Logger.class);
   734      }
   735      return ClientBuilder.newClient(clientConfig);
   736    }
   737    private Map<String, List<String>> buildResponseHeaders(Response response) {
   738      Map<String, List<String>> responseHeaders = new HashMap<String, List<String>>();
   739      for (Entry<String, List<Object>> entry: response.getHeaders().entrySet()) {
   740        List<Object> values = entry.getValue();
   741        List<String> headers = new ArrayList<String>();
   742        for (Object o : values) {
   743          headers.add(String.valueOf(o));
   744        }
   745        responseHeaders.put(entry.getKey(), headers);
   746      }
   747      return responseHeaders;
   748    }
   749  
   750    /**
   751     * Update query and header parameters based on authentication settings.
   752     *
   753     * @param authNames The authentications to apply
   754     */
   755    private void updateParamsForAuth(String[] authNames, List<Pair> queryParams, Map<String, String> headerParams, Map<String, String> cookieParams) {
   756      for (String authName : authNames) {
   757        Authentication auth = authentications.get(authName);
   758        if (auth == null) throw new RuntimeException("Authentication undefined: " + authName);
   759        auth.applyToParams(queryParams, headerParams, cookieParams);
   760      }
   761    }
   762  }