github.com/phrase/openapi@v0.0.0-20240514140800-49e8a106740e/openapi-generator/templates/java/libraries/retrofit/ApiClient.mustache (about) 1 package {{invokerPackage}}; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.lang.reflect.Type; 7 import java.util.LinkedHashMap; 8 import java.util.Map; 9 10 {{#hasOAuthMethods}} 11 import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder; 12 import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder; 13 {{/hasOAuthMethods}} 14 15 import org.joda.time.DateTime; 16 import org.joda.time.LocalDate; 17 import org.joda.time.format.DateTimeFormatter; 18 import org.joda.time.format.ISODateTimeFormat; 19 20 import retrofit.RestAdapter; 21 import retrofit.client.OkClient; 22 import retrofit.converter.ConversionException; 23 import retrofit.converter.Converter; 24 import retrofit.converter.GsonConverter; 25 import retrofit.mime.TypedByteArray; 26 import retrofit.mime.TypedInput; 27 import retrofit.mime.TypedOutput; 28 29 import com.google.gson.Gson; 30 import com.google.gson.GsonBuilder; 31 import com.google.gson.JsonParseException; 32 import com.google.gson.TypeAdapter; 33 import com.google.gson.stream.JsonReader; 34 import com.google.gson.stream.JsonWriter; 35 import com.squareup.okhttp.Interceptor; 36 import com.squareup.okhttp.OkHttpClient; 37 38 import {{invokerPackage}}.auth.HttpBasicAuth; 39 import {{invokerPackage}}.auth.HttpBearerAuth; 40 import {{invokerPackage}}.auth.ApiKeyAuth; 41 {{#hasOAuthMethods}} 42 import {{invokerPackage}}.auth.OAuth; 43 import {{invokerPackage}}.auth.OAuth.AccessTokenListener; 44 import {{invokerPackage}}.auth.OAuthFlow; 45 {{/hasOAuthMethods}} 46 47 public class ApiClient { 48 49 private Map<String, Interceptor> apiAuthorizations; 50 private OkHttpClient okClient; 51 private RestAdapter.Builder adapterBuilder; 52 53 public ApiClient() { 54 apiAuthorizations = new LinkedHashMap<String, Interceptor>(); 55 createDefaultAdapter(); 56 } 57 58 public ApiClient(String[] authNames) { 59 this(); 60 for(String authName : authNames) { 61 {{#hasAuthMethods}} 62 Interceptor auth; 63 {{#authMethods}}if ("{{name}}".equals(authName)) { 64 {{#isBasic}} 65 {{#isBasicBasic}} 66 auth = new HttpBasicAuth(); 67 {{/isBasicBasic}} 68 {{^isBasicBasic}} 69 auth = new HttpBearerAuth("{{scheme}}"); 70 {{/isBasicBasic}} 71 {{/isBasic}} 72 {{#isApiKey}} 73 auth = new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{#isKeyInQuery}}"query"{{/isKeyInQuery}}{{#isKeyInCookie}}"cookie"{{/isKeyInCookie}}, "{{keyParamName}}"); 74 {{/isApiKey}} 75 {{#isOAuth}} 76 auth = new OAuth(OAuthFlow.{{flow}}, "{{authorizationUrl}}", "{{tokenUrl}}", "{{#scopes}}{{scope}}{{^-last}}, {{/-last}}{{/scopes}}"); 77 {{/isOAuth}} 78 } else {{/authMethods}}{ 79 throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names"); 80 } 81 addAuthorization(authName, auth); 82 {{/hasAuthMethods}} 83 {{^hasAuthMethods}} 84 throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names"); 85 {{/hasAuthMethods}} 86 } 87 } 88 89 /** 90 * Basic constructor for single auth name 91 * @param authName Authentication name 92 */ 93 public ApiClient(String authName) { 94 this(new String[]{authName}); 95 } 96 97 /** 98 * Helper constructor for single api key 99 * @param authName Authentication name 100 * @param apiKey API key 101 */ 102 public ApiClient(String authName, String apiKey) { 103 this(authName); 104 this.setApiKey(apiKey); 105 } 106 107 /** 108 * Helper constructor for single basic auth or password oauth2 109 * @param authName Authentication name 110 * @param username Username 111 * @param password Password 112 */ 113 public ApiClient(String authName, String username, String password) { 114 this(authName); 115 this.setCredentials(username, password); 116 } 117 118 {{#hasOAuthMethods}} 119 /** 120 * Helper constructor for single password oauth2 121 * @param authName Authentication name 122 * @param clientId Client ID 123 * @param secret Client secret 124 * @param username Username 125 * @param password Password 126 */ 127 public ApiClient(String authName, String clientId, String secret, String username, String password) { 128 this(authName); 129 this.getTokenEndPoint() 130 .setClientId(clientId) 131 .setClientSecret(secret) 132 .setUsername(username) 133 .setPassword(password); 134 } 135 136 {{/hasOAuthMethods}} 137 public void createDefaultAdapter() { 138 Gson gson = new GsonBuilder() 139 .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ") 140 .registerTypeAdapter(DateTime.class, new DateTimeTypeAdapter()) 141 .registerTypeAdapter(LocalDate.class, new LocalDateTypeAdapter()) 142 .create(); 143 144 okClient = new OkHttpClient(); 145 146 adapterBuilder = new RestAdapter 147 .Builder() 148 .setEndpoint("{{{basePath}}}") 149 .setClient(new OkClient(okClient)) 150 .setConverter(new GsonConverterWrapper(gson)); 151 } 152 153 public <S> S createService(Class<S> serviceClass) { 154 return adapterBuilder.build().create(serviceClass); 155 156 } 157 158 /** 159 * Helper method to configure the first api key found 160 * @param apiKey API key 161 */ 162 private void setApiKey(String apiKey) { 163 for(Interceptor apiAuthorization : apiAuthorizations.values()) { 164 if (apiAuthorization instanceof ApiKeyAuth) { 165 ApiKeyAuth keyAuth = (ApiKeyAuth) apiAuthorization; 166 keyAuth.setApiKey(apiKey); 167 return; 168 } 169 } 170 } 171 172 /** 173 * Helper method to set token for the first Http Bearer authentication found. 174 * @param bearerToken Bearer token 175 */ 176 public void setBearerToken(String bearerToken) { 177 for (Interceptor apiAuthorization : apiAuthorizations.values()) { 178 if (apiAuthorization instanceof HttpBearerAuth) { 179 ((HttpBearerAuth) apiAuthorization).setBearerToken(bearerToken); 180 return; 181 } 182 } 183 } 184 185 /** 186 * Helper method to configure the username/password for basic auth or password oauth 187 * @param username Username 188 * @param password Password 189 */ 190 private void setCredentials(String username, String password) { 191 for(Interceptor apiAuthorization : apiAuthorizations.values()) { 192 if (apiAuthorization instanceof HttpBasicAuth) { 193 HttpBasicAuth basicAuth = (HttpBasicAuth) apiAuthorization; 194 basicAuth.setCredentials(username, password); 195 return; 196 } 197 {{#hasOAuthMethods}} 198 if (apiAuthorization instanceof OAuth) { 199 OAuth oauth = (OAuth) apiAuthorization; 200 oauth.getTokenRequestBuilder().setUsername(username).setPassword(password); 201 return; 202 } 203 {{/hasOAuthMethods}} 204 } 205 } 206 207 {{#hasOAuthMethods}} 208 /** 209 * Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one) 210 * @return Token request builder 211 */ 212 public TokenRequestBuilder getTokenEndPoint() { 213 for(Interceptor apiAuthorization : apiAuthorizations.values()) { 214 if (apiAuthorization instanceof OAuth) { 215 OAuth oauth = (OAuth) apiAuthorization; 216 return oauth.getTokenRequestBuilder(); 217 } 218 } 219 return null; 220 } 221 222 /** 223 * Helper method to configure authorization endpoint of the first oauth found in the apiAuthorizations (there should be only one) 224 * @return Authentication request builder 225 */ 226 public AuthenticationRequestBuilder getAuthorizationEndPoint() { 227 for(Interceptor apiAuthorization : apiAuthorizations.values()) { 228 if (apiAuthorization instanceof OAuth) { 229 OAuth oauth = (OAuth) apiAuthorization; 230 return oauth.getAuthenticationRequestBuilder(); 231 } 232 } 233 return null; 234 } 235 236 /** 237 * Helper method to pre-set the oauth access token of the first oauth found in the apiAuthorizations (there should be only one) 238 * @param accessToken Access token 239 */ 240 public void setAccessToken(String accessToken) { 241 for(Interceptor apiAuthorization : apiAuthorizations.values()) { 242 if (apiAuthorization instanceof OAuth) { 243 OAuth oauth = (OAuth) apiAuthorization; 244 oauth.setAccessToken(accessToken); 245 return; 246 } 247 } 248 } 249 250 /** 251 * Helper method to configure the oauth accessCode/implicit flow parameters 252 * @param clientId Client ID 253 * @param clientSecret Client secret 254 * @param redirectURI Redirect URI 255 */ 256 public void configureAuthorizationFlow(String clientId, String clientSecret, String redirectURI) { 257 for(Interceptor apiAuthorization : apiAuthorizations.values()) { 258 if (apiAuthorization instanceof OAuth) { 259 OAuth oauth = (OAuth) apiAuthorization; 260 oauth.getTokenRequestBuilder() 261 .setClientId(clientId) 262 .setClientSecret(clientSecret) 263 .setRedirectURI(redirectURI); 264 oauth.getAuthenticationRequestBuilder() 265 .setClientId(clientId) 266 .setRedirectURI(redirectURI); 267 return; 268 } 269 } 270 } 271 272 /** 273 * Configures a listener which is notified when a new access token is received. 274 * @param accessTokenListener Access token listener 275 */ 276 public void registerAccessTokenListener(AccessTokenListener accessTokenListener) { 277 for(Interceptor apiAuthorization : apiAuthorizations.values()) { 278 if (apiAuthorization instanceof OAuth) { 279 OAuth oauth = (OAuth) apiAuthorization; 280 oauth.registerAccessTokenListener(accessTokenListener); 281 return; 282 } 283 } 284 } 285 {{/hasOAuthMethods}} 286 287 /** 288 * Adds an authorization to be used by the client 289 * @param authName Authentication name 290 * @param authorization Authorization 291 */ 292 public void addAuthorization(String authName, Interceptor authorization) { 293 if (apiAuthorizations.containsKey(authName)) { 294 throw new RuntimeException("auth name \"" + authName + "\" already in api authorizations"); 295 } 296 apiAuthorizations.put(authName, authorization); 297 okClient.interceptors().add(authorization); 298 } 299 300 public Map<String, Interceptor> getApiAuthorizations() { 301 return apiAuthorizations; 302 } 303 304 public void setApiAuthorizations(Map<String, Interceptor> apiAuthorizations) { 305 this.apiAuthorizations = apiAuthorizations; 306 } 307 308 public RestAdapter.Builder getAdapterBuilder() { 309 return adapterBuilder; 310 } 311 312 public void setAdapterBuilder(RestAdapter.Builder adapterBuilder) { 313 this.adapterBuilder = adapterBuilder; 314 } 315 316 public OkHttpClient getOkClient() { 317 return okClient; 318 } 319 320 public void addAuthsToOkClient(OkHttpClient okClient) { 321 for(Interceptor apiAuthorization : apiAuthorizations.values()) { 322 okClient.interceptors().add(apiAuthorization); 323 } 324 } 325 326 /** 327 * Clones the okClient given in parameter, adds the auth interceptors and uses it to configure the RestAdapter 328 * @param okClient OkHttp client 329 */ 330 public void configureFromOkclient(OkHttpClient okClient) { 331 OkHttpClient clone = okClient.clone(); 332 addAuthsToOkClient(clone); 333 adapterBuilder.setClient(new OkClient(clone)); 334 } 335 } 336 337 /** 338 * This wrapper is to take care of this case: 339 * when the deserialization fails due to JsonParseException and the 340 * expected type is String, then just return the body string. 341 */ 342 class GsonConverterWrapper implements Converter { 343 private GsonConverter converter; 344 345 public GsonConverterWrapper(Gson gson) { 346 converter = new GsonConverter(gson); 347 } 348 349 @Override public Object fromBody(TypedInput body, Type type) throws ConversionException { 350 byte[] bodyBytes = readInBytes(body); 351 TypedByteArray newBody = new TypedByteArray(body.mimeType(), bodyBytes); 352 try { 353 return converter.fromBody(newBody, type); 354 } catch (ConversionException e) { 355 if (e.getCause() instanceof JsonParseException && type.equals(String.class)) { 356 return new String(bodyBytes); 357 } else { 358 throw e; 359 } 360 } 361 } 362 363 @Override public TypedOutput toBody(Object object) { 364 return converter.toBody(object); 365 } 366 367 private byte[] readInBytes(TypedInput body) throws ConversionException { 368 InputStream in = null; 369 try { 370 in = body.in(); 371 ByteArrayOutputStream os = new ByteArrayOutputStream(); 372 byte[] buffer = new byte[0xFFFF]; 373 for (int len; (len = in.read(buffer)) != -1;) 374 os.write(buffer, 0, len); 375 os.flush(); 376 return os.toByteArray(); 377 } catch (IOException e) { 378 throw new ConversionException(e); 379 } finally { 380 if (in != null) { 381 try { 382 in.close(); 383 } catch (IOException ignored) { 384 } 385 } 386 } 387 388 } 389 } 390 391 /** 392 * Gson TypeAdapter for Joda DateTime type 393 */ 394 class DateTimeTypeAdapter extends TypeAdapter<DateTime> { 395 396 private final DateTimeFormatter parseFormatter = ISODateTimeFormat.dateOptionalTimeParser(); 397 private final DateTimeFormatter printFormatter = ISODateTimeFormat.dateTime(); 398 399 @Override 400 public void write(JsonWriter out, DateTime date) throws IOException { 401 if (date == null) { 402 out.nullValue(); 403 } else { 404 out.value(printFormatter.print(date)); 405 } 406 } 407 408 @Override 409 public DateTime read(JsonReader in) throws IOException { 410 switch (in.peek()) { 411 case NULL: 412 in.nextNull(); 413 return null; 414 default: 415 String date = in.nextString(); 416 return parseFormatter.parseDateTime(date); 417 } 418 } 419 } 420 421 /** 422 * Gson TypeAdapter for Joda DateTime type 423 */ 424 class LocalDateTypeAdapter extends TypeAdapter<LocalDate> { 425 426 private final DateTimeFormatter formatter = ISODateTimeFormat.date(); 427 428 @Override 429 public void write(JsonWriter out, LocalDate date) throws IOException { 430 if (date == null) { 431 out.nullValue(); 432 } else { 433 out.value(formatter.print(date)); 434 } 435 } 436 437 @Override 438 public LocalDate read(JsonReader in) throws IOException { 439 switch (in.peek()) { 440 case NULL: 441 in.nextNull(); 442 return null; 443 default: 444 String date = in.nextString(); 445 return formatter.parseLocalDate(date); 446 } 447 } 448 }