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

     1  package {{invokerPackage}};
     2  
     3  import okhttp3.*;
     4  import okio.AsyncTimeout;
     5  import okio.Buffer;
     6  import okio.BufferedSource;
     7  import okio.Timeout;
     8  import play.libs.ws.WSClient;
     9  import play.libs.ws.WSRequest;
    10  import play.libs.ws.WSResponse;
    11  import play.libs.ws.WSRequestFilter;
    12  import play.libs.ws.WSCookie;
    13  
    14  import java.io.IOException;
    15  import java.net.MalformedURLException;
    16  import java.net.URI;
    17  import java.net.URISyntaxException;
    18  import java.util.ArrayList;
    19  import java.util.HashMap;
    20  import java.util.List;
    21  import java.util.Map;
    22  import java.util.Optional;
    23  import java.util.concurrent.CompletionStage;
    24  
    25  /**
    26   * Creates {@link Call} instances that invoke underlying {@link WSClient}
    27   */
    28  public class Play25CallFactory implements okhttp3.Call.Factory {
    29  
    30      /** PlayWS http client */
    31      private final WSClient wsClient;
    32  
    33      /** Extra headers to add to request */
    34      private Map<String, String> extraHeaders = new HashMap<>();
    35  
    36      /** Extra cookies to add to request */
    37      private Map<String, String> extraCookies = new HashMap<>();
    38  
    39      /** Extra query parameters to add to request */
    40      private List<Pair> extraQueryParams = new ArrayList<>();
    41  
    42      /** Filters (interceptors) */
    43      private List<WSRequestFilter> filters = new ArrayList<>();
    44  
    45      public Play25CallFactory(WSClient wsClient) {
    46          this.wsClient = wsClient;
    47      }
    48  
    49      public Play25CallFactory(WSClient wsClient, List<WSRequestFilter> filters) {
    50          this.wsClient = wsClient;
    51          this.filters.addAll(filters);
    52      }
    53  
    54      public Play25CallFactory(WSClient wsClient, Map<String, String> extraHeaders,
    55          Map<String, String> extraCookies,
    56          List<Pair> extraQueryParams) {
    57          this.wsClient = wsClient;
    58  
    59          this.extraHeaders.putAll(extraHeaders);
    60          this.extraCookies.putAll(extraCookies);
    61          this.extraQueryParams.addAll(extraQueryParams);
    62      }
    63  
    64      @Override
    65      public Call newCall(Request request) {
    66          // add extra headers
    67          Request.Builder rb = request.newBuilder();
    68          for (Map.Entry<String, String> header : this.extraHeaders.entrySet()) {
    69              rb.addHeader(header.getKey(), header.getValue());
    70          }
    71          for (Map.Entry<String, String> cookie : this.extraCookies.entrySet()) {
    72              rb.addHeader("Cookie", String.format("%s=%s", cookie.getKey(), cookie.getValue()));
    73          }
    74  
    75          // add extra query params
    76          if (!this.extraQueryParams.isEmpty()) {
    77              String newQuery = request.url().uri().getQuery();
    78              for (Pair queryParam : this.extraQueryParams) {
    79                  String param = String.format("%s=%s", queryParam.getName(), queryParam.getValue());
    80                  if (newQuery == null) {
    81                      newQuery = param;
    82                  } else {
    83                      newQuery += "&" + param;
    84                  }
    85              }
    86  
    87              URI newUri;
    88              try {
    89                  newUri = new URI(request.url().uri().getScheme(), request.url().uri().getAuthority(),
    90                          request.url().uri().getPath(), newQuery, request.url().uri().getFragment());
    91                  rb.url(newUri.toURL());
    92              } catch (MalformedURLException | URISyntaxException e) {
    93                  throw new RuntimeException("Error while updating an url", e);
    94              }
    95          }
    96  
    97          return new PlayWSCall(wsClient, this.filters, rb.build());
    98      }
    99  
   100      /**
   101       * Call implementation that delegates to Play WS Client
   102       */
   103      static class PlayWSCall implements Call {
   104  
   105          private final WSClient wsClient;
   106          private WSRequest wsRequest;
   107          private List<WSRequestFilter> filters;
   108  
   109          private final Request request;
   110          private final AsyncTimeout timeout;
   111  
   112          public PlayWSCall(WSClient wsClient, List<WSRequestFilter> filters, Request request) {
   113              this.wsClient = wsClient;
   114              this.request = request;
   115              this.filters = filters;
   116              this.timeout = new AsyncTimeout();
   117          }
   118  
   119          @Override
   120          public Request request() {
   121              return request;
   122          }
   123  
   124          @Override
   125          public Timeout timeout() {
   126              return timeout;
   127          }
   128  
   129          @Override
   130          public void enqueue(final okhttp3.Callback responseCallback) {
   131              final Call call = this;
   132              final CompletionStage<WSResponse> promise = executeAsync();
   133  
   134              promise.whenCompleteAsync((v, t) -> {
   135                  if (t != null) {
   136                      if (t instanceof IOException) {
   137                          responseCallback.onFailure(call, (IOException) t);
   138                      } else {
   139                          responseCallback.onFailure(call, new IOException(t));
   140                      }
   141                  } else {
   142                      try {
   143                          responseCallback.onResponse(call, PlayWSCall.this.toWSResponse(v));
   144                      } catch (IOException e) {
   145                          throw new RuntimeException(e);
   146                      }
   147                  }
   148              }, play.libs.concurrent.HttpExecution.defaultContext());
   149          }
   150  
   151          CompletionStage<WSResponse> executeAsync() {
   152              try {
   153                  wsRequest = wsClient.url(request.url().uri().toString());
   154                  addHeaders(wsRequest);
   155                  addCookies(wsRequest);
   156                  if (request.body() != null) {
   157                      addBody(wsRequest);
   158                  }
   159                  filters.stream().forEach(f -> wsRequest.withRequestFilter(f));
   160  
   161                  return wsRequest.execute(request.method());
   162              } catch (Exception e) {
   163                  throw new RuntimeException(e.getMessage(), e);
   164              }
   165          }
   166  
   167          private void addHeaders(WSRequest wsRequest) {
   168              for(Map.Entry<String, List<String>> entry : request.headers().toMultimap().entrySet()) {
   169                  List<String> values = entry.getValue();
   170                  for (String value : values) {
   171                      wsRequest.setHeader(entry.getKey(), value);
   172                  }
   173              }
   174          }
   175  
   176          private void addCookies(WSRequest wsRequest) {
   177              final List<String> cookies = request.headers("Cookie");
   178              if (!cookies.isEmpty()) {
   179                  String delimiter = "";
   180                  final StringBuilder cookieHeader = new StringBuilder();
   181                  for (final String cookie : cookies) {
   182                      cookieHeader.append(String.format("%s%s", delimiter, cookie));
   183                      delimiter = "; ";
   184                  }
   185                  wsRequest.setHeader("Cookie", cookieHeader.toString());
   186              }
   187          }
   188  
   189          private void addBody(WSRequest wsRequest) throws IOException {
   190              Buffer buffer = new Buffer();
   191              request.body().writeTo(buffer);
   192              wsRequest.setBody(buffer.inputStream());
   193  
   194              MediaType mediaType = request.body().contentType();
   195              if (mediaType != null) {
   196                  wsRequest.setContentType(mediaType.toString());
   197              }
   198          }
   199  
   200          private Response toWSResponse(final WSResponse r) {
   201              final Response.Builder builder = new Response.Builder();
   202              builder.request(request)
   203                     .code(r.getStatus())
   204                     .body(new ResponseBody() {
   205  
   206                         @Override
   207                         public MediaType contentType() {
   208                             return Optional.ofNullable(r.getHeader("Content-Type"))
   209                                            .map(MediaType::parse)
   210                                            .orElse(null);
   211                         }
   212  
   213                         @Override
   214                         public long contentLength() {
   215                             return r.asByteArray().length;
   216                         }
   217  
   218                         @Override
   219                         public BufferedSource source() {
   220                             return new Buffer().write(r.asByteArray());
   221                         }
   222  
   223                     });
   224  
   225              for (Map.Entry<String, List<String>> entry : r.getAllHeaders().entrySet()) {
   226                  for (String value : entry.getValue()) {
   227                      builder.addHeader(entry.getKey(), value);
   228                  }
   229              }
   230              for (final WSCookie cookie : r.getCookies()) {
   231                  builder.addHeader("Cookie", String.format("%s=%s", cookie.getName(), cookie.getValue()));
   232              }
   233  
   234  
   235              builder.protocol(Protocol.HTTP_1_1);
   236              return builder.build();
   237          }
   238  
   239          @Override
   240          public Response execute() throws IOException {
   241              throw new UnsupportedOperationException("Not supported");
   242          }
   243  
   244          @Override
   245          public void cancel() {
   246              throw new UnsupportedOperationException("Not supported");
   247          }
   248  
   249          @Override
   250          public PlayWSCall clone() {
   251              throw new UnsupportedOperationException("Not supported");
   252          }
   253  
   254          @Override
   255          public boolean isExecuted() {
   256              return false;
   257          }
   258  
   259          @Override
   260          public boolean isCanceled() {
   261              return false;
   262          }
   263      }
   264  }