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