/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package saulmm.avengers.rest;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.logging.HttpLoggingInterceptor;
import java.lang.reflect.Type;
import java.util.List;
import javax.inject.Inject;
import retrofit.GsonConverterFactory;
import retrofit.Retrofit;
import retrofit.RxJavaCallAdapterFactory;
import rx.Observable;
import rx.functions.Action1;
import rx.functions.Func1;
import saulmm.avengers.entities.CollectionItem;
import saulmm.avengers.entities.MarvelCharacter;
import saulmm.avengers.repository.CharacterRepository;
import saulmm.avengers.rest.exceptions.ServerErrorException;
import saulmm.avengers.rest.exceptions.UknownErrorException;
import saulmm.avengers.rest.utils.deserializers.MarvelResultsDeserializer;
import saulmm.avengers.rest.utils.interceptors.MarvelSigningIterceptor;
import static com.squareup.okhttp.logging.HttpLoggingInterceptor.*;
import static saulmm.avengers.entities.CollectionItem.COMICS;
import static saulmm.avengers.entities.CollectionItem.EVENTS;
import static saulmm.avengers.entities.CollectionItem.SERIES;
import static saulmm.avengers.entities.CollectionItem.STORIES;
public class RestDataSource implements CharacterRepository {
public static String END_POINT = "http://gateway.marvel.com/";
public static String PARAM_API_KEY = "apikey";
public static String PARAM_HASH = "hash";
public static String PARAM_TIMESTAMP = "ts";
private final MarvelApi mMarvelApi;
public final static int MAX_ATTEMPS = 3;
@Inject
public RestDataSource(MarvelAuthorizer marvelAuthorizer) {
OkHttpClient client = new OkHttpClient();
MarvelSigningIterceptor signingIterceptor =
new MarvelSigningIterceptor(
marvelAuthorizer.getApiClient(),
marvelAuthorizer.getApiSecret());
HttpLoggingInterceptor logginInterceptor = new HttpLoggingInterceptor();
logginInterceptor.setLevel(Level.BODY);
client.interceptors().add(signingIterceptor);
client.interceptors().add(logginInterceptor);
Gson customGsonInstance = new GsonBuilder()
.registerTypeAdapter(new TypeToken<List<MarvelCharacter>>() {}.getType(),
new MarvelResultsDeserializer<MarvelCharacter>())
.registerTypeAdapter(new TypeToken<List<CollectionItem>>() {}.getType(),
new MarvelResultsDeserializer<CollectionItem>())
.create();
Retrofit marvelApiAdapter = new Retrofit.Builder()
.baseUrl(END_POINT)
.addConverterFactory(GsonConverterFactory.create(customGsonInstance))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(client)
.build();
mMarvelApi = marvelApiAdapter.create(MarvelApi.class);
}
@Override
public Observable<MarvelCharacter> getCharacter(final int characterId) {
return mMarvelApi.getCharacterById(characterId)
.flatMap(new Func1<List<MarvelCharacter>, Observable<MarvelCharacter>>() {
@Override public Observable<MarvelCharacter> call(List<MarvelCharacter> characters) {
return Observable.just(characters.get(0));
}
});
}
@Override
public Observable<List<MarvelCharacter>> getCharacters(int currentOffset) {
return mMarvelApi.getCharacters(currentOffset)
.onErrorResumeNext(new Func1<Throwable, Observable<? extends List<MarvelCharacter>>>() {
@Override
public Observable<? extends List<MarvelCharacter>> call(Throwable throwable) {
boolean serverError = throwable.getMessage().equals(HttpErrors.SERVER_ERROR);
return Observable.error(
(serverError) ? new ServerErrorException() : new UknownErrorException());
}
});
}
@Override
public Observable<List<CollectionItem>> getCharacterCollection(int characterId, String type) {
if (!type.equals(COMICS) && !type.equals(EVENTS) && !type.equals(SERIES) && !type.equals(STORIES))
throw new IllegalArgumentException("Collection type must be: events|series|comics|stories");
return mMarvelApi.getCharacterCollection(characterId, type);
}
}