github.com/phrase/openapi@v0.0.0-20240514140800-49e8a106740e/openapi-generator/templates/java/libraries/retrofit2/play26/Play26CallAdapterFactory.mustache (about) 1 package {{invokerPackage}}; 2 3 import java.util.concurrent.CompletionStage; 4 import retrofit2.*; 5 6 import java.lang.annotation.Annotation; 7 import java.lang.reflect.ParameterizedType; 8 import java.lang.reflect.Type; 9 import java.lang.reflect.WildcardType; 10 import java.util.concurrent.CompletableFuture; 11 import java.util.concurrent.CompletionStage; 12 import java.util.function.Function; 13 14 /** 15 * Creates {@link CallAdapter} instances that convert {@link Call} into {@link java.util.concurrent.CompletionStage} 16 */ 17 public class Play26CallAdapterFactory extends CallAdapter.Factory { 18 19 private Function<RuntimeException, RuntimeException> exceptionConverter = Function.identity(); 20 21 public Play26CallAdapterFactory() { 22 } 23 24 public Play26CallAdapterFactory( 25 Function<RuntimeException, RuntimeException> exceptionConverter) { 26 this.exceptionConverter = exceptionConverter; 27 } 28 29 @Override 30 public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) { 31 if (!(returnType instanceof ParameterizedType)) { 32 return null; 33 } 34 35 ParameterizedType type = (ParameterizedType) returnType; 36 if (type.getRawType() != CompletionStage.class) { 37 return null; 38 } 39 40 return createAdapter((ParameterizedType) returnType); 41 } 42 43 private CallAdapter<?, CompletionStage<?>> createAdapter(ParameterizedType returnType) { 44 // Get CompletionStage type argument 45 Type[] types = returnType.getActualTypeArguments(); 46 if (types.length != 1) { 47 throw new IllegalStateException("Must be exactly one type parameter"); 48 } 49 50 Type resultType = types[0]; 51 Class<?> rawTypeParam = getRawType(resultType); 52 53 boolean includeResponse = false; 54 if (rawTypeParam == Response.class) { 55 if (!(resultType instanceof ParameterizedType)) { 56 throw new IllegalStateException("Response must be parameterized" 57 + " as Response<T>"); 58 } 59 resultType = ((ParameterizedType) resultType).getActualTypeArguments()[0]; 60 includeResponse = true; 61 } 62 63 return new ValueAdapter(resultType, includeResponse, exceptionConverter); 64 } 65 66 /** 67 * Adpater that coverts values returned by API interface into CompletionStage 68 */ 69 private static final class ValueAdapter<R> implements CallAdapter<R, CompletionStage<R>> { 70 71 private final Type responseType; 72 private final boolean includeResponse; 73 private Function<RuntimeException, RuntimeException> exceptionConverter; 74 75 ValueAdapter(Type responseType, boolean includeResponse, 76 Function<RuntimeException, RuntimeException> exceptionConverter) { 77 this.responseType = responseType; 78 this.includeResponse = includeResponse; 79 this.exceptionConverter = exceptionConverter; 80 } 81 82 @Override 83 public Type responseType() { 84 return responseType; 85 } 86 87 @Override 88 public CompletionStage<R> adapt(final Call<R> call) { 89 final CompletableFuture<R> promise = new CompletableFuture(); 90 91 call.enqueue(new Callback<R>() { 92 93 @Override 94 public void onResponse(Call<R> call, Response<R> response) { 95 if (response.isSuccessful()) { 96 if (includeResponse) { 97 promise.complete((R) response); 98 } else { 99 promise.complete(response.body()); 100 } 101 } else { 102 promise.completeExceptionally(exceptionConverter.apply(new HttpException(response))); 103 } 104 } 105 106 @Override 107 public void onFailure(Call<R> call, Throwable t) { 108 promise.completeExceptionally(t); 109 } 110 111 }); 112 113 return promise; 114 } 115 } 116 }