001package com.jaredsburrows.retrofit2.adapter.synchronous; 002 003import java.lang.annotation.Annotation; 004import java.lang.reflect.ParameterizedType; 005import java.lang.reflect.Type; 006import javax.annotation.Nullable; 007import retrofit2.Call; 008import retrofit2.CallAdapter; 009import retrofit2.Response; 010import retrofit2.Retrofit; 011 012/** 013 * A synchronous {@link CallAdapter.Factory} that uses the same thread for both I/O and 014 * application-level callbacks. 015 * <p> 016 * Adding this class to {@link Retrofit} allows you to return direct deserialized type from service 017 * methods: 018 * <pre><code> 019 * interface MyService { 020 * @GET("user/me") 021 * User getUser() 022 * } 023 * </code></pre> 024 * or allows you to return deserialized type wrapped in {@link Response}: 025 * <pre><code> 026 * interface MyService { 027 * @GET("user/me") 028 * Response<User> getUser() 029 * } 030 * </code></pre> 031 * {@link CallAdapter.Factory} returns the deserialized body for 2XX responses, sets {@link 032 * retrofit2.HttpException} errors for non-2XX responses, and for network errors. 033 */ 034public final class SynchronousCallAdapterFactory extends CallAdapter.Factory { 035 private SynchronousCallAdapterFactory() { 036 } 037 038 public static CallAdapter.Factory create() { 039 return new SynchronousCallAdapterFactory(); 040 } 041 042 @Override @Nullable public CallAdapter<?, ?> get( 043 Type returnType, Annotation[] annotations, Retrofit retrofit) { 044 // Prevent the Async calls via Call class 045 if (getRawType(returnType) == Call.class) { 046 return null; 047 } 048 049 // Return type is not Response<T>. Use it for body-only adapter. 050 if (getRawType(returnType) != Response.class) { 051 return new SynchronousBodyCallAdapter<>(returnType); 052 } 053 054 // Make sure Response<T> is parameterized 055 if (!(returnType instanceof ParameterizedType)) { 056 throw new IllegalStateException( 057 "Response must be parameterized as Response<Foo> or Response<? extends Foo>"); 058 } 059 060 // Handle Response<T> return types 061 Type responseType = getParameterUpperBound(0, (ParameterizedType) returnType); 062 return new SynchronousResponseCallAdapter<>(responseType); 063 } 064}