package br.com.nglauber.starwarsjavarx.model.api; import android.net.Uri; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import java.util.ArrayList; import java.util.HashMap; import br.com.nglauber.starwarsjavarx.model.Character; import br.com.nglauber.starwarsjavarx.model.Movie; import okhttp3.OkHttpClient; import okhttp3.logging.HttpLoggingInterceptor; import retrofit2.Retrofit; import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; import retrofit2.converter.gson.GsonConverterFactory; import rx.Observable; public class StarWarsApiLambda { StarWarsApiDef service; HashMap<String, Person> peopleCache = new HashMap<>(); public StarWarsApiLambda() { HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); httpClient.addInterceptor(logging); Gson gson = new GsonBuilder().setLenient().create(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://swapi.co/api/") .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .client(httpClient.build()) .build(); service = retrofit.create(StarWarsApiDef.class); } public Observable<Movie> loadMovies() { return service.listMovies() .flatMap( filmResult -> Observable.from(filmResult.results) ) .map(film -> new Movie(film.title, film.episodeId, new ArrayList<>())); } public Observable<Movie> loadMoviesFull() { return service.listMovies() .flatMap(filmResult -> Observable.from(filmResult.results) ) .flatMap((film) -> { final Movie movieObj = new Movie(film.title, film.episodeId, new ArrayList<>()); return Observable.zip( Observable.just(movieObj), Observable.from(film.personUrls) .flatMap((personUrl) -> Observable.concat( getCache(personUrl), service.loadPerson(Uri.parse(personUrl).getLastPathSegment()) .doOnNext(person -> peopleCache.put(personUrl, person)) ).first()) .map(person -> new Character(person.name, person.gender)) .toList(), (movie, characters) -> { movie.characters.addAll(characters); return movie; } ); }); } private Observable<Person> getCache(final String personUrl) { return Observable.from(peopleCache.keySet()) .filter(s -> personUrl.equals(s)) .map(s -> peopleCache.get(s)); } }