package core.datasource; import android.support.annotation.NonNull; import com.google.gson.ExclusionStrategy; import com.google.gson.FieldAttributes; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import core.ApiClient; import core.Exclude; import java.lang.reflect.Type; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import okhttp3.OkHttpClient; import okhttp3.Request; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; public abstract class RetrofitWrapper extends RestWrapper { private String token; public RetrofitWrapper(ApiClient apiClient, String token) { super(apiClient); this.token = token; } @Override protected <T> T get(ApiClient apiClient) { GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.registerTypeAdapter(Date.class, new DateDeserializer()); gsonBuilder.setExclusionStrategies(new AnnotationExclusionStrategy()); Gson gson = gsonBuilder.setLenient().create(); Retrofit retrofit = new Retrofit.Builder().baseUrl(apiClient.getApiEndpoint()) .addConverterFactory(getConverterFactory(gson)) .client(getClient()) .build(); return get(retrofit); } @NonNull protected GsonConverterFactory getConverterFactory(Gson gson) { return GsonConverterFactory.create(gson); } protected abstract <T> T get(Retrofit retrofit); protected OkHttpClient getClient() { OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.addInterceptor(chain -> { Request original = chain.request(); Request.Builder builder1 = original.newBuilder(); if (token != null) { builder1.addHeader("Authorization", "token " + token); } builder1.addHeader("User-Agent", "Gitskarios"); builder1.addHeader("Accept", "application/vnd.github.v3.json"); builder1.method(original.method(), original.body()); return chain.proceed(builder1.build()); }); return builder.build(); } @Override public boolean isPaginated(retrofit2.Response response) { if (response.headers() != null) { String header = response.headers().get("Link"); if (null != header) { String[] parts = header.split(","); for (String part : parts) { PaginationLink bottomPaginationLink = new PaginationLink(part); return bottomPaginationLink.rel == RelType.next; } } } return false; } @Override public Integer getPage(retrofit2.Response response) { if (isPaginated(response)) { String header = response.headers().get("Link"); if (null != header) { String[] parts = header.split(","); for (String part : parts) { PaginationLink bottomPaginationLink = new PaginationLink(part); if (bottomPaginationLink.rel == RelType.next) { return bottomPaginationLink.page; } } } } return null; } @Override public Integer getLastPage(retrofit2.Response response) { if (isPaginated(response)) { String header = response.headers().get("Link"); if (null != header) { String[] parts = header.split(","); for (String part : parts) { PaginationLink bottomPaginationLink = new PaginationLink(part); if (bottomPaginationLink.rel == RelType.last) { return bottomPaginationLink.page; } } } } return null; } // date deserializer private class DateDeserializer implements JsonDeserializer<Date> { final DateFormat original = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH); @Override public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { Date date = new Date(); try { date = original.parse(json.getAsString()); } catch (ParseException e) { } return date; } } private class AnnotationExclusionStrategy implements ExclusionStrategy { @Override public boolean shouldSkipField(FieldAttributes f) { return f.getAnnotation(Exclude.class) != null; } @Override public boolean shouldSkipClass(Class<?> clazz) { return false; } } }