diff --git a/app/build.gradle b/app/build.gradle index 5eed9f96..06b411c1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,6 +28,10 @@ android { abortOnError false disable 'InvalidPackage' } + + packagingOptions { + exclude 'META-INF/rxjava.properties' + } } dependencies { @@ -40,21 +44,20 @@ dependencies { compile libraries.supportDesign compile libraries.retrofit compile libraries.retrofitGsonConverter - compile libraries.retrofitRx + compile libraries.retrofitRx2 compile libraries.picasso compile libraries.guava annotationProcessor libraries.immutablesValue // <-- for annotation processor provided libraries.immutablesValue // <-- for annotation API provided libraries.immutablesGson // for annotations - compile 'com.nytimes.android:store:2.0.2' - compile'com.nytimes.android:cache:2.0.2' - compile'com.nytimes.android:middleware:2.0.2' - compile 'com.nytimes.android:filesystem:2.0.2' - //compile project(path: ':store') - //compile project(path: ':cache') - //compile project(path: ':middleware') - //compile project(path: ':filesystem') + //compile 'com.nytimes.android:store:2.0.2' + //compile'com.nytimes.android:cache:2.0.2' + //compile'com.nytimes.android:middleware:2.0.2' + //compile 'com.nytimes.android:filesystem:2.0.2' + compile project(path: ':store') + compile project(path: ':cache') + compile project(path: ':middleware') + compile project(path: ':filesystem') retrolambdaConfig libraries.retrolambda - compile libraries.rxAndroid - + compile libraries.rxAndroid2 } diff --git a/app/src/main/java/com/nytimes/android/sample/SampleApp.java b/app/src/main/java/com/nytimes/android/sample/SampleApp.java index c50a9ddd..29c5305b 100644 --- a/app/src/main/java/com/nytimes/android/sample/SampleApp.java +++ b/app/src/main/java/com/nytimes/android/sample/SampleApp.java @@ -1,18 +1,16 @@ package com.nytimes.android.sample; import android.app.Application; -import android.util.Log; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.nytimes.android.external.fs.SourcePersisterFactory; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.MemoryPolicy; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.StoreBuilder; -import com.nytimes.android.external.store.middleware.GsonParserFactory; +import com.nytimes.android.external.fs2.SourcePersisterFactory; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.MemoryPolicy; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; +import com.nytimes.android.external.store2.middleware.GsonParserFactory; import com.nytimes.android.sample.data.model.GsonAdaptersModel; import com.nytimes.android.sample.data.model.RedditData; import com.nytimes.android.sample.data.remote.Api; @@ -20,13 +18,12 @@ import java.io.IOException; import java.util.concurrent.TimeUnit; -import javax.annotation.Nonnull; - +import io.reactivex.Single; +import okhttp3.ResponseBody; import okio.BufferedSource; -import retrofit2.GsonConverterFactory; import retrofit2.Retrofit; -import retrofit2.RxJavaCallAdapterFactory; -import rx.Observable; +import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; public class SampleApp extends Application { @@ -63,11 +60,11 @@ private Store provideRedditStore() { return StoreBuilder.barcode() .fetcher(barCode -> provideRetrofit().fetchSubreddit(barCode.getKey(), "10")) .memoryPolicy( - MemoryPolicy - .builder() - .setExpireAfter(10) - .setExpireAfterTimeUnit(TimeUnit.SECONDS) - .build() + MemoryPolicy + .builder() + .setExpireAfter(10) + .setExpireAfterTimeUnit(TimeUnit.SECONDS) + .build() ) .open(); } @@ -84,16 +81,16 @@ private Persister newPersister() throws IOException { return SourcePersisterFactory.create(getApplicationContext().getCacheDir()); } - private Observable fetcher(BarCode barCode) { + private Single fetcher(BarCode barCode) { return provideRetrofit().fetchSubredditForPersister(barCode.getKey(), "10") - .map(responseBody -> responseBody.source()); + .map(ResponseBody::source); } private Api provideRetrofit() { return new Retrofit.Builder() .baseUrl("http://reddit.com/") .addConverterFactory(GsonConverterFactory.create(provideGson())) - .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .validateEagerly(BuildConfig.DEBUG) // Fail early: check Retrofit configuration at creation time in Debug build. .build() .create(Api.class); diff --git a/app/src/main/java/com/nytimes/android/sample/activity/PersistingStoreActivity.java b/app/src/main/java/com/nytimes/android/sample/activity/PersistingStoreActivity.java index 74e1bf24..63abce3f 100644 --- a/app/src/main/java/com/nytimes/android/sample/activity/PersistingStoreActivity.java +++ b/app/src/main/java/com/nytimes/android/sample/activity/PersistingStoreActivity.java @@ -7,8 +7,8 @@ import android.support.v7.widget.Toolbar; import android.widget.Toast; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.Store; import com.nytimes.android.sample.R; import com.nytimes.android.sample.SampleApp; import com.nytimes.android.sample.data.model.Children; @@ -18,9 +18,9 @@ import java.util.List; -import rx.Observable; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers; import static android.widget.Toast.makeText; @@ -52,12 +52,13 @@ private void initStore() { } } + @SuppressWarnings("CheckReturnValue") public void loadPosts() { BarCode awwRequest = new BarCode(RedditData.class.getSimpleName(), "aww"); this.persistedStore .get(awwRequest) - .flatMap(this::sanitizeData) + .flatMapObservable(this::sanitizeData) .toList() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) @@ -74,7 +75,7 @@ private void showPosts(List posts) { } private Observable sanitizeData(RedditData redditData) { - return Observable.from(redditData.data().children()) + return Observable.fromIterable(redditData.data().children()) .map(Children::data); } diff --git a/app/src/main/java/com/nytimes/android/sample/activity/StoreActivity.java b/app/src/main/java/com/nytimes/android/sample/activity/StoreActivity.java index 9d4ace93..f4391a05 100644 --- a/app/src/main/java/com/nytimes/android/sample/activity/StoreActivity.java +++ b/app/src/main/java/com/nytimes/android/sample/activity/StoreActivity.java @@ -8,8 +8,8 @@ import android.util.Log; import android.widget.Toast; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.Store; import com.nytimes.android.sample.R; import com.nytimes.android.sample.SampleApp; import com.nytimes.android.sample.data.model.Children; @@ -19,9 +19,12 @@ import java.util.List; -import rx.Observable; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Observable; +import io.reactivex.ObservableSource; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.annotations.NonNull; +import io.reactivex.functions.Function; +import io.reactivex.schedulers.Schedulers; import static android.widget.Toast.makeText; @@ -51,12 +54,18 @@ private void initStore() { } } + @SuppressWarnings("CheckReturnValue") public void loadPosts() { BarCode awwRequest = new BarCode(RedditData.class.getSimpleName(), "aww"); this.nonPersistedStore .get(awwRequest) - .flatMap(this::sanitizeData) + .flatMapObservable(new Function>() { + @Override + public ObservableSource apply(@NonNull RedditData redditData) throws Exception { + return sanitizeData(redditData); + } + }) .toList() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) @@ -74,7 +83,7 @@ private void showPosts(List posts) { } private Observable sanitizeData(RedditData redditData) { - return Observable.from(redditData.data().children()) + return Observable.fromIterable(redditData.data().children()) .map(Children::data); } diff --git a/app/src/main/java/com/nytimes/android/sample/data/remote/Api.java b/app/src/main/java/com/nytimes/android/sample/data/remote/Api.java index a10be874..65e8d5a8 100644 --- a/app/src/main/java/com/nytimes/android/sample/data/remote/Api.java +++ b/app/src/main/java/com/nytimes/android/sample/data/remote/Api.java @@ -2,20 +2,19 @@ import com.nytimes.android.sample.data.model.RedditData; -import okhttp3.Response; +import io.reactivex.Single; import okhttp3.ResponseBody; import retrofit2.http.GET; import retrofit2.http.Path; import retrofit2.http.Query; -import rx.Observable; public interface Api { @GET("r/{subredditName}/new/.json") - Observable fetchSubreddit(@Path("subredditName") String subredditName, - @Query("limit") String limit); + Single fetchSubreddit(@Path("subredditName") String subredditName, + @Query("limit") String limit); @GET("r/{subredditName}/new/.json") - Observable fetchSubredditForPersister(@Path("subredditName") String subredditName, - @Query("limit") String limit); + Single fetchSubredditForPersister(@Path("subredditName") String subredditName, + @Query("limit") String limit); } diff --git a/app/src/test/java/com/nytimes/android/sample/StoreIntegrationTest.java b/app/src/test/java/com/nytimes/android/sample/StoreIntegrationTest.java index 3da98901..2b796a48 100644 --- a/app/src/test/java/com/nytimes/android/sample/StoreIntegrationTest.java +++ b/app/src/test/java/com/nytimes/android/sample/StoreIntegrationTest.java @@ -1,42 +1,30 @@ package com.nytimes.android.sample; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.StoreBuilder; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; import org.junit.Before; import org.junit.Test; -import rx.Observable; +import io.reactivex.Single; import static junit.framework.Assert.assertEquals; -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ public class StoreIntegrationTest { private Store testStore; - @Test - public void addition_isCorrect() throws Exception { - - } - - @Before public void setUp() throws Exception { testStore = StoreBuilder.barcode() - .fetcher(barCode -> Observable.just("hello")) + .fetcher(barCode -> Single.just("hello")) .open(); - } @Test public void testRepeatedGet() throws Exception { - String first = testStore.get(BarCode.empty()).toBlocking().first(); + String first = testStore.get(BarCode.empty()).blockingGet(); assertEquals(first, "hello"); } diff --git a/build.gradle b/build.gradle index 226fe864..fb70c488 100644 --- a/build.gradle +++ b/build.gradle @@ -49,13 +49,11 @@ allprojects { } ext { - // SDK versions - // POM file GROUP = "com.nytimes.android" - VERSION_NAME = "2.0.5-SNAPSHOT" + VERSION_NAME = "0.0.1-SNAPSHOT" POM_PACKAGING = "pom" - POM_DESCRIPTION = "Store" + POM_DESCRIPTION = "Store2 is built with RxJava2" POM_URL = "https://github.com/nytimes/Store/" POM_SCM_URL = "https://github.com/nytimes/Store/" diff --git a/buildsystem/dependencies.gradle b/buildsystem/dependencies.gradle index 8b693c94..8d5349cf 100644 --- a/buildsystem/dependencies.gradle +++ b/buildsystem/dependencies.gradle @@ -26,12 +26,14 @@ ext.versions = [ // Reactive. rxJava : '1.2.6', + rxJava2 : '2.0.7', rxJavaProGuardRules : '1.1.6.0', rxJavaAsyncUtil : '0.21.0', rxAndroid : '1.2.1', + rxAndroid2 : '2.0.1', // Others. - retrofit : '2.0.0-beta3', + retrofit : '2.2.0', retrolambda : '2.3.0', dagger : '2.9', jsr305 : '3.0.1', @@ -80,14 +82,16 @@ ext.libraries = [ // Reactive. rxJava : "io.reactivex:rxjava:$versions.rxJava", + rxJava2 : "io.reactivex.rxjava2:rxjava:$versions.rxJava2", rxJavaAsyncUtil : "io.reactivex:rxjava-async-util:$versions.rxJavaAsyncUtil", rxJavaProGuardRules : "com.artemzin.rxjava:proguard-rules:$versions.rxJavaProGuardRules", rxAndroid : "io.reactivex:rxandroid:$versions.rxAndroid", + rxAndroid2 : "io.reactivex.rxjava2:rxandroid:$versions.rxAndroid2", // Others. retrofit : "com.squareup.retrofit2:retrofit:$versions.retrofit", retrofitGsonConverter : "com.squareup.retrofit2:converter-gson:$versions.retrofit", - retrofitRx : "com.squareup.retrofit2:adapter-rxjava:$versions.retrofit", + retrofitRx2 : "com.squareup.retrofit2:adapter-rxjava2:$versions.retrofit", retrolambda : "net.orfjackal.retrolambda:retrolambda:$versions.retrolambda", dagger : "com.google.dagger:dagger:$versions.dagger", daggerCompiler : "com.google.dagger:dagger-compiler:$versions.dagger", diff --git a/filesystem/gradle.properties b/filesystem/gradle.properties index af82b201..44840389 100644 --- a/filesystem/gradle.properties +++ b/filesystem/gradle.properties @@ -1,3 +1,3 @@ POM_NAME=com.nytimes.android -POM_ARTIFACT_ID=filesystem +POM_ARTIFACT_ID=filesystem2 POM_PACKAGING=aar diff --git a/filesystem/src/main/java/com/nytimes/android/external/fs/BarCodePathResolver.java b/filesystem/src/main/java/com/nytimes/android/external/fs2/BarCodePathResolver.java similarity index 67% rename from filesystem/src/main/java/com/nytimes/android/external/fs/BarCodePathResolver.java rename to filesystem/src/main/java/com/nytimes/android/external/fs2/BarCodePathResolver.java index c9da92bb..6ae2a391 100644 --- a/filesystem/src/main/java/com/nytimes/android/external/fs/BarCodePathResolver.java +++ b/filesystem/src/main/java/com/nytimes/android/external/fs2/BarCodePathResolver.java @@ -1,6 +1,6 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; -import com.nytimes.android.external.store.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.BarCode; import javax.annotation.Nonnull; diff --git a/filesystem/src/main/java/com/nytimes/android/external/fs/FSReader.java b/filesystem/src/main/java/com/nytimes/android/external/fs2/FSReader.java similarity index 69% rename from filesystem/src/main/java/com/nytimes/android/external/fs/FSReader.java rename to filesystem/src/main/java/com/nytimes/android/external/fs2/FSReader.java index 5b76697b..94e5f37a 100644 --- a/filesystem/src/main/java/com/nytimes/android/external/fs/FSReader.java +++ b/filesystem/src/main/java/com/nytimes/android/external/fs2/FSReader.java @@ -1,16 +1,16 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; -import com.nytimes.android.external.fs.filesystem.FileSystem; -import com.nytimes.android.external.store.base.DiskRead; +import com.nytimes.android.external.fs2.filesystem.FileSystem; +import com.nytimes.android.external.store2.base.DiskRead; import java.io.FileNotFoundException; import javax.annotation.Nonnull; +import io.reactivex.Maybe; +import io.reactivex.MaybeEmitter; +import io.reactivex.MaybeOnSubscribe; import okio.BufferedSource; -import rx.Emitter; -import rx.Observable; -import rx.functions.Action1; /** * FSReader is used when persisting from file system @@ -31,17 +31,18 @@ public FSReader(FileSystem fileSystem, PathResolver pathResolver) { @Nonnull @Override - public Observable read(@Nonnull final T key) { - return Observable.fromEmitter(new Action1>() { + public Maybe read(@Nonnull final T key) { + return Maybe.create(new MaybeOnSubscribe() { @Override - public void call(Emitter emitter) { + public void subscribe(MaybeEmitter emitter) { String resolvedKey = pathResolver.resolve(key); boolean exists = fileSystem.exists(resolvedKey); + if (exists) { try { BufferedSource bufferedSource = fileSystem.read(resolvedKey); - emitter.onNext(bufferedSource); - emitter.onCompleted(); + emitter.onSuccess(bufferedSource); + emitter.onComplete(); } catch (FileNotFoundException e) { emitter.onError(e); } @@ -49,6 +50,6 @@ public void call(Emitter emitter) { emitter.onError(new FileNotFoundException(ERROR_MESSAGE + resolvedKey)); } } - }, Emitter.BackpressureMode.NONE); + }); } } diff --git a/filesystem/src/main/java/com/nytimes/android/external/fs/FSWriter.java b/filesystem/src/main/java/com/nytimes/android/external/fs2/FSWriter.java similarity index 73% rename from filesystem/src/main/java/com/nytimes/android/external/fs/FSWriter.java rename to filesystem/src/main/java/com/nytimes/android/external/fs2/FSWriter.java index 67bf9e75..52047fa7 100644 --- a/filesystem/src/main/java/com/nytimes/android/external/fs/FSWriter.java +++ b/filesystem/src/main/java/com/nytimes/android/external/fs2/FSWriter.java @@ -1,14 +1,15 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; -import com.nytimes.android.external.fs.filesystem.FileSystem; -import com.nytimes.android.external.store.base.DiskWrite; +import com.nytimes.android.external.fs2.filesystem.FileSystem; +import com.nytimes.android.external.store2.base.DiskWrite; import java.util.concurrent.Callable; import javax.annotation.Nonnull; +import io.reactivex.Single; import okio.BufferedSource; -import rx.Observable; + /** * FSReader is used when persisting to file system * PathResolver will be used in creating file system paths based on cache keys. @@ -26,8 +27,8 @@ public FSWriter(FileSystem fileSystem, PathResolver pathResolver) { @Nonnull @Override - public Observable write(@Nonnull final T key, @Nonnull final BufferedSource data) { - return Observable.fromCallable(new Callable() { + public Single write(@Nonnull final T key, @Nonnull final BufferedSource data) { + return Single.fromCallable(new Callable() { @Nonnull @Override @SuppressWarnings("PMD.SignatureDeclareThrowsException") diff --git a/filesystem/src/main/java/com/nytimes/android/external/fs/FileSystemPersister.java b/filesystem/src/main/java/com/nytimes/android/external/fs2/FileSystemPersister.java similarity index 76% rename from filesystem/src/main/java/com/nytimes/android/external/fs/FileSystemPersister.java rename to filesystem/src/main/java/com/nytimes/android/external/fs2/FileSystemPersister.java index 31a8ca70..df20fc5d 100644 --- a/filesystem/src/main/java/com/nytimes/android/external/fs/FileSystemPersister.java +++ b/filesystem/src/main/java/com/nytimes/android/external/fs2/FileSystemPersister.java @@ -1,12 +1,14 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; -import com.nytimes.android.external.fs.filesystem.FileSystem; -import com.nytimes.android.external.store.base.Persister; +import com.nytimes.android.external.fs2.filesystem.FileSystem; +import com.nytimes.android.external.store2.base.Persister; import javax.annotation.Nonnull; +import io.reactivex.Maybe; +import io.reactivex.Single; import okio.BufferedSource; -import rx.Observable; + /** * FileSystemPersister is used when persisting to/from file system * PathResolver will be used in creating file system paths based on cache keys. @@ -33,13 +35,13 @@ public static Persister create(FileSystem fileSystem, @Nonnull @Override - public Observable read(@Nonnull final T key) { + public Maybe read(@Nonnull final T key) { return fileReader.read(key); } @Nonnull @Override - public Observable write(@Nonnull final T key, @Nonnull final BufferedSource data) { + public Single write(@Nonnull final T key, @Nonnull final BufferedSource data) { return fileWriter.write(key, data); } } diff --git a/filesystem/src/main/java/com/nytimes/android/external/fs/FileSystemPersisterFactory.java b/filesystem/src/main/java/com/nytimes/android/external/fs2/FileSystemPersisterFactory.java similarity index 84% rename from filesystem/src/main/java/com/nytimes/android/external/fs/FileSystemPersisterFactory.java rename to filesystem/src/main/java/com/nytimes/android/external/fs2/FileSystemPersisterFactory.java index bb829d05..9374b2f1 100644 --- a/filesystem/src/main/java/com/nytimes/android/external/fs/FileSystemPersisterFactory.java +++ b/filesystem/src/main/java/com/nytimes/android/external/fs2/FileSystemPersisterFactory.java @@ -1,8 +1,8 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; -import com.nytimes.android.external.fs.filesystem.FileSystem; -import com.nytimes.android.external.fs.filesystem.FileSystemFactory; -import com.nytimes.android.external.store.base.Persister; +import com.nytimes.android.external.fs2.filesystem.FileSystem; +import com.nytimes.android.external.fs2.filesystem.FileSystemFactory; +import com.nytimes.android.external.store2.base.Persister; import java.io.File; import java.io.IOException; @@ -19,7 +19,7 @@ private FileSystemPersisterFactory() { /** * Returns a new {@link BufferedSource} persister with the provided file as the root of the - * persistence {@link com.nytimes.android.external.fs.filesystem.FileSystem}. + * persistence {@link FileSystem}. * * @throws IOException */ @@ -34,7 +34,7 @@ public static Persister create(@Nonnull File root, /** * Returns a new {@link BufferedSource} persister with the provided fileSystem as the root of the - * persistence {@link com.nytimes.android.external.fs.filesystem.FileSystem}. + * persistence {@link FileSystem}. * * @throws IOException */ @@ -49,7 +49,7 @@ public static Persister create(@Nonnull FileSystem fi /** * Returns a new {@link BufferedSource} persister with the provided file as the root of the - * persistence {@link com.nytimes.android.external.fs.filesystem.FileSystem}. + * persistence {@link FileSystem}. * * @throws IOException */ @@ -68,7 +68,7 @@ public static Persister create(@Nonnull File root, /** * Returns a new {@link BufferedSource} persister with the provided fileSystem as the root of the - * persistence {@link com.nytimes.android.external.fs.filesystem.FileSystem}. + * persistence {@link FileSystem}. **/ @Nonnull public static Persister create(@Nonnull FileSystem fileSystem, diff --git a/filesystem/src/main/java/com/nytimes/android/external/fs/FileSystemRecordPersister.java b/filesystem/src/main/java/com/nytimes/android/external/fs2/FileSystemRecordPersister.java similarity index 82% rename from filesystem/src/main/java/com/nytimes/android/external/fs/FileSystemRecordPersister.java rename to filesystem/src/main/java/com/nytimes/android/external/fs2/FileSystemRecordPersister.java index 7ebebcc4..a312d11a 100644 --- a/filesystem/src/main/java/com/nytimes/android/external/fs/FileSystemRecordPersister.java +++ b/filesystem/src/main/java/com/nytimes/android/external/fs2/FileSystemRecordPersister.java @@ -1,16 +1,17 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; -import com.nytimes.android.external.fs.filesystem.FileSystem; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.RecordProvider; -import com.nytimes.android.external.store.base.RecordState; +import com.nytimes.android.external.fs2.filesystem.FileSystem; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.RecordProvider; +import com.nytimes.android.external.store2.base.RecordState; import java.util.concurrent.TimeUnit; import javax.annotation.Nonnull; +import io.reactivex.Maybe; +import io.reactivex.Single; import okio.BufferedSource; -import rx.Observable; /** * FileSystemRecordPersister is used when persisting to/from file system while being stale aware @@ -59,13 +60,13 @@ public RecordState getRecordState(@Nonnull Key key) { @Nonnull @Override - public Observable read(@Nonnull Key key) { + public Maybe read(@Nonnull Key key) { return fileReader.read(key); } @Nonnull @Override - public Observable write(@Nonnull Key key, @Nonnull BufferedSource bufferedSource) { + public Single write(@Nonnull Key key, @Nonnull BufferedSource bufferedSource) { return fileWriter.write(key, bufferedSource); } } diff --git a/filesystem/src/main/java/com/nytimes/android/external/fs/PathResolver.java b/filesystem/src/main/java/com/nytimes/android/external/fs2/PathResolver.java similarity index 88% rename from filesystem/src/main/java/com/nytimes/android/external/fs/PathResolver.java rename to filesystem/src/main/java/com/nytimes/android/external/fs2/PathResolver.java index befbdeae..7c570cbe 100644 --- a/filesystem/src/main/java/com/nytimes/android/external/fs/PathResolver.java +++ b/filesystem/src/main/java/com/nytimes/android/external/fs2/PathResolver.java @@ -1,4 +1,4 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; import javax.annotation.Nonnull; diff --git a/filesystem/src/main/java/com/nytimes/android/external/fs/RecordPersister.java b/filesystem/src/main/java/com/nytimes/android/external/fs2/RecordPersister.java similarity index 78% rename from filesystem/src/main/java/com/nytimes/android/external/fs/RecordPersister.java rename to filesystem/src/main/java/com/nytimes/android/external/fs2/RecordPersister.java index 155cc0ba..5968b614 100644 --- a/filesystem/src/main/java/com/nytimes/android/external/fs/RecordPersister.java +++ b/filesystem/src/main/java/com/nytimes/android/external/fs2/RecordPersister.java @@ -1,9 +1,9 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; -import com.nytimes.android.external.fs.filesystem.FileSystem; -import com.nytimes.android.external.store.base.RecordProvider; -import com.nytimes.android.external.store.base.RecordState; -import com.nytimes.android.external.store.base.impl.BarCode; +import com.nytimes.android.external.fs2.filesystem.FileSystem; +import com.nytimes.android.external.store2.base.RecordProvider; +import com.nytimes.android.external.store2.base.RecordState; +import com.nytimes.android.external.store2.base.impl.BarCode; import java.util.concurrent.TimeUnit; diff --git a/filesystem/src/main/java/com/nytimes/android/external/fs/RecordPersisterFactory.java b/filesystem/src/main/java/com/nytimes/android/external/fs2/RecordPersisterFactory.java similarity index 77% rename from filesystem/src/main/java/com/nytimes/android/external/fs/RecordPersisterFactory.java rename to filesystem/src/main/java/com/nytimes/android/external/fs2/RecordPersisterFactory.java index 529e3586..25ae2bd3 100644 --- a/filesystem/src/main/java/com/nytimes/android/external/fs/RecordPersisterFactory.java +++ b/filesystem/src/main/java/com/nytimes/android/external/fs2/RecordPersisterFactory.java @@ -1,9 +1,9 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; -import com.nytimes.android.external.fs.filesystem.FileSystem; -import com.nytimes.android.external.fs.filesystem.FileSystemFactory; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.impl.BarCode; +import com.nytimes.android.external.fs2.filesystem.FileSystem; +import com.nytimes.android.external.fs2.filesystem.FileSystemFactory; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.impl.BarCode; import java.io.File; import java.io.IOException; @@ -23,7 +23,7 @@ private RecordPersisterFactory() { /** * Returns a new {@link BufferedSource} persister with the provided file as the root of the - * persistence {@link com.nytimes.android.external.fs.filesystem.FileSystem}. + * persistence {@link FileSystem}. * * @throws IOException */ @@ -39,7 +39,7 @@ public static Persister create(@Nonnull File root, /** * Returns a new {@link BufferedSource} persister with the provided fileSystem as the root of the - * persistence {@link com.nytimes.android.external.fs.filesystem.FileSystem}. + * persistence {@link FileSystem}. **/ @Nonnull public static Persister create(@Nonnull FileSystem fileSystem, diff --git a/filesystem/src/main/java/com/nytimes/android/external/fs/SourceFileReader.java b/filesystem/src/main/java/com/nytimes/android/external/fs2/SourceFileReader.java similarity index 64% rename from filesystem/src/main/java/com/nytimes/android/external/fs/SourceFileReader.java rename to filesystem/src/main/java/com/nytimes/android/external/fs2/SourceFileReader.java index 61a872e9..99a1bfdd 100644 --- a/filesystem/src/main/java/com/nytimes/android/external/fs/SourceFileReader.java +++ b/filesystem/src/main/java/com/nytimes/android/external/fs2/SourceFileReader.java @@ -1,9 +1,9 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; -import com.nytimes.android.external.fs.filesystem.FileSystem; -import com.nytimes.android.external.store.base.DiskRead; -import com.nytimes.android.external.store.base.RecordState; -import com.nytimes.android.external.store.base.impl.BarCode; +import com.nytimes.android.external.fs2.filesystem.FileSystem; +import com.nytimes.android.external.store2.base.DiskRead; +import com.nytimes.android.external.store2.base.RecordState; +import com.nytimes.android.external.store2.base.impl.BarCode; import java.util.concurrent.TimeUnit; @@ -11,7 +11,7 @@ import okio.BufferedSource; -import static com.nytimes.android.external.fs.SourcePersister.pathForBarcode; +import static com.nytimes.android.external.fs2.SourcePersister.pathForBarcode; public class SourceFileReader extends FSReader implements DiskRead { diff --git a/filesystem/src/main/java/com/nytimes/android/external/fs/SourceFileWriter.java b/filesystem/src/main/java/com/nytimes/android/external/fs2/SourceFileWriter.java similarity index 52% rename from filesystem/src/main/java/com/nytimes/android/external/fs/SourceFileWriter.java rename to filesystem/src/main/java/com/nytimes/android/external/fs2/SourceFileWriter.java index 08580c72..2b9a5df8 100644 --- a/filesystem/src/main/java/com/nytimes/android/external/fs/SourceFileWriter.java +++ b/filesystem/src/main/java/com/nytimes/android/external/fs2/SourceFileWriter.java @@ -1,8 +1,8 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; -import com.nytimes.android.external.fs.filesystem.FileSystem; -import com.nytimes.android.external.store.base.DiskWrite; -import com.nytimes.android.external.store.base.impl.BarCode; +import com.nytimes.android.external.fs2.filesystem.FileSystem; +import com.nytimes.android.external.store2.base.DiskWrite; +import com.nytimes.android.external.store2.base.impl.BarCode; import okio.BufferedSource; diff --git a/filesystem/src/main/java/com/nytimes/android/external/fs/SourcePersister.java b/filesystem/src/main/java/com/nytimes/android/external/fs2/SourcePersister.java similarity index 72% rename from filesystem/src/main/java/com/nytimes/android/external/fs/SourcePersister.java rename to filesystem/src/main/java/com/nytimes/android/external/fs2/SourcePersister.java index 5888e2ad..8f18a0e4 100644 --- a/filesystem/src/main/java/com/nytimes/android/external/fs/SourcePersister.java +++ b/filesystem/src/main/java/com/nytimes/android/external/fs2/SourcePersister.java @@ -1,15 +1,16 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; -import com.nytimes.android.external.fs.filesystem.FileSystem; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.impl.BarCode; +import com.nytimes.android.external.fs2.filesystem.FileSystem; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.impl.BarCode; import javax.annotation.Nonnull; import javax.inject.Inject; +import io.reactivex.Maybe; +import io.reactivex.Single; import okio.BufferedSource; -import rx.Observable; /** * Persister to be used when storing something to persister from a BufferedSource @@ -44,13 +45,13 @@ static String pathForBarcode(@Nonnull BarCode barCode) { @Nonnull @Override - public Observable read(@Nonnull final BarCode barCode) { + public Maybe read(@Nonnull final BarCode barCode) { return sourceFileReader.read(barCode); } @Nonnull @Override - public Observable write(@Nonnull final BarCode barCode, @Nonnull final BufferedSource data) { + public Single write(@Nonnull final BarCode barCode, @Nonnull final BufferedSource data) { return sourceFileWriter.write(barCode, data); } diff --git a/filesystem/src/main/java/com/nytimes/android/external/fs/SourcePersisterFactory.java b/filesystem/src/main/java/com/nytimes/android/external/fs2/SourcePersisterFactory.java similarity index 79% rename from filesystem/src/main/java/com/nytimes/android/external/fs/SourcePersisterFactory.java rename to filesystem/src/main/java/com/nytimes/android/external/fs2/SourcePersisterFactory.java index d7473705..53c996cd 100644 --- a/filesystem/src/main/java/com/nytimes/android/external/fs/SourcePersisterFactory.java +++ b/filesystem/src/main/java/com/nytimes/android/external/fs2/SourcePersisterFactory.java @@ -1,9 +1,9 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; -import com.nytimes.android.external.fs.filesystem.FileSystem; -import com.nytimes.android.external.fs.filesystem.FileSystemFactory; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.impl.BarCode; +import com.nytimes.android.external.fs2.filesystem.FileSystem; +import com.nytimes.android.external.fs2.filesystem.FileSystemFactory; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.impl.BarCode; import java.io.File; import java.io.IOException; @@ -24,7 +24,7 @@ private SourcePersisterFactory() { /** * Returns a new {@link BufferedSource} persister with the provided file as the root of the - * persistence {@link com.nytimes.android.external.fs.filesystem.FileSystem}. + * persistence {@link FileSystem}. * * @throws IOException */ @@ -40,7 +40,7 @@ public static Persister create(@Nonnull File root, /** * Returns a new {@link BufferedSource} persister with the provided fileSystem as the root of the - * persistence {@link com.nytimes.android.external.fs.filesystem.FileSystem}. + * persistence {@link FileSystem}. **/ @Nonnull public static Persister create(@Nonnull FileSystem fileSystem, @@ -54,7 +54,7 @@ public static Persister create(@Nonnull FileSystem file /** * Returns a new {@link BufferedSource} persister with the provided file as the root of the - * persistence {@link com.nytimes.android.external.fs.filesystem.FileSystem}. + * persistence {@link FileSystem}. * * @throws IOException */ @@ -68,7 +68,7 @@ public static Persister create(@Nonnull File root) thro /** * Returns a new {@link BufferedSource} persister with the provided fileSystem as the root of the - * persistence {@link com.nytimes.android.external.fs.filesystem.FileSystem}. + * persistence {@link FileSystem}. **/ @Nonnull public static Persister create(@Nonnull FileSystem fileSystem) { diff --git a/filesystem/src/main/java/com/nytimes/android/external/fs/Util.java b/filesystem/src/main/java/com/nytimes/android/external/fs2/Util.java similarity index 98% rename from filesystem/src/main/java/com/nytimes/android/external/fs/Util.java rename to filesystem/src/main/java/com/nytimes/android/external/fs2/Util.java index 24f997c2..d2ee25e2 100644 --- a/filesystem/src/main/java/com/nytimes/android/external/fs/Util.java +++ b/filesystem/src/main/java/com/nytimes/android/external/fs2/Util.java @@ -1,4 +1,4 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; import java.io.File; diff --git a/filesystem/src/main/java/com/nytimes/android/external/fs/filesystem/BreadthFirstFileTreeIterator.java b/filesystem/src/main/java/com/nytimes/android/external/fs2/filesystem/BreadthFirstFileTreeIterator.java similarity index 98% rename from filesystem/src/main/java/com/nytimes/android/external/fs/filesystem/BreadthFirstFileTreeIterator.java rename to filesystem/src/main/java/com/nytimes/android/external/fs2/filesystem/BreadthFirstFileTreeIterator.java index 78b591ab..fb8e6e89 100644 --- a/filesystem/src/main/java/com/nytimes/android/external/fs/filesystem/BreadthFirstFileTreeIterator.java +++ b/filesystem/src/main/java/com/nytimes/android/external/fs2/filesystem/BreadthFirstFileTreeIterator.java @@ -1,4 +1,4 @@ -package com.nytimes.android.external.fs.filesystem; +package com.nytimes.android.external.fs2.filesystem; /* * Copyright 2004-2007 the original author or authors. diff --git a/filesystem/src/main/java/com/nytimes/android/external/fs/filesystem/FSFile.java b/filesystem/src/main/java/com/nytimes/android/external/fs2/filesystem/FSFile.java similarity index 95% rename from filesystem/src/main/java/com/nytimes/android/external/fs/filesystem/FSFile.java rename to filesystem/src/main/java/com/nytimes/android/external/fs2/filesystem/FSFile.java index e03b4e81..c70b73b3 100644 --- a/filesystem/src/main/java/com/nytimes/android/external/fs/filesystem/FSFile.java +++ b/filesystem/src/main/java/com/nytimes/android/external/fs2/filesystem/FSFile.java @@ -1,7 +1,7 @@ -package com.nytimes.android.external.fs.filesystem; +package com.nytimes.android.external.fs2.filesystem; -import com.nytimes.android.external.fs.Util; +import com.nytimes.android.external.fs2.Util; import java.io.File; import java.io.FileNotFoundException; diff --git a/filesystem/src/main/java/com/nytimes/android/external/fs/filesystem/FileSystem.java b/filesystem/src/main/java/com/nytimes/android/external/fs2/filesystem/FileSystem.java similarity index 97% rename from filesystem/src/main/java/com/nytimes/android/external/fs/filesystem/FileSystem.java rename to filesystem/src/main/java/com/nytimes/android/external/fs2/filesystem/FileSystem.java index bfe2524a..6df95584 100644 --- a/filesystem/src/main/java/com/nytimes/android/external/fs/filesystem/FileSystem.java +++ b/filesystem/src/main/java/com/nytimes/android/external/fs2/filesystem/FileSystem.java @@ -1,6 +1,6 @@ -package com.nytimes.android.external.fs.filesystem; +package com.nytimes.android.external.fs2.filesystem; -import com.nytimes.android.external.store.base.RecordState; +import com.nytimes.android.external.store2.base.RecordState; import java.io.File; import java.io.FileNotFoundException; diff --git a/filesystem/src/main/java/com/nytimes/android/external/fs/filesystem/FileSystemFactory.java b/filesystem/src/main/java/com/nytimes/android/external/fs2/filesystem/FileSystemFactory.java similarity index 91% rename from filesystem/src/main/java/com/nytimes/android/external/fs/filesystem/FileSystemFactory.java rename to filesystem/src/main/java/com/nytimes/android/external/fs2/filesystem/FileSystemFactory.java index 902fb5ce..71696ef8 100644 --- a/filesystem/src/main/java/com/nytimes/android/external/fs/filesystem/FileSystemFactory.java +++ b/filesystem/src/main/java/com/nytimes/android/external/fs2/filesystem/FileSystemFactory.java @@ -1,4 +1,4 @@ -package com.nytimes.android.external.fs.filesystem; +package com.nytimes.android.external.fs2.filesystem; import java.io.File; import java.io.IOException; diff --git a/filesystem/src/main/java/com/nytimes/android/external/fs/filesystem/FileSystemImpl.java b/filesystem/src/main/java/com/nytimes/android/external/fs2/filesystem/FileSystemImpl.java similarity index 96% rename from filesystem/src/main/java/com/nytimes/android/external/fs/filesystem/FileSystemImpl.java rename to filesystem/src/main/java/com/nytimes/android/external/fs2/filesystem/FileSystemImpl.java index ea187b43..84633804 100644 --- a/filesystem/src/main/java/com/nytimes/android/external/fs/filesystem/FileSystemImpl.java +++ b/filesystem/src/main/java/com/nytimes/android/external/fs2/filesystem/FileSystemImpl.java @@ -1,9 +1,9 @@ -package com.nytimes.android.external.fs.filesystem; +package com.nytimes.android.external.fs2.filesystem; import com.nytimes.android.external.cache.CacheLoader; import com.nytimes.android.external.cache.LoadingCache; -import com.nytimes.android.external.fs.Util; -import com.nytimes.android.external.store.base.RecordState; +import com.nytimes.android.external.fs2.Util; +import com.nytimes.android.external.store2.base.RecordState; import java.io.File; import java.io.FileNotFoundException; diff --git a/filesystem/src/test/java/com/nytimes/android/external/fs/FilePersisterTest.java b/filesystem/src/test/java/com/nytimes/android/external/fs2/FilePersisterTest.java similarity index 68% rename from filesystem/src/test/java/com/nytimes/android/external/fs/FilePersisterTest.java rename to filesystem/src/test/java/com/nytimes/android/external/fs2/FilePersisterTest.java index 3a296a7b..76b47fbc 100644 --- a/filesystem/src/test/java/com/nytimes/android/external/fs/FilePersisterTest.java +++ b/filesystem/src/test/java/com/nytimes/android/external/fs2/FilePersisterTest.java @@ -1,13 +1,11 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; -import com.nytimes.android.external.fs.filesystem.FileSystem; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.impl.BarCode; +import com.nytimes.android.external.fs2.filesystem.FileSystem; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.impl.BarCode; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -22,14 +20,14 @@ import static org.mockito.Mockito.when; public class FilePersisterTest { - private static final BarCode simple = new BarCode("type", "key"); - private static final String resolvedPath = new BarCodePathResolver().resolve(simple); - @Rule - public ExpectedException expectedException = ExpectedException.none(); + @Mock FileSystem fileSystem; @Mock BufferedSource bufferedSource; + + private final BarCode simple = new BarCode("type", "key"); + private final String resolvedPath = new BarCodePathResolver().resolve(simple); private Persister fileSystemPersister; @Before @@ -44,23 +42,26 @@ public void readExists() throws FileNotFoundException { .thenReturn(true); when(fileSystem.read(resolvedPath)).thenReturn(bufferedSource); - BufferedSource returnedValue = fileSystemPersister.read(simple).toBlocking().single(); + BufferedSource returnedValue = fileSystemPersister.read(simple).blockingGet(); assertThat(returnedValue).isEqualTo(bufferedSource); } @Test - public void readDoesNotExist() { + @SuppressWarnings("CheckReturnValue") + public void readDoesNotExist() throws FileNotFoundException { when(fileSystem.exists(resolvedPath)) .thenReturn(false); - fileSystemPersister.read(simple).test().awaitTerminalEvent().assertError(FileNotFoundException.class); + + fileSystemPersister.read(simple).test().assertError(FileNotFoundException.class); } @Test + @SuppressWarnings("CheckReturnValue") public void writeThenRead() throws IOException { when(fileSystem.read(resolvedPath)).thenReturn(bufferedSource); when(fileSystem.exists(resolvedPath)).thenReturn(true); - fileSystemPersister.write(simple, bufferedSource).toBlocking().single(); - BufferedSource source = fileSystemPersister.read(simple).toBlocking().first(); + fileSystemPersister.write(simple, bufferedSource).blockingGet(); + BufferedSource source = fileSystemPersister.read(simple).blockingGet(); InOrder inOrder = inOrder(fileSystem); inOrder.verify(fileSystem).write(resolvedPath, bufferedSource); inOrder.verify(fileSystem).exists(resolvedPath); @@ -68,5 +69,4 @@ public void writeThenRead() throws IOException { assertThat(source).isEqualTo(bufferedSource); } - } diff --git a/filesystem/src/test/java/com/nytimes/android/external/fs/FileSystemRecordPersisterTest.java b/filesystem/src/test/java/com/nytimes/android/external/fs2/FileSystemRecordPersisterTest.java similarity index 75% rename from filesystem/src/test/java/com/nytimes/android/external/fs/FileSystemRecordPersisterTest.java rename to filesystem/src/test/java/com/nytimes/android/external/fs2/FileSystemRecordPersisterTest.java index 4dd4928d..feb76542 100644 --- a/filesystem/src/test/java/com/nytimes/android/external/fs/FileSystemRecordPersisterTest.java +++ b/filesystem/src/test/java/com/nytimes/android/external/fs2/FileSystemRecordPersisterTest.java @@ -1,13 +1,11 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; -import com.nytimes.android.external.fs.filesystem.FileSystem; -import com.nytimes.android.external.store.base.RecordState; -import com.nytimes.android.external.store.base.impl.BarCode; +import com.nytimes.android.external.fs2.filesystem.FileSystem; +import com.nytimes.android.external.store2.base.RecordState; +import com.nytimes.android.external.store2.base.impl.BarCode; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -23,14 +21,14 @@ import static org.mockito.Mockito.when; public class FileSystemRecordPersisterTest { - private static final BarCode simple = new BarCode("type", "key"); - private static final String resolvedPath = new BarCodePathResolver().resolve(simple); - @Rule - public ExpectedException expectedException = ExpectedException.none(); + @Mock FileSystem fileSystem; @Mock BufferedSource bufferedSource; + + private final BarCode simple = new BarCode("type", "key"); + private final String resolvedPath = new BarCodePathResolver().resolve(simple); private FileSystemRecordPersister fileSystemPersister; @Before @@ -47,28 +45,26 @@ public void readExists() throws FileNotFoundException { .thenReturn(true); when(fileSystem.read(resolvedPath)).thenReturn(bufferedSource); - BufferedSource returnedValue = fileSystemPersister.read(simple).toBlocking().single(); + BufferedSource returnedValue = fileSystemPersister.read(simple).blockingGet(); assertThat(returnedValue).isEqualTo(bufferedSource); } @Test - public void readDoesNotExist() { + @SuppressWarnings("CheckReturnValue") + public void readDoesNotExist() throws FileNotFoundException { when(fileSystem.exists(resolvedPath)) .thenReturn(false); - fileSystemPersister - .read(simple) - .test() - .awaitTerminalEvent() - .assertError(FileNotFoundException.class); + fileSystemPersister.read(simple).test().assertError(FileNotFoundException.class); } @Test + @SuppressWarnings("CheckReturnValue") public void writeThenRead() throws IOException { when(fileSystem.read(resolvedPath)).thenReturn(bufferedSource); when(fileSystem.exists(resolvedPath)).thenReturn(true); - fileSystemPersister.write(simple, bufferedSource).toBlocking().single(); - BufferedSource source = fileSystemPersister.read(simple).toBlocking().first(); + fileSystemPersister.write(simple, bufferedSource).blockingGet(); + BufferedSource source = fileSystemPersister.read(simple).blockingGet(); InOrder inOrder = inOrder(fileSystem); inOrder.verify(fileSystem).write(resolvedPath, bufferedSource); inOrder.verify(fileSystem).exists(resolvedPath); diff --git a/filesystem/src/test/java/com/nytimes/android/external/fs/MultiTest.java b/filesystem/src/test/java/com/nytimes/android/external/fs2/MultiTest.java similarity index 92% rename from filesystem/src/test/java/com/nytimes/android/external/fs/MultiTest.java rename to filesystem/src/test/java/com/nytimes/android/external/fs2/MultiTest.java index 8ca61cc7..2933cde1 100644 --- a/filesystem/src/test/java/com/nytimes/android/external/fs/MultiTest.java +++ b/filesystem/src/test/java/com/nytimes/android/external/fs2/MultiTest.java @@ -1,8 +1,8 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; import com.google.common.collect.ImmutableMap; -import com.nytimes.android.external.fs.filesystem.FileSystem; -import com.nytimes.android.external.fs.filesystem.FileSystemFactory; +import com.nytimes.android.external.fs2.filesystem.FileSystem; +import com.nytimes.android.external.fs2.filesystem.FileSystemFactory; import org.junit.Test; diff --git a/filesystem/src/test/java/com/nytimes/android/external/fs/RecordPersisterTest.java b/filesystem/src/test/java/com/nytimes/android/external/fs2/RecordPersisterTest.java similarity index 77% rename from filesystem/src/test/java/com/nytimes/android/external/fs/RecordPersisterTest.java rename to filesystem/src/test/java/com/nytimes/android/external/fs2/RecordPersisterTest.java index a5cc290e..31dbe754 100644 --- a/filesystem/src/test/java/com/nytimes/android/external/fs/RecordPersisterTest.java +++ b/filesystem/src/test/java/com/nytimes/android/external/fs2/RecordPersisterTest.java @@ -1,13 +1,11 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; -import com.nytimes.android.external.fs.filesystem.FileSystem; -import com.nytimes.android.external.store.base.RecordState; -import com.nytimes.android.external.store.base.impl.BarCode; +import com.nytimes.android.external.fs2.filesystem.FileSystem; +import com.nytimes.android.external.store2.base.RecordState; +import com.nytimes.android.external.store2.base.impl.BarCode; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -21,14 +19,14 @@ import static org.mockito.Mockito.when; public class RecordPersisterTest { - private static final BarCode simple = new BarCode("type", "key"); - @Rule - public ExpectedException expectedException = ExpectedException.none(); + @Mock FileSystem fileSystem; @Mock BufferedSource bufferedSource; + private RecordPersister sourcePersister; + private final BarCode simple = new BarCode("type", "key"); @Before public void setUp() { @@ -42,7 +40,7 @@ public void readExists() throws FileNotFoundException { .thenReturn(true); when(fileSystem.read(simple.toString())).thenReturn(bufferedSource); - BufferedSource returnedValue = sourcePersister.read(simple).toBlocking().single(); + BufferedSource returnedValue = sourcePersister.read(simple).blockingGet(); assertThat(returnedValue).isEqualTo(bufferedSource); } @@ -71,20 +69,17 @@ public void missingTest() { } @Test + @SuppressWarnings("CheckReturnValue") public void readDoesNotExist() throws FileNotFoundException { when(fileSystem.exists(SourcePersister.pathForBarcode(simple))) .thenReturn(false); - sourcePersister - .read(simple) - .test() - .awaitTerminalEvent() - .assertError(FileNotFoundException.class); + sourcePersister.read(simple).test().assertError(FileNotFoundException.class); } @Test public void write() throws IOException { - assertThat(sourcePersister.write(simple, bufferedSource).toBlocking().single()).isTrue(); + assertThat(sourcePersister.write(simple, bufferedSource).blockingGet()).isTrue(); } @Test diff --git a/filesystem/src/test/java/com/nytimes/android/external/fs/SourceDiskDaoStoreTest.java b/filesystem/src/test/java/com/nytimes/android/external/fs2/SourceDiskDaoStoreTest.java similarity index 70% rename from filesystem/src/test/java/com/nytimes/android/external/fs/SourceDiskDaoStoreTest.java rename to filesystem/src/test/java/com/nytimes/android/external/fs2/SourceDiskDaoStoreTest.java index 68f5bfbe..1a16764d 100644 --- a/filesystem/src/test/java/com/nytimes/android/external/fs/SourceDiskDaoStoreTest.java +++ b/filesystem/src/test/java/com/nytimes/android/external/fs2/SourceDiskDaoStoreTest.java @@ -1,12 +1,12 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; import com.google.gson.Gson; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.StoreBuilder; -import com.nytimes.android.external.store.middleware.GsonSourceParser; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; +import com.nytimes.android.external.store2.middleware.GsonSourceParser; import org.junit.Test; import org.mockito.Mock; @@ -14,9 +14,10 @@ import java.io.ByteArrayInputStream; +import io.reactivex.Maybe; +import io.reactivex.Single; import okio.BufferedSource; import okio.Okio; -import rx.Observable; import static com.google.common.base.Charsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; @@ -54,20 +55,20 @@ public void testSimple() { BufferedSource source = source(sourceData); - Observable value = Observable.just(source); + Single value = Single.just(source); when(fetcher.fetch(barCode)) .thenReturn(value); when(diskDAO.read(barCode)) - .thenReturn(Observable.empty()) - .thenReturn(value); + .thenReturn(Maybe.empty()) + .thenReturn(value.toMaybe()); when(diskDAO.write(barCode, source)) - .thenReturn(Observable.just(true)); + .thenReturn(Single.just(true)); - Foo result = store.get(barCode).toBlocking().first(); + Foo result = store.get(barCode).blockingGet(); assertThat(result.bar).isEqualTo(KEY); - result = store.get(barCode).toBlocking().first(); + result = store.get(barCode).blockingGet(); assertThat(result.bar).isEqualTo(KEY); verify(fetcher, times(1)).fetch(barCode); } diff --git a/filesystem/src/test/java/com/nytimes/android/external/fs/SourceFilerReaderWriterStoreTest.java b/filesystem/src/test/java/com/nytimes/android/external/fs2/SourceFilerReaderWriterStoreTest.java similarity index 71% rename from filesystem/src/test/java/com/nytimes/android/external/fs/SourceFilerReaderWriterStoreTest.java rename to filesystem/src/test/java/com/nytimes/android/external/fs2/SourceFilerReaderWriterStoreTest.java index 800990ad..8e4ed779 100644 --- a/filesystem/src/test/java/com/nytimes/android/external/fs/SourceFilerReaderWriterStoreTest.java +++ b/filesystem/src/test/java/com/nytimes/android/external/fs2/SourceFilerReaderWriterStoreTest.java @@ -1,11 +1,11 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; import com.google.gson.Gson; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.StoreBuilder; -import com.nytimes.android.external.store.middleware.GsonSourceParser; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; +import com.nytimes.android.external.store2.middleware.GsonSourceParser; import org.junit.Test; import org.mockito.Mock; @@ -13,9 +13,10 @@ import java.io.ByteArrayInputStream; +import io.reactivex.Maybe; +import io.reactivex.Single; import okio.BufferedSource; import okio.Okio; -import rx.Observable; import static com.google.common.base.Charsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; @@ -54,20 +55,20 @@ public void testSimple() { String sourceData = new Gson().toJson(foo); BufferedSource source = source(sourceData); - Observable value = Observable.just(source); + Single value = Single.just(source); when(fetcher.fetch(barCode)) .thenReturn(value); when(fileReader.read(barCode)) - .thenReturn(Observable.empty()) - .thenReturn(value); + .thenReturn(Maybe.empty()) + .thenReturn(value.toMaybe()); when(fileWriter.write(barCode, source)) - .thenReturn(Observable.just(true)); + .thenReturn(Single.just(true)); - Foo result = simpleStore.get(barCode).toBlocking().first(); + Foo result = simpleStore.get(barCode).blockingGet(); assertThat(result.bar).isEqualTo(KEY); - result = simpleStore.get(barCode).toBlocking().first(); + result = simpleStore.get(barCode).blockingGet(); assertThat(result.bar).isEqualTo(KEY); verify(fetcher, times(1)).fetch(barCode); } diff --git a/filesystem/src/test/java/com/nytimes/android/external/fs/SourcePersisterTest.java b/filesystem/src/test/java/com/nytimes/android/external/fs2/SourcePersisterTest.java similarity index 72% rename from filesystem/src/test/java/com/nytimes/android/external/fs/SourcePersisterTest.java rename to filesystem/src/test/java/com/nytimes/android/external/fs2/SourcePersisterTest.java index e76d047d..bb3bf645 100644 --- a/filesystem/src/test/java/com/nytimes/android/external/fs/SourcePersisterTest.java +++ b/filesystem/src/test/java/com/nytimes/android/external/fs2/SourcePersisterTest.java @@ -1,10 +1,12 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; -import com.nytimes.android.external.fs.filesystem.FileSystem; -import com.nytimes.android.external.store.base.impl.BarCode; +import com.nytimes.android.external.fs2.filesystem.FileSystem; +import com.nytimes.android.external.store2.base.impl.BarCode; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -17,12 +19,17 @@ import static org.mockito.Mockito.when; public class SourcePersisterTest { - private static final BarCode simple = new BarCode("type", "key"); + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Mock FileSystem fileSystem; @Mock BufferedSource bufferedSource; + private SourcePersister sourcePersister; + private final BarCode simple = new BarCode("type", "key"); @Before public void setUp() { @@ -36,24 +43,22 @@ public void readExists() throws FileNotFoundException { .thenReturn(true); when(fileSystem.read(simple.toString())).thenReturn(bufferedSource); - BufferedSource returnedValue = sourcePersister.read(simple).toBlocking().single(); + BufferedSource returnedValue = sourcePersister.read(simple).blockingGet(); assertThat(returnedValue).isEqualTo(bufferedSource); } @Test + @SuppressWarnings("CheckReturnValue") public void readDoesNotExist() throws FileNotFoundException { when(fileSystem.exists(SourcePersister.pathForBarcode(simple))) .thenReturn(false); - sourcePersister.read(simple) - .test() - .awaitTerminalEvent() - .assertError(FileNotFoundException.class); + sourcePersister.read(simple).test().assertError(FileNotFoundException.class); } @Test public void write() throws IOException { - assertThat(sourcePersister.write(simple, bufferedSource).toBlocking().single()).isTrue(); + assertThat(sourcePersister.write(simple, bufferedSource).blockingGet()).isTrue(); } @Test diff --git a/filesystem/src/test/java/com/nytimes/android/external/fs2/StoreNetworkBeforeStaleFailTest.java b/filesystem/src/test/java/com/nytimes/android/external/fs2/StoreNetworkBeforeStaleFailTest.java new file mode 100644 index 00000000..bcfae6eb --- /dev/null +++ b/filesystem/src/test/java/com/nytimes/android/external/fs2/StoreNetworkBeforeStaleFailTest.java @@ -0,0 +1,76 @@ +package com.nytimes.android.external.fs2; + +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.RecordProvider; +import com.nytimes.android.external.store2.base.RecordState; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.runners.MockitoJUnitRunner; + +import javax.annotation.Nonnull; + +import io.reactivex.Maybe; +import io.reactivex.Single; +import okio.BufferedSource; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class StoreNetworkBeforeStaleFailTest { + private static final Exception sorry = new Exception("sorry"); + private static final BarCode barCode = new BarCode("key", "value"); + @Mock + Fetcher fetcher; + Store store; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + store = StoreBuilder.barcode() + .fetcher(fetcher) + .persister(new TestPersister()) + .networkBeforeStale() + .open(); + + } + + @Test + public void networkBeforeStaleNoNetworkResponse() { + Single exception = Single.error(sorry); + when(fetcher.fetch(barCode)) + .thenReturn(exception); + store.get(barCode).test().assertError(sorry); + verify(fetcher, times(1)).fetch(barCode); + } + + final class TestPersister implements Persister, RecordProvider { + @Nonnull + @Override + public RecordState getRecordState(@Nonnull BarCode barCode) { + return RecordState.MISSING; + } + + @Nonnull + @Override + public Maybe read(@Nonnull BarCode barCode) { + return Maybe.error(sorry); + } + + @Nonnull + @Override + public Single write(@Nonnull BarCode barCode, + @Nonnull BufferedSource bufferedSource) { + return Single.just(true); + } + } +} diff --git a/filesystem/src/test/java/com/nytimes/android/external/fs/StoreNetworkBeforeStaleTest.java b/filesystem/src/test/java/com/nytimes/android/external/fs2/StoreNetworkBeforeStaleTest.java similarity index 70% rename from filesystem/src/test/java/com/nytimes/android/external/fs/StoreNetworkBeforeStaleTest.java rename to filesystem/src/test/java/com/nytimes/android/external/fs2/StoreNetworkBeforeStaleTest.java index a6988661..5a1c8d4e 100644 --- a/filesystem/src/test/java/com/nytimes/android/external/fs/StoreNetworkBeforeStaleTest.java +++ b/filesystem/src/test/java/com/nytimes/android/external/fs2/StoreNetworkBeforeStaleTest.java @@ -1,10 +1,10 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.RecordState; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.StoreBuilder; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.RecordState; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; import org.junit.Before; import org.junit.Test; @@ -14,9 +14,9 @@ import org.mockito.MockitoAnnotations; import org.mockito.runners.MockitoJUnitRunner; +import io.reactivex.Maybe; +import io.reactivex.Single; import okio.BufferedSource; -import rx.Observable; -import rx.observers.AssertableSubscriber; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.never; @@ -26,8 +26,8 @@ @RunWith(MockitoJUnitRunner.class) public class StoreNetworkBeforeStaleTest { - final BarCode barCode = new BarCode("key", "value"); - final Exception sorry = new Exception("sorry"); + + Exception sorry = new Exception("sorry"); @Mock Fetcher fetcher; @Mock @@ -40,6 +40,8 @@ public class StoreNetworkBeforeStaleTest { BufferedSource disk1; @Mock BufferedSource disk2; + + private final BarCode barCode = new BarCode("key", "value"); private Store store; @Before @@ -56,13 +58,13 @@ public void setUp() { @Test public void networkBeforeDiskWhenStale() { when(fetcher.fetch(barCode)) - .thenReturn(Observable.error(new Exception())); + .thenReturn(Single.error(new Exception())); when(persister.read(barCode)) - .thenReturn(Observable.just(disk1)); //get should return from disk + .thenReturn(Maybe.just(disk1)); //get should return from disk when(persister.getRecordState(barCode)).thenReturn(RecordState.STALE); when(persister.write(barCode, network1)) - .thenReturn(Observable.just(true)); + .thenReturn(Single.just(true)); store.get(barCode).test().awaitTerminalEvent(); @@ -75,14 +77,14 @@ public void networkBeforeDiskWhenStale() { @Test public void noNetworkBeforeStaleWhenMissingRecord() { when(fetcher.fetch(barCode)) - .thenReturn(Observable.just(network1)); + .thenReturn(Single.just(network1)); when(persister.read(barCode)) - .thenReturn(Observable.empty(), Observable.just(disk1)); //first call should return + .thenReturn(Maybe.empty(), Maybe.just(disk1)); //first call should return // empty, second call after network should return the network value when(persister.getRecordState(barCode)).thenReturn(RecordState.MISSING); when(persister.write(barCode, network1)) - .thenReturn(Observable.just(true)); + .thenReturn(Single.just(true)); store.get(barCode).test().awaitTerminalEvent(); @@ -96,7 +98,7 @@ public void noNetworkBeforeStaleWhenMissingRecord() { @Test public void noNetworkBeforeStaleWhenFreshRecord() { when(persister.read(barCode)) - .thenReturn(Observable.just(disk1)); //get should return from disk + .thenReturn(Maybe.just(disk1)); //get should return from disk when(persister.getRecordState(barCode)).thenReturn(RecordState.FRESH); store.get(barCode).test().awaitTerminalEvent(); @@ -108,19 +110,19 @@ public void noNetworkBeforeStaleWhenFreshRecord() { @Test public void networkBeforeStaleNoNetworkResponse() { - Observable exception = Observable.error(sorry); + Single singleError = Single.error(sorry); + Maybe maybeError = Maybe.error(sorry); when(fetcher.fetch(barCode)) - .thenReturn(exception); + .thenReturn(singleError); when(persister.read(barCode)) - .thenReturn(exception, exception); //first call should return + .thenReturn(maybeError, maybeError); //first call should return // empty, second call after network should return the network value when(persister.getRecordState(barCode)).thenReturn(RecordState.MISSING); when(persister.write(barCode, network1)) - .thenReturn(Observable.just(true)); + .thenReturn(Single.just(true)); - AssertableSubscriber subscriber = store.get(barCode).test().awaitTerminalEvent(); - subscriber.assertError(sorry); + store.get(barCode).test().assertError(sorry); InOrder inOrder = inOrder(fetcher, persister); inOrder.verify(persister, times(1)).read(barCode); diff --git a/filesystem/src/test/java/com/nytimes/android/external/fs/StoreRefreshWhenStaleTest.java b/filesystem/src/test/java/com/nytimes/android/external/fs2/StoreRefreshWhenStaleTest.java similarity index 63% rename from filesystem/src/test/java/com/nytimes/android/external/fs/StoreRefreshWhenStaleTest.java rename to filesystem/src/test/java/com/nytimes/android/external/fs2/StoreRefreshWhenStaleTest.java index 57cb80bd..2f3fe9bc 100644 --- a/filesystem/src/test/java/com/nytimes/android/external/fs/StoreRefreshWhenStaleTest.java +++ b/filesystem/src/test/java/com/nytimes/android/external/fs2/StoreRefreshWhenStaleTest.java @@ -1,10 +1,10 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.RecordState; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.StoreBuilder; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.RecordState; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; import org.junit.Before; import org.junit.Test; @@ -13,10 +13,11 @@ import org.mockito.MockitoAnnotations; import org.mockito.runners.MockitoJUnitRunner; +import io.reactivex.Maybe; +import io.reactivex.Single; +import io.reactivex.observers.TestObserver; import okio.BufferedSource; -import rx.Observable; -import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -53,13 +54,13 @@ public void setUp() { @Test public void diskWasRefreshedWhenStaleRecord() { when(fetcher.fetch(barCode)) - .thenReturn(Observable.just(network1)); + .thenReturn(Single.just(network1)); when(persister.read(barCode)) - .thenReturn(Observable.just(disk1)); //get should return from disk + .thenReturn(Maybe.just(disk1)); //get should return from disk when(persister.getRecordState(barCode)).thenReturn(RecordState.STALE); when(persister.write(barCode, network1)) - .thenReturn(Observable.just(true)); + .thenReturn(Single.just(true)); store.get(barCode).test().awaitTerminalEvent(); verify(fetcher, times(1)).fetch(barCode); @@ -72,29 +73,31 @@ public void diskWasRefreshedWhenStaleRecord() { @Test public void diskWasNotRefreshedWhenFreshRecord() { when(fetcher.fetch(barCode)) - .thenReturn(Observable.just(network1)); + .thenReturn(Single.just(network1)); when(persister.read(barCode)) - .thenReturn(Observable.just(disk1)) //get should return from disk - .thenReturn(Observable.just(disk2)); //backfill should read from disk again + .thenReturn(Maybe.just(disk1)) //get should return from disk + .thenReturn(Maybe.just(disk2)); //backfill should read from disk again when(persister.getRecordState(barCode)).thenReturn(RecordState.FRESH); when(persister.write(barCode, network1)) - .thenReturn(Observable.just(true)); - - BufferedSource result = store.get(barCode) - .test() - .awaitTerminalEvent() - .getOnNextEvents() - .get(0); - assertThat(result).isEqualTo(disk1); + .thenReturn(Single.just(true)); + + TestObserver testObserver = store + .get(barCode) + .test(); + testObserver.awaitTerminalEvent(); + testObserver.assertNoErrors(); + testObserver.assertResult(disk1); verify(fetcher, times(0)).fetch(barCode); verify(persister, times(1)).getRecordState(barCode); store.clear(barCode); - result = store.get(barCode).test().awaitTerminalEvent().getOnNextEvents().get(0); - assertThat(result).isEqualTo(disk2); + testObserver = store + .get(barCode) + .test(); + testObserver.awaitTerminalEvent(); + testObserver.assertResult(disk2); verify(fetcher, times(0)).fetch(barCode); verify(persister, times(2)).getRecordState(barCode); - } } diff --git a/filesystem/src/test/java/com/nytimes/android/external/fs/UtilTest.java b/filesystem/src/test/java/com/nytimes/android/external/fs2/UtilTest.java similarity index 97% rename from filesystem/src/test/java/com/nytimes/android/external/fs/UtilTest.java rename to filesystem/src/test/java/com/nytimes/android/external/fs2/UtilTest.java index 75351581..6d8ce72e 100644 --- a/filesystem/src/test/java/com/nytimes/android/external/fs/UtilTest.java +++ b/filesystem/src/test/java/com/nytimes/android/external/fs2/UtilTest.java @@ -1,4 +1,4 @@ -package com.nytimes.android.external.fs; +package com.nytimes.android.external.fs2; import org.junit.Test; diff --git a/filesystem/src/test/java/com/nytimes/android/external/fs/filesystem/BreadthFirstFileTreeIteratorTest.java b/filesystem/src/test/java/com/nytimes/android/external/fs2/filesystem/BreadthFirstFileTreeIteratorTest.java similarity index 97% rename from filesystem/src/test/java/com/nytimes/android/external/fs/filesystem/BreadthFirstFileTreeIteratorTest.java rename to filesystem/src/test/java/com/nytimes/android/external/fs2/filesystem/BreadthFirstFileTreeIteratorTest.java index ea7e122a..b18d6e29 100644 --- a/filesystem/src/test/java/com/nytimes/android/external/fs/filesystem/BreadthFirstFileTreeIteratorTest.java +++ b/filesystem/src/test/java/com/nytimes/android/external/fs2/filesystem/BreadthFirstFileTreeIteratorTest.java @@ -1,4 +1,4 @@ -package com.nytimes.android.external.fs.filesystem; +package com.nytimes.android.external.fs2.filesystem; import org.junit.Before; import org.junit.Test; diff --git a/filesystem/src/test/java/com/nytimes/android/external/fs/impl/SimpleTest.java b/filesystem/src/test/java/com/nytimes/android/external/fs2/impl/SimpleTest.java similarity index 95% rename from filesystem/src/test/java/com/nytimes/android/external/fs/impl/SimpleTest.java rename to filesystem/src/test/java/com/nytimes/android/external/fs2/impl/SimpleTest.java index c2f86f5e..790ed595 100644 --- a/filesystem/src/test/java/com/nytimes/android/external/fs/impl/SimpleTest.java +++ b/filesystem/src/test/java/com/nytimes/android/external/fs2/impl/SimpleTest.java @@ -1,9 +1,9 @@ -package com.nytimes.android.external.fs.impl; +package com.nytimes.android.external.fs2.impl; -import com.nytimes.android.external.fs.filesystem.FileSystem; -import com.nytimes.android.external.fs.filesystem.FileSystemFactory; -import com.nytimes.android.external.store.base.RecordState; +import com.nytimes.android.external.fs2.filesystem.FileSystem; +import com.nytimes.android.external.fs2.filesystem.FileSystemFactory; +import com.nytimes.android.external.store2.base.RecordState; import org.junit.Before; import org.junit.Test; diff --git a/middleware-jackson/gradle.properties b/middleware-jackson/gradle.properties index f80d5ec9..a3ffb436 100644 --- a/middleware-jackson/gradle.properties +++ b/middleware-jackson/gradle.properties @@ -1,3 +1,3 @@ POM_NAME=com.nytimes.android -POM_ARTIFACT_ID=middleware-jackson +POM_ARTIFACT_ID=middleware-jackson2 POM_PACKAGING=aar diff --git a/middleware-jackson/src/main/java/com/nytimes/android/external/store/middleware/jackson/JacksonParserFactory.java b/middleware-jackson/src/main/java/com/nytimes/android/external/store2/middleware/jackson/JacksonParserFactory.java similarity index 97% rename from middleware-jackson/src/main/java/com/nytimes/android/external/store/middleware/jackson/JacksonParserFactory.java rename to middleware-jackson/src/main/java/com/nytimes/android/external/store2/middleware/jackson/JacksonParserFactory.java index 60da6bbe..950a5457 100644 --- a/middleware-jackson/src/main/java/com/nytimes/android/external/store/middleware/jackson/JacksonParserFactory.java +++ b/middleware-jackson/src/main/java/com/nytimes/android/external/store2/middleware/jackson/JacksonParserFactory.java @@ -1,9 +1,9 @@ -package com.nytimes.android.external.store.middleware.jackson; +package com.nytimes.android.external.store2.middleware.jackson; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.databind.ObjectMapper; import com.nytimes.android.external.cache.Preconditions; -import com.nytimes.android.external.store.base.Parser; +import com.nytimes.android.external.store2.base.Parser; import java.io.Reader; import java.lang.reflect.Type; diff --git a/middleware-jackson/src/main/java/com/nytimes/android/external/store/middleware/jackson/JacksonReaderParser.java b/middleware-jackson/src/main/java/com/nytimes/android/external/store2/middleware/jackson/JacksonReaderParser.java similarity index 73% rename from middleware-jackson/src/main/java/com/nytimes/android/external/store/middleware/jackson/JacksonReaderParser.java rename to middleware-jackson/src/main/java/com/nytimes/android/external/store2/middleware/jackson/JacksonReaderParser.java index a43f476f..14af5a58 100644 --- a/middleware-jackson/src/main/java/com/nytimes/android/external/store/middleware/jackson/JacksonReaderParser.java +++ b/middleware-jackson/src/main/java/com/nytimes/android/external/store2/middleware/jackson/JacksonReaderParser.java @@ -1,10 +1,11 @@ -package com.nytimes.android.external.store.middleware.jackson; +package com.nytimes.android.external.store2.middleware.jackson; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; -import com.nytimes.android.external.store.base.Parser; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.util.ParserException; import java.io.IOException; import java.io.Reader; @@ -13,6 +14,8 @@ import javax.annotation.Nonnull; import javax.inject.Inject; +import io.reactivex.annotations.NonNull; + public class JacksonReaderParser implements Parser { private final ObjectMapper objectMapper; @@ -30,11 +33,11 @@ public JacksonReaderParser(@Nonnull ObjectMapper objectMapper, @Nonnull Type typ } @Override - public Parsed call(@Nonnull Reader reader) { + public Parsed apply(@NonNull Reader reader) throws ParserException { try { return objectMapper.readValue(reader, parsedType); } catch (IOException e) { - return null; + throw new ParserException(e.getMessage(), e); } } } diff --git a/middleware-jackson/src/main/java/com/nytimes/android/external/store/middleware/jackson/JacksonSourceParser.java b/middleware-jackson/src/main/java/com/nytimes/android/external/store2/middleware/jackson/JacksonSourceParser.java similarity index 72% rename from middleware-jackson/src/main/java/com/nytimes/android/external/store/middleware/jackson/JacksonSourceParser.java rename to middleware-jackson/src/main/java/com/nytimes/android/external/store2/middleware/jackson/JacksonSourceParser.java index 262fb67a..3d63aa1b 100644 --- a/middleware-jackson/src/main/java/com/nytimes/android/external/store/middleware/jackson/JacksonSourceParser.java +++ b/middleware-jackson/src/main/java/com/nytimes/android/external/store2/middleware/jackson/JacksonSourceParser.java @@ -1,18 +1,19 @@ -package com.nytimes.android.external.store.middleware.jackson; +package com.nytimes.android.external.store2.middleware.jackson; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; -import com.nytimes.android.external.store.base.Parser; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.util.ParserException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Type; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import javax.inject.Inject; +import io.reactivex.annotations.NonNull; import okio.BufferedSource; public class JacksonSourceParser implements Parser { @@ -32,14 +33,13 @@ public JacksonSourceParser(@Nonnull ObjectMapper objectMapper, @Nonnull Type typ } @Override - @Nullable - @SuppressWarnings("PMD.EmptyCatchBlock") - public Parsed call(@Nonnull BufferedSource source) { - InputStream inputStream = source.inputStream(); + @SuppressWarnings({"PMD.EmptyCatchBlock"}) + public Parsed apply(@NonNull BufferedSource bufferedSource) throws ParserException { + InputStream inputStream = bufferedSource.inputStream(); try { return objectMapper.readValue(inputStream, parsedType); } catch (IOException e) { - return null; + throw new ParserException(e.getMessage(), e); } finally { try { if (inputStream != null) { diff --git a/middleware-jackson/src/main/java/com/nytimes/android/external/store/middleware/jackson/JacksonStringParser.java b/middleware-jackson/src/main/java/com/nytimes/android/external/store2/middleware/jackson/JacksonStringParser.java similarity index 69% rename from middleware-jackson/src/main/java/com/nytimes/android/external/store/middleware/jackson/JacksonStringParser.java rename to middleware-jackson/src/main/java/com/nytimes/android/external/store2/middleware/jackson/JacksonStringParser.java index 2f1fa6a2..9531893c 100644 --- a/middleware-jackson/src/main/java/com/nytimes/android/external/store/middleware/jackson/JacksonStringParser.java +++ b/middleware-jackson/src/main/java/com/nytimes/android/external/store2/middleware/jackson/JacksonStringParser.java @@ -1,17 +1,19 @@ -package com.nytimes.android.external.store.middleware.jackson; +package com.nytimes.android.external.store2.middleware.jackson; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; -import com.nytimes.android.external.store.base.Parser; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.util.ParserException; import java.io.IOException; import java.lang.reflect.Type; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import javax.inject.Inject; +import io.reactivex.annotations.NonNull; + public class JacksonStringParser implements Parser { private final ObjectMapper objectMapper; @@ -29,12 +31,11 @@ public JacksonStringParser(@Nonnull ObjectMapper objectMapper, @Nonnull Type typ } @Override - @Nullable - public Parsed call(@Nonnull String source) { + public Parsed apply(@NonNull String s) throws ParserException { try { - return objectMapper.readValue(source, parsedType); + return objectMapper.readValue(s, parsedType); } catch (IOException e) { - return null; + throw new ParserException(e.getMessage(), e); } } } diff --git a/middleware-jackson/src/test/java/com/nytimes/android/external/store/middleware/jackson/JacksonReaderParserStoreTest.java b/middleware-jackson/src/test/java/com/nytimes/android/external/store2/middleware/jackson/JacksonReaderParserStoreTest.java similarity index 79% rename from middleware-jackson/src/test/java/com/nytimes/android/external/store/middleware/jackson/JacksonReaderParserStoreTest.java rename to middleware-jackson/src/test/java/com/nytimes/android/external/store2/middleware/jackson/JacksonReaderParserStoreTest.java index cf0ee2a4..83b8ccf1 100644 --- a/middleware-jackson/src/test/java/com/nytimes/android/external/store/middleware/jackson/JacksonReaderParserStoreTest.java +++ b/middleware-jackson/src/test/java/com/nytimes/android/external/store2/middleware/jackson/JacksonReaderParserStoreTest.java @@ -1,14 +1,14 @@ -package com.nytimes.android.external.store.middleware.jackson; +package com.nytimes.android.external.store2.middleware.jackson; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.databind.ObjectMapper; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.Parser; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.StoreBuilder; -import com.nytimes.android.external.store.middleware.jackson.data.Foo; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; +import com.nytimes.android.external.store2.middleware.jackson.data.Foo; import org.junit.Before; import org.junit.Rule; @@ -20,7 +20,9 @@ import java.io.Reader; import java.io.StringReader; -import rx.Observable; + +import io.reactivex.Maybe; +import io.reactivex.Single; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -47,14 +49,14 @@ public void setUp() throws Exception { Reader source = new StringReader(sourceString); when(fetcher.fetch(barCode)) - .thenReturn(Observable.just(source)); + .thenReturn(Single.just(source)); when(persister.read(barCode)) - .thenReturn(Observable.empty()) - .thenReturn(Observable.just(source)); + .thenReturn(Maybe.empty()) + .thenReturn(Maybe.just(source)); when(persister.write(barCode, source)) - .thenReturn(Observable.just(true)); + .thenReturn(Single.just(true)); } @Test @@ -66,7 +68,7 @@ public void testDefaultJacksonReaderParser() { .parser(parser) .open(); - Foo result = store.get(barCode).toBlocking().first(); + Foo result = store.get(barCode).blockingGet(); validateFoo(result); @@ -85,7 +87,7 @@ public void testCustomJsonFactoryReaderParser() { .parser(parser) .open(); - Foo result = store.get(barCode).toBlocking().first(); + Foo result = store.get(barCode).blockingGet(); validateFoo(result); diff --git a/middleware-jackson/src/test/java/com/nytimes/android/external/store/middleware/jackson/JacksonSourceParserStoreTest.java b/middleware-jackson/src/test/java/com/nytimes/android/external/store2/middleware/jackson/JacksonSourceParserStoreTest.java similarity index 80% rename from middleware-jackson/src/test/java/com/nytimes/android/external/store/middleware/jackson/JacksonSourceParserStoreTest.java rename to middleware-jackson/src/test/java/com/nytimes/android/external/store2/middleware/jackson/JacksonSourceParserStoreTest.java index f19c46d3..1a4b23bc 100644 --- a/middleware-jackson/src/test/java/com/nytimes/android/external/store/middleware/jackson/JacksonSourceParserStoreTest.java +++ b/middleware-jackson/src/test/java/com/nytimes/android/external/store2/middleware/jackson/JacksonSourceParserStoreTest.java @@ -1,14 +1,14 @@ -package com.nytimes.android.external.store.middleware.jackson; +package com.nytimes.android.external.store2.middleware.jackson; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.databind.ObjectMapper; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.Parser; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.StoreBuilder; -import com.nytimes.android.external.store.middleware.jackson.data.Foo; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; +import com.nytimes.android.external.store2.middleware.jackson.data.Foo; import org.junit.Before; import org.junit.Rule; @@ -20,9 +20,10 @@ import java.io.ByteArrayInputStream; import java.nio.charset.Charset; +import io.reactivex.Maybe; +import io.reactivex.Single; import okio.BufferedSource; import okio.Okio; -import rx.Observable; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -55,14 +56,14 @@ public void setUp() throws Exception { assertNotNull(bufferedSource); when(fetcher.fetch(barCode)) - .thenReturn(Observable.just(bufferedSource)); + .thenReturn(Single.just(bufferedSource)); when(persister.read(barCode)) - .thenReturn(Observable.empty()) - .thenReturn(Observable.just(bufferedSource)); + .thenReturn(Maybe.empty()) + .thenReturn(Maybe.just(bufferedSource)); when(persister.write(barCode, bufferedSource)) - .thenReturn(Observable.just(true)); + .thenReturn(Single.just(true)); } @Test @@ -74,7 +75,7 @@ public void testDefaultJacksonSourceParser() { .parser(parser) .open(); - Foo result = store.get(barCode).toBlocking().first(); + Foo result = store.get(barCode).blockingGet(); validateFoo(result); @@ -93,7 +94,7 @@ public void testCustomJsonFactorySourceParser() { .parser(parser) .open(); - Foo result = store.get(barCode).toBlocking().first(); + Foo result = store.get(barCode).blockingGet(); validateFoo(result); diff --git a/middleware-jackson/src/test/java/com/nytimes/android/external/store/middleware/jackson/JacksonStringParserStoreTest.java b/middleware-jackson/src/test/java/com/nytimes/android/external/store2/middleware/jackson/JacksonStringParserStoreTest.java similarity index 78% rename from middleware-jackson/src/test/java/com/nytimes/android/external/store/middleware/jackson/JacksonStringParserStoreTest.java rename to middleware-jackson/src/test/java/com/nytimes/android/external/store2/middleware/jackson/JacksonStringParserStoreTest.java index 382cae87..1e892371 100644 --- a/middleware-jackson/src/test/java/com/nytimes/android/external/store/middleware/jackson/JacksonStringParserStoreTest.java +++ b/middleware-jackson/src/test/java/com/nytimes/android/external/store2/middleware/jackson/JacksonStringParserStoreTest.java @@ -1,14 +1,14 @@ -package com.nytimes.android.external.store.middleware.jackson; +package com.nytimes.android.external.store2.middleware.jackson; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.databind.ObjectMapper; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.Parser; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.StoreBuilder; -import com.nytimes.android.external.store.middleware.jackson.data.Foo; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; +import com.nytimes.android.external.store2.middleware.jackson.data.Foo; import org.junit.Before; import org.junit.Rule; @@ -17,7 +17,9 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import rx.Observable; + +import io.reactivex.Maybe; +import io.reactivex.Single; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -43,14 +45,14 @@ public void setUp() throws Exception { MockitoAnnotations.initMocks(this); when(fetcher.fetch(barCode)) - .thenReturn(Observable.just(source)); + .thenReturn(Single.just(source)); when(persister.read(barCode)) - .thenReturn(Observable.empty()) - .thenReturn(Observable.just(source)); + .thenReturn(Maybe.empty()) + .thenReturn(Maybe.just(source)); when(persister.write(barCode, source)) - .thenReturn(Observable.just(true)); + .thenReturn(Single.just(true)); } @Test @@ -61,7 +63,7 @@ public void testDefaultJacksonStringParser() { .parser(JacksonParserFactory.createStringParser(Foo.class)) .open(); - Foo result = store.get(barCode).toBlocking().first(); + Foo result = store.get(barCode).blockingGet(); validateFoo(result); @@ -80,7 +82,7 @@ public void testCustomJsonFactoryStringParser() { .parser(parser) .open(); - Foo result = store.get(barCode).toBlocking().first(); + Foo result = store.get(barCode).blockingGet(); validateFoo(result); diff --git a/middleware-jackson/src/test/java/com/nytimes/android/external/store/middleware/jackson/data/Bar.java b/middleware-jackson/src/test/java/com/nytimes/android/external/store2/middleware/jackson/data/Bar.java similarity index 67% rename from middleware-jackson/src/test/java/com/nytimes/android/external/store/middleware/jackson/data/Bar.java rename to middleware-jackson/src/test/java/com/nytimes/android/external/store2/middleware/jackson/data/Bar.java index 766161da..3bc0f74e 100644 --- a/middleware-jackson/src/test/java/com/nytimes/android/external/store/middleware/jackson/data/Bar.java +++ b/middleware-jackson/src/test/java/com/nytimes/android/external/store2/middleware/jackson/data/Bar.java @@ -1,4 +1,4 @@ -package com.nytimes.android.external.store.middleware.jackson.data; +package com.nytimes.android.external.store2.middleware.jackson.data; public class Bar { public String string; diff --git a/middleware-jackson/src/test/java/com/nytimes/android/external/store/middleware/jackson/data/Foo.java b/middleware-jackson/src/test/java/com/nytimes/android/external/store2/middleware/jackson/data/Foo.java similarity index 81% rename from middleware-jackson/src/test/java/com/nytimes/android/external/store/middleware/jackson/data/Foo.java rename to middleware-jackson/src/test/java/com/nytimes/android/external/store2/middleware/jackson/data/Foo.java index 5bcb180d..fac48d7e 100644 --- a/middleware-jackson/src/test/java/com/nytimes/android/external/store/middleware/jackson/data/Foo.java +++ b/middleware-jackson/src/test/java/com/nytimes/android/external/store2/middleware/jackson/data/Foo.java @@ -1,4 +1,4 @@ -package com.nytimes.android.external.store.middleware.jackson.data; +package com.nytimes.android.external.store2.middleware.jackson.data; import java.util.List; diff --git a/middleware-moshi/gradle.properties b/middleware-moshi/gradle.properties index 72eed9ac..4c907633 100644 --- a/middleware-moshi/gradle.properties +++ b/middleware-moshi/gradle.properties @@ -1,3 +1,3 @@ POM_NAME=com.nytimes.android -POM_ARTIFACT_ID=middleware-moshi +POM_ARTIFACT_ID=middleware-moshi2 POM_PACKAGING=aar diff --git a/middleware-moshi/src/main/java/com/nytimes/android/external/store/middleware/moshi/MoshiParserFactory.java b/middleware-moshi/src/main/java/com/nytimes/android/external/store2/middleware/moshi/MoshiParserFactory.java similarity index 94% rename from middleware-moshi/src/main/java/com/nytimes/android/external/store/middleware/moshi/MoshiParserFactory.java rename to middleware-moshi/src/main/java/com/nytimes/android/external/store2/middleware/moshi/MoshiParserFactory.java index fe3d6f85..21d4aa03 100644 --- a/middleware-moshi/src/main/java/com/nytimes/android/external/store/middleware/moshi/MoshiParserFactory.java +++ b/middleware-moshi/src/main/java/com/nytimes/android/external/store2/middleware/moshi/MoshiParserFactory.java @@ -1,7 +1,7 @@ -package com.nytimes.android.external.store.middleware.moshi; +package com.nytimes.android.external.store2.middleware.moshi; import com.nytimes.android.external.cache.Preconditions; -import com.nytimes.android.external.store.base.Parser; +import com.nytimes.android.external.store2.base.Parser; import com.squareup.moshi.Moshi; import java.lang.reflect.Type; diff --git a/middleware-moshi/src/main/java/com/nytimes/android/external/store/middleware/moshi/MoshiSourceParser.java b/middleware-moshi/src/main/java/com/nytimes/android/external/store2/middleware/moshi/MoshiSourceParser.java similarity index 57% rename from middleware-moshi/src/main/java/com/nytimes/android/external/store/middleware/moshi/MoshiSourceParser.java rename to middleware-moshi/src/main/java/com/nytimes/android/external/store2/middleware/moshi/MoshiSourceParser.java index 2104bd7b..a5c7ef0d 100644 --- a/middleware-moshi/src/main/java/com/nytimes/android/external/store/middleware/moshi/MoshiSourceParser.java +++ b/middleware-moshi/src/main/java/com/nytimes/android/external/store2/middleware/moshi/MoshiSourceParser.java @@ -1,6 +1,7 @@ -package com.nytimes.android.external.store.middleware.moshi; +package com.nytimes.android.external.store2.middleware.moshi; -import com.nytimes.android.external.store.base.Parser; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.util.ParserException; import com.squareup.moshi.JsonAdapter; import com.squareup.moshi.Moshi; @@ -8,9 +9,9 @@ import java.lang.reflect.Type; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import javax.inject.Inject; +import io.reactivex.annotations.NonNull; import okio.BufferedSource; public class MoshiSourceParser implements Parser { @@ -23,12 +24,11 @@ public MoshiSourceParser(@Nonnull Moshi moshi, @Nonnull Type type) { } @Override - @Nullable - public Parsed call(BufferedSource source) { + public Parsed apply(@NonNull BufferedSource bufferedSource) throws ParserException { try { - return jsonAdapter.fromJson(source); + return jsonAdapter.fromJson(bufferedSource); } catch (IOException e) { - return null; + throw new ParserException(e.getMessage(), e); } } } diff --git a/middleware-moshi/src/main/java/com/nytimes/android/external/store/middleware/moshi/MoshiStringParser.java b/middleware-moshi/src/main/java/com/nytimes/android/external/store2/middleware/moshi/MoshiStringParser.java similarity index 57% rename from middleware-moshi/src/main/java/com/nytimes/android/external/store/middleware/moshi/MoshiStringParser.java rename to middleware-moshi/src/main/java/com/nytimes/android/external/store2/middleware/moshi/MoshiStringParser.java index 23201084..9dc76f27 100644 --- a/middleware-moshi/src/main/java/com/nytimes/android/external/store/middleware/moshi/MoshiStringParser.java +++ b/middleware-moshi/src/main/java/com/nytimes/android/external/store2/middleware/moshi/MoshiStringParser.java @@ -1,6 +1,7 @@ -package com.nytimes.android.external.store.middleware.moshi; +package com.nytimes.android.external.store2.middleware.moshi; -import com.nytimes.android.external.store.base.Parser; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.util.ParserException; import com.squareup.moshi.JsonAdapter; import com.squareup.moshi.Moshi; @@ -8,9 +9,10 @@ import java.lang.reflect.Type; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import javax.inject.Inject; +import io.reactivex.annotations.NonNull; + public class MoshiStringParser implements Parser { private final JsonAdapter jsonAdapter; @@ -20,13 +22,13 @@ public MoshiStringParser(@Nonnull Moshi moshi, @Nonnull Type type) { jsonAdapter = moshi.adapter(type); } + @Override - @Nullable - public Parsed call(@Nonnull String source) { + public Parsed apply(@NonNull String s) throws ParserException { try { - return jsonAdapter.fromJson(source); + return jsonAdapter.fromJson(s); } catch (IOException e) { - return null; + throw new ParserException(e.getMessage(), e); } } } diff --git a/middleware-moshi/src/test/java/com/nytimes/android/external/store/middleware/moshi/MoshiSourceParserTest.java b/middleware-moshi/src/test/java/com/nytimes/android/external/store2/middleware/moshi/MoshiSourceParserTest.java similarity index 75% rename from middleware-moshi/src/test/java/com/nytimes/android/external/store/middleware/moshi/MoshiSourceParserTest.java rename to middleware-moshi/src/test/java/com/nytimes/android/external/store2/middleware/moshi/MoshiSourceParserTest.java index 013a5c17..07b0148a 100644 --- a/middleware-moshi/src/test/java/com/nytimes/android/external/store/middleware/moshi/MoshiSourceParserTest.java +++ b/middleware-moshi/src/test/java/com/nytimes/android/external/store2/middleware/moshi/MoshiSourceParserTest.java @@ -1,12 +1,12 @@ -package com.nytimes.android.external.store.middleware.moshi; +package com.nytimes.android.external.store2.middleware.moshi; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.Parser; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.ParsingStoreBuilder; -import com.nytimes.android.external.store.middleware.moshi.data.Foo; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.ParsingStoreBuilder; +import com.nytimes.android.external.store2.middleware.moshi.data.Foo; import org.junit.Before; import org.junit.Rule; @@ -18,9 +18,10 @@ import java.io.ByteArrayInputStream; import java.nio.charset.Charset; +import io.reactivex.Maybe; +import io.reactivex.Single; import okio.BufferedSource; import okio.Okio; -import rx.Observable; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -53,14 +54,14 @@ public void setUp() throws Exception { assertNotNull(bufferedSource); when(fetcher.fetch(barCode)) - .thenReturn(Observable.just(bufferedSource)); + .thenReturn(Single.just(bufferedSource)); when(persister.read(barCode)) - .thenReturn(Observable.empty()) - .thenReturn(Observable.just(bufferedSource)); + .thenReturn(Maybe.empty()) + .thenReturn(Maybe.just(bufferedSource)); when(persister.write(barCode, bufferedSource)) - .thenReturn(Observable.just(true)); + .thenReturn(Single.just(true)); } @Test @@ -74,7 +75,7 @@ public void testSourceParser() throws Exception { .parser(parser) .open(); - Foo result = store.get(barCode).toBlocking().first(); + Foo result = store.get(barCode).blockingGet(); assertEquals(result.number, 123); assertEquals(result.string, "abc"); diff --git a/middleware-moshi/src/test/java/com/nytimes/android/external/store/middleware/moshi/MoshiStringParserStoreTest.java b/middleware-moshi/src/test/java/com/nytimes/android/external/store2/middleware/moshi/MoshiStringParserStoreTest.java similarity index 73% rename from middleware-moshi/src/test/java/com/nytimes/android/external/store/middleware/moshi/MoshiStringParserStoreTest.java rename to middleware-moshi/src/test/java/com/nytimes/android/external/store2/middleware/moshi/MoshiStringParserStoreTest.java index 278d7fc0..4cf9d627 100644 --- a/middleware-moshi/src/test/java/com/nytimes/android/external/store/middleware/moshi/MoshiStringParserStoreTest.java +++ b/middleware-moshi/src/test/java/com/nytimes/android/external/store2/middleware/moshi/MoshiStringParserStoreTest.java @@ -1,11 +1,11 @@ -package com.nytimes.android.external.store.middleware.moshi; - -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.ParsingStoreBuilder; -import com.nytimes.android.external.store.middleware.moshi.data.Foo; +package com.nytimes.android.external.store2.middleware.moshi; + +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.ParsingStoreBuilder; +import com.nytimes.android.external.store2.middleware.moshi.data.Foo; import com.squareup.moshi.Moshi; import org.junit.Before; @@ -15,7 +15,9 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import rx.Observable; + +import io.reactivex.Maybe; +import io.reactivex.Single; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.times; @@ -40,14 +42,14 @@ public void setUp() throws Exception { MockitoAnnotations.initMocks(this); when(fetcher.fetch(barCode)) - .thenReturn(Observable.just(source)); + .thenReturn(Single.just(source)); when(persister.read(barCode)) - .thenReturn(Observable.empty()) - .thenReturn(Observable.just(source)); + .thenReturn(Maybe.empty()) + .thenReturn(Maybe.just(source)); when(persister.write(barCode, source)) - .thenReturn(Observable.just(true)); + .thenReturn(Single.just(true)); } @Test @@ -58,7 +60,7 @@ public void testMoshiString() { .parser(MoshiParserFactory.createStringParser(Foo.class)) .open(); - Foo result = store.get(barCode).toBlocking().first(); + Foo result = store.get(barCode).blockingGet(); assertEquals(result.number, 123); assertEquals(result.string, "abc"); diff --git a/middleware-moshi/src/test/java/com/nytimes/android/external/store/middleware/moshi/data/Bar.java b/middleware-moshi/src/test/java/com/nytimes/android/external/store2/middleware/moshi/data/Bar.java similarity index 63% rename from middleware-moshi/src/test/java/com/nytimes/android/external/store/middleware/moshi/data/Bar.java rename to middleware-moshi/src/test/java/com/nytimes/android/external/store2/middleware/moshi/data/Bar.java index 692271c8..b39eb19c 100644 --- a/middleware-moshi/src/test/java/com/nytimes/android/external/store/middleware/moshi/data/Bar.java +++ b/middleware-moshi/src/test/java/com/nytimes/android/external/store2/middleware/moshi/data/Bar.java @@ -1,4 +1,4 @@ -package com.nytimes.android.external.store.middleware.moshi.data; +package com.nytimes.android.external.store2.middleware.moshi.data; public class Bar { public String string; diff --git a/middleware-moshi/src/test/java/com/nytimes/android/external/store/middleware/moshi/data/Foo.java b/middleware-moshi/src/test/java/com/nytimes/android/external/store2/middleware/moshi/data/Foo.java similarity index 80% rename from middleware-moshi/src/test/java/com/nytimes/android/external/store/middleware/moshi/data/Foo.java rename to middleware-moshi/src/test/java/com/nytimes/android/external/store2/middleware/moshi/data/Foo.java index 19abfaf9..a73fd1e1 100644 --- a/middleware-moshi/src/test/java/com/nytimes/android/external/store/middleware/moshi/data/Foo.java +++ b/middleware-moshi/src/test/java/com/nytimes/android/external/store2/middleware/moshi/data/Foo.java @@ -1,4 +1,4 @@ -package com.nytimes.android.external.store.middleware.moshi.data; +package com.nytimes.android.external.store2.middleware.moshi.data; import java.util.List; diff --git a/middleware/gradle.properties b/middleware/gradle.properties index 62f4368e..226dc101 100644 --- a/middleware/gradle.properties +++ b/middleware/gradle.properties @@ -1,3 +1,3 @@ POM_NAME=com.nytimes.android -POM_ARTIFACT_ID=middleware +POM_ARTIFACT_ID=middleware2 POM_PACKAGING=aar diff --git a/middleware/src/main/java/com/nytimes/android/external/store/middleware/GsonParserFactory.java b/middleware/src/main/java/com/nytimes/android/external/store2/middleware/GsonParserFactory.java similarity index 95% rename from middleware/src/main/java/com/nytimes/android/external/store/middleware/GsonParserFactory.java rename to middleware/src/main/java/com/nytimes/android/external/store2/middleware/GsonParserFactory.java index c42441ec..267fd5b9 100644 --- a/middleware/src/main/java/com/nytimes/android/external/store/middleware/GsonParserFactory.java +++ b/middleware/src/main/java/com/nytimes/android/external/store2/middleware/GsonParserFactory.java @@ -1,8 +1,8 @@ -package com.nytimes.android.external.store.middleware; +package com.nytimes.android.external.store2.middleware; import com.google.gson.Gson; -import com.nytimes.android.external.store.base.Parser; +import com.nytimes.android.external.store2.base.Parser; import java.io.Reader; import java.lang.reflect.Type; diff --git a/middleware/src/main/java/com/nytimes/android/external/store/middleware/GsonReaderParser.java b/middleware/src/main/java/com/nytimes/android/external/store2/middleware/GsonReaderParser.java similarity index 67% rename from middleware/src/main/java/com/nytimes/android/external/store/middleware/GsonReaderParser.java rename to middleware/src/main/java/com/nytimes/android/external/store2/middleware/GsonReaderParser.java index 22aad937..40c5a636 100644 --- a/middleware/src/main/java/com/nytimes/android/external/store/middleware/GsonReaderParser.java +++ b/middleware/src/main/java/com/nytimes/android/external/store2/middleware/GsonReaderParser.java @@ -1,14 +1,16 @@ -package com.nytimes.android.external.store.middleware; +package com.nytimes.android.external.store2.middleware; import com.google.gson.Gson; -import com.nytimes.android.external.store.base.Parser; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.util.ParserException; import java.io.Reader; import java.lang.reflect.Type; -import javax.annotation.Nonnull; import javax.inject.Inject; +import io.reactivex.annotations.NonNull; + import static com.nytimes.android.external.cache.Preconditions.checkNotNull; public class GsonReaderParser implements Parser { @@ -25,7 +27,7 @@ public GsonReaderParser(Gson gson, Type type) { } @Override - public Parsed call(@Nonnull Reader reader) { + public Parsed apply(@NonNull Reader reader) throws ParserException { return gson.fromJson(reader, type); } } diff --git a/middleware/src/main/java/com/nytimes/android/external/store/middleware/GsonSourceParser.java b/middleware/src/main/java/com/nytimes/android/external/store2/middleware/GsonSourceParser.java similarity index 69% rename from middleware/src/main/java/com/nytimes/android/external/store/middleware/GsonSourceParser.java rename to middleware/src/main/java/com/nytimes/android/external/store2/middleware/GsonSourceParser.java index bfb1d79e..ac7ab225 100644 --- a/middleware/src/main/java/com/nytimes/android/external/store/middleware/GsonSourceParser.java +++ b/middleware/src/main/java/com/nytimes/android/external/store2/middleware/GsonSourceParser.java @@ -1,17 +1,18 @@ -package com.nytimes.android.external.store.middleware; +package com.nytimes.android.external.store2.middleware; import com.google.gson.Gson; -import com.nytimes.android.external.store.base.Parser; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.util.ParserException; import java.io.IOException; import java.io.InputStreamReader; import java.lang.reflect.Type; import java.nio.charset.Charset; -import javax.annotation.Nonnull; import javax.inject.Inject; +import io.reactivex.annotations.NonNull; import okio.BufferedSource; import static com.nytimes.android.external.cache.Preconditions.checkNotNull; @@ -42,11 +43,11 @@ public GsonSourceParser(Gson gson, Type type) { } @Override - public Parsed call(@Nonnull BufferedSource source) { - try (InputStreamReader reader = new InputStreamReader(source.inputStream(), Charset.forName("UTF-8"))) { + public Parsed apply(@NonNull BufferedSource bufferedSource) throws ParserException { + try (InputStreamReader reader = new InputStreamReader(bufferedSource.inputStream(), Charset.forName("UTF-8"))) { return gson.fromJson(reader, type); } catch (IOException e) { - throw new RuntimeException(e); + throw new ParserException(e.getMessage(), e); } } } diff --git a/middleware/src/main/java/com/nytimes/android/external/store/middleware/GsonStringParser.java b/middleware/src/main/java/com/nytimes/android/external/store2/middleware/GsonStringParser.java similarity index 63% rename from middleware/src/main/java/com/nytimes/android/external/store/middleware/GsonStringParser.java rename to middleware/src/main/java/com/nytimes/android/external/store2/middleware/GsonStringParser.java index 311ae4f1..0dcf7474 100644 --- a/middleware/src/main/java/com/nytimes/android/external/store/middleware/GsonStringParser.java +++ b/middleware/src/main/java/com/nytimes/android/external/store2/middleware/GsonStringParser.java @@ -1,11 +1,15 @@ -package com.nytimes.android.external.store.middleware; +package com.nytimes.android.external.store2.middleware; import com.google.gson.Gson; -import com.nytimes.android.external.store.base.Parser; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.util.ParserException; + import java.lang.reflect.Type; import javax.inject.Inject; +import io.reactivex.annotations.NonNull; + import static com.nytimes.android.external.cache.Preconditions.checkNotNull; public class GsonStringParser implements Parser { @@ -22,7 +26,7 @@ public GsonStringParser(Gson gson, Type parsedClass) { } @Override - public Parsed call(String source) { - return gson.fromJson(source, type); + public Parsed apply(@NonNull String s) throws ParserException { + return gson.fromJson(s, type); } } diff --git a/middleware/src/test/java/com/nytimes/android/external/store/GenericParserStoreTest.java b/middleware/src/test/java/com/nytimes/android/external/store2/GenericParserStoreTest.java similarity index 68% rename from middleware/src/test/java/com/nytimes/android/external/store/GenericParserStoreTest.java rename to middleware/src/test/java/com/nytimes/android/external/store2/GenericParserStoreTest.java index 783c6b62..1c702848 100644 --- a/middleware/src/test/java/com/nytimes/android/external/store/GenericParserStoreTest.java +++ b/middleware/src/test/java/com/nytimes/android/external/store2/GenericParserStoreTest.java @@ -1,13 +1,13 @@ -package com.nytimes.android.external.store; +package com.nytimes.android.external.store2; import com.google.gson.Gson; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.Parser; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.StoreBuilder; -import com.nytimes.android.external.store.middleware.GsonParserFactory; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; +import com.nytimes.android.external.store2.middleware.GsonParserFactory; import org.junit.Test; import org.mockito.Mock; @@ -15,9 +15,10 @@ import java.io.ByteArrayInputStream; +import io.reactivex.Maybe; +import io.reactivex.Single; import okio.BufferedSource; import okio.Okio; -import rx.Observable; import static com.google.common.base.Charsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; @@ -56,20 +57,20 @@ public void testSimple() { BufferedSource source = source(sourceData); - Observable value = Observable.just(source); + Single value = Single.just(source); when(fetcher.fetch(barCode)) .thenReturn(value); when(persister.read(barCode)) - .thenReturn(Observable.empty()) - .thenReturn(value); + .thenReturn(Maybe.empty()) + .thenReturn(value.toMaybe()); when(persister.write(barCode, source)) - .thenReturn(Observable.just(true)); + .thenReturn(Single.just(true)); - Foo result = simpleStore.get(barCode).toBlocking().first(); + Foo result = simpleStore.get(barCode).blockingGet(); assertThat(result.bar).isEqualTo(KEY); - result = simpleStore.get(barCode).toBlocking().first(); + result = simpleStore.get(barCode).blockingGet(); assertThat(result.bar).isEqualTo(KEY); verify(fetcher, times(1)).fetch(barCode); } diff --git a/middleware/src/test/java/com/nytimes/android/external/store/GsonParserFactoryTest.java b/middleware/src/test/java/com/nytimes/android/external/store2/GsonParserFactoryTest.java similarity index 94% rename from middleware/src/test/java/com/nytimes/android/external/store/GsonParserFactoryTest.java rename to middleware/src/test/java/com/nytimes/android/external/store2/GsonParserFactoryTest.java index fedd0cea..a8677390 100644 --- a/middleware/src/test/java/com/nytimes/android/external/store/GsonParserFactoryTest.java +++ b/middleware/src/test/java/com/nytimes/android/external/store2/GsonParserFactoryTest.java @@ -1,7 +1,7 @@ -package com.nytimes.android.external.store; +package com.nytimes.android.external.store2; import com.google.gson.Gson; -import com.nytimes.android.external.store.middleware.GsonParserFactory; +import com.nytimes.android.external.store2.middleware.GsonParserFactory; import org.junit.Before; import org.junit.Rule; diff --git a/middleware/src/test/java/com/nytimes/android/external/store/GsonSourceListParserTest.java b/middleware/src/test/java/com/nytimes/android/external/store2/GsonSourceListParserTest.java similarity index 73% rename from middleware/src/test/java/com/nytimes/android/external/store/GsonSourceListParserTest.java rename to middleware/src/test/java/com/nytimes/android/external/store2/GsonSourceListParserTest.java index 637447d5..5a26bb8b 100644 --- a/middleware/src/test/java/com/nytimes/android/external/store/GsonSourceListParserTest.java +++ b/middleware/src/test/java/com/nytimes/android/external/store2/GsonSourceListParserTest.java @@ -1,14 +1,14 @@ -package com.nytimes.android.external.store; +package com.nytimes.android.external.store2; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.Parser; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.StoreBuilder; -import com.nytimes.android.external.store.middleware.GsonParserFactory; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; +import com.nytimes.android.external.store2.middleware.GsonParserFactory; import org.junit.Test; import org.mockito.Mock; @@ -18,9 +18,10 @@ import java.util.Arrays; import java.util.List; +import io.reactivex.Maybe; +import io.reactivex.Single; import okio.BufferedSource; import okio.Okio; -import rx.Observable; import static com.google.common.base.Charsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; @@ -65,18 +66,18 @@ public void testSimple() { BufferedSource source = source(sourceData); - Observable value = Observable.just(source); + Single value = Single.just(source); when(fetcher.fetch(barCode)) .thenReturn(value); when(persister.read(barCode)) - .thenReturn(Observable.empty()) - .thenReturn(value); + .thenReturn(Maybe.empty()) + .thenReturn(value.toMaybe()); when(persister.write(barCode, source)) - .thenReturn(Observable.just(true)); + .thenReturn(Single.just(true)); - List result = simpleStore.get(barCode).toBlocking().first(); + List result = simpleStore.get(barCode).blockingGet(); assertThat(result.get(0).value).isEqualTo("a"); assertThat(result.get(1).value).isEqualTo("b"); assertThat(result.get(2).value).isEqualTo("c"); diff --git a/store/build.gradle b/store/build.gradle index aadc215e..dd8ce145 100644 --- a/store/build.gradle +++ b/store/build.gradle @@ -5,7 +5,7 @@ version = VERSION_NAME dependencies { compile project(path: ':cache') - compile libraries.rxJava + compile libraries.rxJava2 compile libraries.jsr305 testCompile libraries.mockito diff --git a/store/gradle.properties b/store/gradle.properties index a02df4a1..e72a6d5c 100644 --- a/store/gradle.properties +++ b/store/gradle.properties @@ -1,3 +1,3 @@ POM_NAME=com.nytimes.android -POM_ARTIFACT_ID=store +POM_ARTIFACT_ID=store2 POM_PACKAGING=aar diff --git a/store/src/main/java/com/nytimes/android/external/store/base/DiskRead.java b/store/src/main/java/com/nytimes/android/external/store/base/DiskRead.java deleted file mode 100644 index aae574d3..00000000 --- a/store/src/main/java/com/nytimes/android/external/store/base/DiskRead.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.nytimes.android.external.store.base; - -import javax.annotation.Nonnull; - -import rx.Observable; - -public interface DiskRead { - @Nonnull - Observable read(@Nonnull Key key); -} diff --git a/store/src/main/java/com/nytimes/android/external/store/base/InternalStore.java b/store/src/main/java/com/nytimes/android/external/store/base/InternalStore.java deleted file mode 100644 index 4faf4fcb..00000000 --- a/store/src/main/java/com/nytimes/android/external/store/base/InternalStore.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.nytimes.android.external.store.base; - -import com.nytimes.android.external.store.base.impl.Store; - -import javax.annotation.Nonnull; - -import rx.Observable; - -/** - * this interface allows us to mark a {@link Store} as "internal", exposing methods for retrieving data - * directly from memory or from disk. - */ -public interface InternalStore extends Store { - @Nonnull - Observable memory(@Nonnull final Key key); - - @Nonnull - Observable disk(@Nonnull final Key key); -} diff --git a/store/src/main/java/com/nytimes/android/external/store/base/Parser.java b/store/src/main/java/com/nytimes/android/external/store/base/Parser.java deleted file mode 100644 index 7c514a77..00000000 --- a/store/src/main/java/com/nytimes/android/external/store/base/Parser.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.nytimes.android.external.store.base; - -import rx.functions.Func1; - -//just a marker interface allowing for a reimplementation of how the parser is implemented -public interface Parser extends Func1 { -} diff --git a/store/src/main/java/com/nytimes/android/external/store/base/impl/RealInternalStore.java b/store/src/main/java/com/nytimes/android/external/store/base/impl/RealInternalStore.java deleted file mode 100644 index 9677a253..00000000 --- a/store/src/main/java/com/nytimes/android/external/store/base/impl/RealInternalStore.java +++ /dev/null @@ -1,360 +0,0 @@ -package com.nytimes.android.external.store.base.impl; - -import com.nytimes.android.external.cache.Cache; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.InternalStore; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.util.KeyParser; -import com.nytimes.android.external.store.util.OnErrorResumeWithEmpty; - -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ExecutionException; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import rx.Observable; -import rx.annotations.Experimental; -import rx.functions.Action0; -import rx.functions.Action1; -import rx.functions.Func0; -import rx.functions.Func1; -import rx.subjects.PublishSubject; - -import static com.nytimes.android.external.store.base.impl.StoreUtil.persisterIsStale; -import static com.nytimes.android.external.store.base.impl.StoreUtil.shouldReturnNetworkBeforeStale; - -/** - * Store to be used for loading an object from different data sources - * - * @param data type before parsing, usually a String, Reader or BufferedSource - * @param data type after parsing - *

- * Example usage: @link - */ -final class RealInternalStore implements InternalStore { - Cache> inFlightRequests; - Cache> memCache; - Persister persister; - KeyParser parser; - StalePolicy stalePolicy; - private final PublishSubject refreshSubject = PublishSubject.create(); - private Fetcher fetcher; - private PublishSubject subject; - - RealInternalStore(Fetcher fetcher, - Persister persister, - KeyParser parser, - StalePolicy stalePolicy) { - this(fetcher, persister, parser, null, stalePolicy); - } - - RealInternalStore(Fetcher fetcher, - Persister persister, - KeyParser parser, - MemoryPolicy memoryPolicy, - StalePolicy stalePolicy) { - - this.fetcher = fetcher; - this.persister = persister; - this.parser = parser; - this.stalePolicy = stalePolicy; - - this.memCache = CacheFactory.createCache(memoryPolicy); - this.inFlightRequests = CacheFactory.createInflighter(memoryPolicy); - - subject = PublishSubject.create(); - } - - /** - * @param key - * @return an observable from the first data source that is available - */ - @Nonnull - @Override - public Observable get(@Nonnull final Key key) { - return Observable.concat( - lazyCache(key), - fetch(key) - ).take(1); - } - - @Override - @Nonnull - @Experimental - public Observable getRefreshing(@Nonnull final Key key) { - return get(key) - .compose(StoreUtil.repeatWhenCacheEvicted(refreshSubject, key)); - } - - - /** - * @return data from memory - */ - private Observable lazyCache(@Nonnull final Key key) { - return Observable - .defer(new Func0>() { - @Override - public Observable call() { - return cache(key); - } - }) - .onErrorResumeNext(new OnErrorResumeWithEmpty()); - } - - Observable cache(@Nonnull final Key key) { - try { - return memCache.get(key, new Callable>() { - @Nonnull - @Override - @SuppressWarnings("PMD.SignatureDeclareThrowsException") - public Observable call() throws Exception { - return disk(key); - } - }); - } catch (ExecutionException e) { - return Observable.empty(); - } - } - - - @Nonnull - @Override - public Observable memory(@Nonnull Key key) { - Observable cachedValue = memCache.getIfPresent(key); - return cachedValue == null ? Observable.empty() : cachedValue; - } - - /** - * Fetch data from persister and update memory after. If an error occurs, emit an empty observable - * so that the concat call in {@link #get(Key)} moves on to {@link #fetch(Key)} - * - * @param key - * @return - */ - @Nonnull - @Override - public Observable disk(@Nonnull final Key key) { - if (shouldReturnNetworkBeforeStale(persister, stalePolicy, key)) { - return Observable.empty(); - } - - return readDisk(key); - } - - Observable readDisk(@Nonnull final Key key) { - return readDisk(key, null); - } - - Observable readDisk(@Nonnull final Key key, final Throwable error) { - return persister().read(key) - .onErrorResumeNext(new Func1>() { - @Override - public Observable call(Throwable throwable) { - if (error == null) { - return Observable.empty(); - } else { - return Observable.error(error); - } - } - }) - .map(new Func1() { - @Override - public Parsed call(Raw raw) { - return parser.call(key, raw); - } - }) - .doOnNext(new Action1() { - @Override - public void call(Parsed parsed) { - updateMemory(key, parsed); - if (stalePolicy == StalePolicy.REFRESH_ON_STALE - && persisterIsStale(key, persister)) { - backfillCache(key); - } - } - }).cache(); - } - - void backfillCache(@Nonnull Key key) { - fetch(key).subscribe(new Action1() { - @Override - public void call(Parsed parsed) { - //do nothing we are just backfilling cache - } - }, new Action1() { - @Override - public void call(Throwable throwable) { - //do nothing as we are just backfilling cache - } - }); - } - - - /** - * Will check to see if there exists an in flight observable and return it before - * going to network - * - * @return data from fetch and store it in memory and persister - */ - @Nonnull - @Override - public Observable fetch(@Nonnull final Key key) { - return Observable.defer(new Func0>() { - @Nullable - @Override - public Observable call() { - return fetchAndPersist(key); - } - }); - } - - /** - * There should only be one fetch request in flight at any give time. - *

- * Return cached request in the form of a Behavior Subject which will emit to its subscribers - * the last value it gets. Subject/Observable is cached in a {@link ConcurrentMap} to maintain - * thread safety. - * - * @param key resource identifier - * @return observable that emits a {@link Parsed} value - */ - @Nullable - Observable fetchAndPersist(@Nonnull final Key key) { - try { - return inFlightRequests.get(key, new Callable>() { - @Nonnull - @Override - public Observable call() { - return response(key); - } - }); - } catch (ExecutionException e) { - return Observable.empty(); - } - } - - @Nonnull - Observable response(@Nonnull final Key key) { - return fetcher() - .fetch(key) - .flatMap(new Func1>() { - @Override - public Observable call(Raw raw) { - return persister().write(key, raw) - .flatMap(new Func1>() { - @Override - public Observable call(Boolean aBoolean) { - return readDisk(key); - } - }); - } - }) - .onErrorResumeNext(new Func1>() { - @Override - public Observable call(Throwable throwable) { - if (stalePolicy == StalePolicy.NETWORK_BEFORE_STALE) { - return readDisk(key, throwable); - } - return Observable.error(throwable); - } - }) - .doOnNext(new Action1() { - @Override - public void call(Parsed data) { - notifySubscribers(data); - } - }) - .doOnTerminate(new Action0() { - @Override - public void call() { - inFlightRequests.invalidate(key); - } - }) - .cache(); - } - - void notifySubscribers(Parsed data) { - subject.onNext(data); - } - - /** - * Get data stream for Subjects with the argument id - * - * @return - */ - @Nonnull - @Override - public Observable stream(@Nonnull Key key) { - return subject.startWith(get(key)); - } - - @Nonnull - @Override - public Observable stream() { - return subject.asObservable(); - } - - /** - * Only update memory after persister has been successfully updated - * - * @param key - * @param data - */ - void updateMemory(@Nonnull final Key key, final Parsed data) { - memCache.put(key, Observable.just(data)); - } - - @Override - @Deprecated - public void clearMemory() { - clear(); - } - - /** - * Clear memory by id - * - * @param key of data to clear - */ - @Override - @Deprecated - public void clearMemory(@Nonnull final Key key) { - clear(key); - } - - - @Override - public void clear() { - for (Key cachedKey : memCache.asMap().keySet()) { - clear(cachedKey); - } - } - - @Override - public void clear(@Nonnull Key key) { - inFlightRequests.invalidate(key); - memCache.invalidate(key); - StoreUtil.clearPersister(persister(), key); - notifyRefresh(key); - } - - private void notifyRefresh(@Nonnull Key key) { - refreshSubject.onNext(key); - } - - /** - * @return DiskDAO that stores and stores data - */ - Persister persister() { - return persister; - } - - /** - * - */ - Fetcher fetcher() { - return fetcher; - } -} - diff --git a/store/src/main/java/com/nytimes/android/external/store/base/impl/RepeatWhenEmits.java b/store/src/main/java/com/nytimes/android/external/store/base/impl/RepeatWhenEmits.java deleted file mode 100644 index 0a018e2a..00000000 --- a/store/src/main/java/com/nytimes/android/external/store/base/impl/RepeatWhenEmits.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.nytimes.android.external.store.base.impl; - -import javax.annotation.Nonnull; - -import rx.Observable; -import rx.functions.Func1; - -import static com.nytimes.android.external.cache.Preconditions.checkNotNull; - -/** - * A Transformer that takes a source observable and re-subscribes to the upstream Observable when - * it emits. - */ -final class RepeatWhenEmits implements Observable.Transformer { - - private final Observable source; - - private RepeatWhenEmits(@Nonnull Observable source) { - this.source = source; - } - - @Nonnull - static RepeatWhenEmits from(@Nonnull Observable source) { - return new RepeatWhenEmits<>(checkNotNull(source)); - } - - @Override - public Observable call(Observable upstream) { - return upstream.repeatWhen(new Func1, Observable>() { - @Override - public Observable call(Observable events) { - return events.switchMap(new Func1>() { - @Override - public Observable call(Void aVoid) { - return source; - } - }); - } - }); - } -} diff --git a/store/src/main/java/com/nytimes/android/external/store/util/KeyParser.java b/store/src/main/java/com/nytimes/android/external/store/util/KeyParser.java deleted file mode 100644 index a3a8b288..00000000 --- a/store/src/main/java/com/nytimes/android/external/store/util/KeyParser.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.nytimes.android.external.store.util; - -import javax.annotation.Nonnull; - -import rx.functions.Func2; - -public interface KeyParser extends Func2 { - - - @Override - @Nonnull - Parsed call(@Nonnull Key key, @Nonnull Raw raw); -} diff --git a/store/src/main/java/com/nytimes/android/external/store/util/NoopParserFunc.java b/store/src/main/java/com/nytimes/android/external/store/util/NoopParserFunc.java deleted file mode 100644 index 9373bd26..00000000 --- a/store/src/main/java/com/nytimes/android/external/store/util/NoopParserFunc.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.nytimes.android.external.store.util; - -import com.nytimes.android.external.store.base.Parser; - -/** - * Pass-through parser for stores that parse externally - */ -public class NoopParserFunc implements Parser { - @Override - public Object call(Object object) { - return object; - } -} diff --git a/store/src/main/java/com/nytimes/android/external/store/util/OnErrorResumeWithEmpty.java b/store/src/main/java/com/nytimes/android/external/store/util/OnErrorResumeWithEmpty.java deleted file mode 100644 index e1025afd..00000000 --- a/store/src/main/java/com/nytimes/android/external/store/util/OnErrorResumeWithEmpty.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.nytimes.android.external.store.util; - -import rx.Observable; -import rx.functions.Func1; - -/** - * Resume with empty observable on error - */ -public class OnErrorResumeWithEmpty implements Func1> { - - @Override - public Observable call(Throwable throwable) { - return Observable.empty(); - } -} diff --git a/store/src/main/java/com/nytimes/android/external/store/util/ParserException.java b/store/src/main/java/com/nytimes/android/external/store/util/ParserException.java deleted file mode 100644 index d3ea2298..00000000 --- a/store/src/main/java/com/nytimes/android/external/store/util/ParserException.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.nytimes.android.external.store.util; - -/** - * Exception thrown when one of the provided parsers fails. - */ -public class ParserException extends RuntimeException { - - public ParserException(String message) { - super(message); - } -} diff --git a/store/src/main/java/com/nytimes/android/external/store/base/Clearable.java b/store/src/main/java/com/nytimes/android/external/store2/base/Clearable.java similarity index 83% rename from store/src/main/java/com/nytimes/android/external/store/base/Clearable.java rename to store/src/main/java/com/nytimes/android/external/store2/base/Clearable.java index 9b8baef3..a037914e 100644 --- a/store/src/main/java/com/nytimes/android/external/store/base/Clearable.java +++ b/store/src/main/java/com/nytimes/android/external/store2/base/Clearable.java @@ -1,4 +1,4 @@ -package com.nytimes.android.external.store.base; +package com.nytimes.android.external.store2.base; import javax.annotation.Nonnull; diff --git a/store/src/main/java/com/nytimes/android/external/store2/base/DiskRead.java b/store/src/main/java/com/nytimes/android/external/store2/base/DiskRead.java new file mode 100644 index 00000000..4247bbda --- /dev/null +++ b/store/src/main/java/com/nytimes/android/external/store2/base/DiskRead.java @@ -0,0 +1,10 @@ +package com.nytimes.android.external.store2.base; + +import javax.annotation.Nonnull; + +import io.reactivex.Maybe; + +public interface DiskRead { + @Nonnull + Maybe read(@Nonnull Key key); +} diff --git a/store/src/main/java/com/nytimes/android/external/store/base/DiskWrite.java b/store/src/main/java/com/nytimes/android/external/store2/base/DiskWrite.java similarity index 67% rename from store/src/main/java/com/nytimes/android/external/store/base/DiskWrite.java rename to store/src/main/java/com/nytimes/android/external/store2/base/DiskWrite.java index 0321de5c..0eb31de9 100644 --- a/store/src/main/java/com/nytimes/android/external/store/base/DiskWrite.java +++ b/store/src/main/java/com/nytimes/android/external/store2/base/DiskWrite.java @@ -1,8 +1,8 @@ -package com.nytimes.android.external.store.base; +package com.nytimes.android.external.store2.base; import javax.annotation.Nonnull; -import rx.Observable; +import io.reactivex.Single; public interface DiskWrite { /** @@ -11,5 +11,5 @@ public interface DiskWrite { * either return Observable.empty or throw an exception */ @Nonnull - Observable write(@Nonnull Key key, @Nonnull Raw raw); + Single write(@Nonnull Key key, @Nonnull Raw raw); } diff --git a/store/src/main/java/com/nytimes/android/external/store/base/Fetcher.java b/store/src/main/java/com/nytimes/android/external/store2/base/Fetcher.java similarity index 73% rename from store/src/main/java/com/nytimes/android/external/store/base/Fetcher.java rename to store/src/main/java/com/nytimes/android/external/store2/base/Fetcher.java index 4fb5325d..242992c3 100644 --- a/store/src/main/java/com/nytimes/android/external/store/base/Fetcher.java +++ b/store/src/main/java/com/nytimes/android/external/store2/base/Fetcher.java @@ -1,8 +1,9 @@ -package com.nytimes.android.external.store.base; +package com.nytimes.android.external.store2.base; import javax.annotation.Nonnull; -import rx.Observable; +import io.reactivex.Single; + /** * Interface for fetching new data for a Store @@ -16,5 +17,5 @@ public interface Fetcher { * @return Observable that emits {@link Raw} data */ @Nonnull - Observable fetch(@Nonnull Key key); + Single fetch(@Nonnull Key key); } diff --git a/store/src/main/java/com/nytimes/android/external/store2/base/InternalStore.java b/store/src/main/java/com/nytimes/android/external/store2/base/InternalStore.java new file mode 100644 index 00000000..7ceb110e --- /dev/null +++ b/store/src/main/java/com/nytimes/android/external/store2/base/InternalStore.java @@ -0,0 +1,19 @@ +package com.nytimes.android.external.store2.base; + +import com.nytimes.android.external.store2.base.impl.Store; + +import javax.annotation.Nonnull; + +import io.reactivex.Maybe; + +/** +2 * this interface allows us to mark a {@link Store} as "internal", exposing methods for retrieving data + * directly from memory or from disk. + */ +public interface InternalStore extends Store { + @Nonnull + Maybe memory(@Nonnull final Key key); + + @Nonnull + Maybe disk(@Nonnull final Key key); +} diff --git a/store/src/main/java/com/nytimes/android/external/store2/base/Parser.java b/store/src/main/java/com/nytimes/android/external/store2/base/Parser.java new file mode 100644 index 00000000..a3af271c --- /dev/null +++ b/store/src/main/java/com/nytimes/android/external/store2/base/Parser.java @@ -0,0 +1,14 @@ +package com.nytimes.android.external.store2.base; + +import com.nytimes.android.external.store2.util.ParserException; + +import io.reactivex.annotations.NonNull; +import io.reactivex.functions.Function; + +//just a marker interface allowing for a reimplementation of how the parser is implemented +public interface Parser extends Function { + + @Override + Parsed apply(@NonNull Raw raw) throws ParserException; + +} diff --git a/store/src/main/java/com/nytimes/android/external/store/base/Persister.java b/store/src/main/java/com/nytimes/android/external/store2/base/Persister.java similarity index 74% rename from store/src/main/java/com/nytimes/android/external/store/base/Persister.java rename to store/src/main/java/com/nytimes/android/external/store2/base/Persister.java index 39b6a51a..38646b3e 100644 --- a/store/src/main/java/com/nytimes/android/external/store/base/Persister.java +++ b/store/src/main/java/com/nytimes/android/external/store2/base/Persister.java @@ -1,8 +1,9 @@ -package com.nytimes.android.external.store.base; +package com.nytimes.android.external.store2.base; import javax.annotation.Nonnull; -import rx.Observable; +import io.reactivex.Maybe; +import io.reactivex.Single; /** * Interface for fetching data from persister @@ -19,7 +20,7 @@ public interface Persister extends DiskRead, DiskWrite read(@Nonnull final Key key); + Maybe read(@Nonnull final Key key); /** * @param key to use to store data to persister @@ -27,5 +28,5 @@ public interface Persister extends DiskRead, DiskWrite write(@Nonnull final Key key, @Nonnull final Raw raw); + Single write(@Nonnull final Key key, @Nonnull final Raw raw); } diff --git a/store/src/main/java/com/nytimes/android/external/store/base/RecordProvider.java b/store/src/main/java/com/nytimes/android/external/store2/base/RecordProvider.java similarity index 73% rename from store/src/main/java/com/nytimes/android/external/store/base/RecordProvider.java rename to store/src/main/java/com/nytimes/android/external/store2/base/RecordProvider.java index 41d7141f..99750f30 100644 --- a/store/src/main/java/com/nytimes/android/external/store/base/RecordProvider.java +++ b/store/src/main/java/com/nytimes/android/external/store2/base/RecordProvider.java @@ -1,4 +1,4 @@ -package com.nytimes.android.external.store.base; +package com.nytimes.android.external.store2.base; import javax.annotation.Nonnull; diff --git a/store/src/main/java/com/nytimes/android/external/store/base/RecordState.java b/store/src/main/java/com/nytimes/android/external/store2/base/RecordState.java similarity index 52% rename from store/src/main/java/com/nytimes/android/external/store/base/RecordState.java rename to store/src/main/java/com/nytimes/android/external/store2/base/RecordState.java index 480b806c..fe1feaa1 100644 --- a/store/src/main/java/com/nytimes/android/external/store/base/RecordState.java +++ b/store/src/main/java/com/nytimes/android/external/store2/base/RecordState.java @@ -1,4 +1,4 @@ -package com.nytimes.android.external.store.base; +package com.nytimes.android.external.store2.base; public enum RecordState { FRESH, STALE, MISSING diff --git a/store/src/main/java/com/nytimes/android/external/store/base/impl/BarCode.java b/store/src/main/java/com/nytimes/android/external/store2/base/impl/BarCode.java similarity index 87% rename from store/src/main/java/com/nytimes/android/external/store/base/impl/BarCode.java rename to store/src/main/java/com/nytimes/android/external/store2/base/impl/BarCode.java index ed16a8e4..c46f9994 100644 --- a/store/src/main/java/com/nytimes/android/external/store/base/impl/BarCode.java +++ b/store/src/main/java/com/nytimes/android/external/store2/base/impl/BarCode.java @@ -1,17 +1,18 @@ -package com.nytimes.android.external.store.base.impl; +package com.nytimes.android.external.store2.base.impl; import com.nytimes.android.external.cache.Preconditions; +import com.nytimes.android.external.store2.base.Persister; import java.io.Serializable; import javax.annotation.Nonnull; /** - * {@link com.nytimes.android.external.store.base.impl.BarCode Barcode} is used as a unique + * {@link BarCode Barcode} is used as a unique * identifier for a particular {@link Store Store} *

* Barcode will be passed to Fetcher - * and {@link com.nytimes.android.external.store.base.Persister Persister} + * and {@link Persister Persister} **/ public final class BarCode implements Serializable { diff --git a/store/src/main/java/com/nytimes/android/external/store/base/impl/MemoryPolicy.java b/store/src/main/java/com/nytimes/android/external/store2/base/impl/MemoryPolicy.java similarity index 86% rename from store/src/main/java/com/nytimes/android/external/store/base/impl/MemoryPolicy.java rename to store/src/main/java/com/nytimes/android/external/store2/base/impl/MemoryPolicy.java index 1a153814..875e712b 100644 --- a/store/src/main/java/com/nytimes/android/external/store/base/impl/MemoryPolicy.java +++ b/store/src/main/java/com/nytimes/android/external/store2/base/impl/MemoryPolicy.java @@ -1,18 +1,20 @@ -package com.nytimes.android.external.store.base.impl; +package com.nytimes.android.external.store2.base.impl; +import com.nytimes.android.external.store2.util.NoopPersister; + import java.util.concurrent.TimeUnit; /** * MemoryPolicy holds all required info to create MemoryCache and - * {@link com.nytimes.android.external.store.util.NoopPersister NoopPersister} + * {@link NoopPersister NoopPersister} *

* This class is used, in order to define the appropriate parameters for the MemoryCache * to be built. *

- * MemoryPolicy is used by a {@link com.nytimes.android.external.store.base.impl.Store Store} + * MemoryPolicy is used by a {@link Store Store} * and defines the in-memory cache behavior. It is also used by - * {@link com.nytimes.android.external.store.util.NoopPersister NoopPersister} + * {@link NoopPersister NoopPersister} * to define a basic caching mechanism. */ public class MemoryPolicy { diff --git a/store/src/main/java/com/nytimes/android/external/store/base/impl/MultiParser.java b/store/src/main/java/com/nytimes/android/external/store2/base/impl/MultiParser.java similarity index 77% rename from store/src/main/java/com/nytimes/android/external/store/base/impl/MultiParser.java rename to store/src/main/java/com/nytimes/android/external/store2/base/impl/MultiParser.java index 26ba559b..ebf392a5 100644 --- a/store/src/main/java/com/nytimes/android/external/store/base/impl/MultiParser.java +++ b/store/src/main/java/com/nytimes/android/external/store2/base/impl/MultiParser.java @@ -1,11 +1,13 @@ -package com.nytimes.android.external.store.base.impl; +package com.nytimes.android.external.store2.base.impl; -import com.nytimes.android.external.store.util.KeyParser; -import com.nytimes.android.external.store.util.ParserException; +import com.nytimes.android.external.store2.util.KeyParser; +import com.nytimes.android.external.store2.util.ParserException; import java.util.ArrayList; import java.util.List; +import io.reactivex.annotations.NonNull; + import static com.nytimes.android.external.cache.Preconditions.checkArgument; import static com.nytimes.android.external.cache.Preconditions.checkNotNull; @@ -28,12 +30,13 @@ private ParserException createParserException() { } @Override + @NonNull @SuppressWarnings("unchecked") - public Parsed call(Key key, Raw raw) { + public Parsed apply(@NonNull Key key, @NonNull Raw raw) throws ParserException { Object parsed = raw; for (KeyParser parser : parsers) { try { - parsed = parser.call(key, parsed); + parsed = parser.apply(key, parsed); } catch (ClassCastException exception) { throw createParserException(); } diff --git a/store/src/main/java/com/nytimes/android/external/store/base/impl/ParsingStoreBuilder.java b/store/src/main/java/com/nytimes/android/external/store2/base/impl/ParsingStoreBuilder.java similarity index 85% rename from store/src/main/java/com/nytimes/android/external/store/base/impl/ParsingStoreBuilder.java rename to store/src/main/java/com/nytimes/android/external/store2/base/impl/ParsingStoreBuilder.java index fd4a380c..b4af35f6 100644 --- a/store/src/main/java/com/nytimes/android/external/store/base/impl/ParsingStoreBuilder.java +++ b/store/src/main/java/com/nytimes/android/external/store2/base/impl/ParsingStoreBuilder.java @@ -1,4 +1,4 @@ -package com.nytimes.android.external.store.base.impl; +package com.nytimes.android.external.store2.base.impl; import javax.annotation.Nonnull; diff --git a/store/src/main/java/com/nytimes/android/external/store2/base/impl/RealInternalStore.java b/store/src/main/java/com/nytimes/android/external/store2/base/impl/RealInternalStore.java new file mode 100644 index 00000000..30072737 --- /dev/null +++ b/store/src/main/java/com/nytimes/android/external/store2/base/impl/RealInternalStore.java @@ -0,0 +1,425 @@ +package com.nytimes.android.external.store2.base.impl; + +import com.nytimes.android.external.cache.Cache; +import com.nytimes.android.external.cache.CacheBuilder; +import com.nytimes.android.external.store2.base.Clearable; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.InternalStore; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.util.KeyParser; + +import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import io.reactivex.Maybe; +import io.reactivex.MaybeSource; +import io.reactivex.Observable; +import io.reactivex.Single; +import io.reactivex.SingleSource; +import io.reactivex.annotations.Experimental; +import io.reactivex.annotations.NonNull; +import io.reactivex.functions.Action; +import io.reactivex.functions.Consumer; +import io.reactivex.functions.Function; +import io.reactivex.subjects.BehaviorSubject; +import io.reactivex.subjects.PublishSubject; + +/** + * Store to be used for loading an object different data sources + * + * @param data type before parsing usually String, Reader or BufferedSource + * @param data type after parsing + *

+ * Example usage: @link + */ +@SuppressWarnings("PMD") +final class RealInternalStore implements InternalStore { + Cache> inFlightRequests; + Cache> memCache; + StalePolicy stalePolicy; + Persister persister; + KeyParser parser; + + private final PublishSubject refreshSubject = PublishSubject.create(); + private Fetcher fetcher; + private BehaviorSubject subject; + + RealInternalStore(Fetcher fetcher, + Persister persister, + KeyParser parser, + StalePolicy stalePolicy) { + this(fetcher, persister, parser, null, stalePolicy); + } + + RealInternalStore(Fetcher fetcher, + Persister persister, + KeyParser parser, + MemoryPolicy memoryPolicy, + StalePolicy stalePolicy) { + + this.fetcher = fetcher; + this.persister = persister; + this.parser = parser; + this.stalePolicy = stalePolicy; + + if (memoryPolicy == null) { + memoryPolicy = MemoryPolicy + .builder() + .setMemorySize(getCacheSize()) + .setExpireAfter(getCacheTTL()) + .setExpireAfterTimeUnit(getCacheTTLTimeUnit()) + .build(); + } + + initMemCache(memoryPolicy); + initFlightRequests(memoryPolicy); + + subject = BehaviorSubject.create(); + } + + private void initFlightRequests(MemoryPolicy memoryPolicy) { + long expireAfterToSeconds = memoryPolicy.getExpireAfterTimeUnit().toSeconds(memoryPolicy.getExpireAfter()); + long maximumInFlightRequestsDuration = TimeUnit.MINUTES.toSeconds(1); + + if (expireAfterToSeconds > maximumInFlightRequestsDuration) { + inFlightRequests = CacheBuilder + .newBuilder() + .expireAfterWrite(maximumInFlightRequestsDuration, TimeUnit.SECONDS) + .build(); + } else { + inFlightRequests = CacheBuilder.newBuilder() + .expireAfterWrite(memoryPolicy.getExpireAfter(), memoryPolicy.getExpireAfterTimeUnit()) + .build(); + } + } + + private void initMemCache(MemoryPolicy memoryPolicy) { + memCache = CacheBuilder + .newBuilder() + .maximumSize(memoryPolicy.getMaxSize()) + .expireAfterWrite(memoryPolicy.getExpireAfter(), memoryPolicy.getExpireAfterTimeUnit()) + .build(); + } + + /** + * @param key + * @return an observable from the first data source that is available + */ + @Nonnull + @Override + public Single get(@Nonnull final Key key) { + return lazyCache(key) + .switchIfEmpty(fetch(key).toMaybe()) + .toSingle(); + } + + @Override + @Nonnull + @Experimental + public Observable getRefreshing(@Nonnull final Key key) { + return get(key) + .toObservable() + .compose(StoreUtil.repeatWhenCacheEvicted(refreshSubject, key)); + } + + + /** + * @return data from memory + */ + private Maybe lazyCache(@Nonnull final Key key) { + return Maybe + .defer(new Callable>() { + @Override + public MaybeSource call() { + return cache(key); + } + }) + .onErrorResumeNext(Maybe.empty()); + } + + Maybe cache(@Nonnull final Key key) { + try { + return memCache.get(key, new Callable>() { + @Nonnull + @Override + public Maybe call() { + return disk(key); + } + }); + } catch (ExecutionException e) { + return Maybe.empty(); + } + } + + + @Nonnull + @Override + public Maybe memory(@Nonnull Key key) { + Maybe cachedValue = memCache.getIfPresent(key); + return cachedValue == null ? Maybe.empty() : cachedValue; + } + + /** + * Fetch data from persister and update memory after. If an error occurs, emit and empty observable + * so that the concat call in {@link #get(Key)} moves on to {@link #fetch(Key)} + * + * @param key + * @return + */ + @Nonnull + @Override + public Maybe disk(@Nonnull final Key key) { + if (StoreUtil.shouldReturnNetworkBeforeStale(persister, stalePolicy, key)) { + return Maybe.empty(); + } + + return readDisk(key); + } + + Maybe readDisk(@Nonnull final Key key) { + return persister().read(key) + .onErrorResumeNext(Maybe.empty()) + .map(new Function() { + @Override + public Parsed apply(@NonNull Raw raw) { + return parser.apply(key, raw); + } + }) + .doOnSuccess(new Consumer() { + @Override + public void accept(@NonNull Parsed parsed) { + updateMemory(key, parsed); + if (stalePolicy == StalePolicy.REFRESH_ON_STALE + && StoreUtil.persisterIsStale(key, persister)) { + backfillCache(key); + } + } + }).cache(); + } + + @SuppressWarnings("CheckReturnValue") + void backfillCache(@Nonnull Key key) { + fetch(key).subscribe(new Consumer() { + @Override + public void accept(@NonNull Parsed parsed) { + // do Nothing we are just backfilling cache + } + }, new Consumer() { + @Override + public void accept(@NonNull Throwable throwable) { + // do nothing as we are just backfilling cache + } + }); + } + + + /** + * Will check to see if there exists an in flight observable and return it before + * going to nerwork + * + * @return data from fetch and store it in memory and persister + */ + @Nonnull + @Override + public Single fetch(@Nonnull final Key key) { + return Single.defer(new Callable>() { + @Override + public SingleSource call() { + return fetchAndPersist(key); + } + }); + } + + /** + * There should only be one fetch request in flight at any give time. + *

+ * Return cached request in the form of a Behavior Subject which will emit to its subscribers + * the last value it gets. Subject/Observable is cached in a {@link ConcurrentMap} to maintain + * thread safety. + * + * @param key resource identifier + * @return observable that emits a {@link Parsed} value + */ + @Nullable + Single fetchAndPersist(@Nonnull final Key key) { + try { + return inFlightRequests.get(key, new Callable>() { + @Nonnull + @Override + public Single call() { + return response(key); + } + }); + } catch (ExecutionException e) { + return Single.error(e); + } + } + + @Nonnull + Single response(@Nonnull final Key key) { + return fetcher() + .fetch(key) + .flatMap(new Function>() { + @Override + public SingleSource apply(@NonNull Raw raw) { + return persister().write(key, raw) + .flatMap(new Function>() { + @Override + public SingleSource apply(@NonNull Boolean aBoolean) { + return readDisk(key).toSingle(); + } + }); + } + }) + .onErrorResumeNext(new Function>() { + @Override + public SingleSource apply(@NonNull Throwable throwable) { + if (stalePolicy == StalePolicy.NETWORK_BEFORE_STALE) { + return readDisk(key) + .switchIfEmpty(Maybe.error(throwable)) + .toSingle(); + } + return Single.error(throwable); + } + }) + .doOnSuccess(new Consumer() { + @Override + public void accept(@NonNull Parsed parsed) { + notifySubscribers(parsed); + } + }) + .doAfterTerminate(new Action() { + @Override + public void run() { + inFlightRequests.invalidate(key); + } + }) + .cache(); + } + + void notifySubscribers(Parsed data) { + subject.onNext(data); + } + + /** + * Get data stream for Subjects with the argument id + * + * @return + */ + @Nonnull + @Override + public Observable stream(@Nonnull Key key) { + + Observable stream = subject.hide(); + + //If nothing was emitted through the subject yet, start stream with get() value + if (!subject.hasValue()) { + return stream.startWith(get(key).toObservable()); + } + + return stream; + } + + @Nonnull + @Override + public Observable stream() { + return subject.hide(); + } + + /** + * Only update memory after persister has been successfully update + * + * @param key + * @param data + */ + void updateMemory(@Nonnull final Key key, final Parsed data) { + memCache.put(key, Maybe.just(data)); + } + + @Override + @Deprecated + public void clearMemory() { + clear(); + } + + /** + * Clear memory by id + * + * @param key of data to clear + */ + @Override + @Deprecated + public void clearMemory(@Nonnull final Key key) { + clear(key); + } + + + @Override + public void clear() { + for (Key cachedKey : memCache.asMap().keySet()) { + clear(cachedKey); + } + } + + @Override + public void clear(@Nonnull Key key) { + inFlightRequests.invalidate(key); + memCache.invalidate(key); + clearPersister(key); + notifyRefresh(key); + } + + private void notifyRefresh(Key key) { + refreshSubject.onNext(key); + } + + private void clearPersister(Key key) { + boolean isPersisterClearable = persister instanceof Clearable; + + if (isPersisterClearable) { + ((Clearable) persister).clear(key); + } + } + + /** + * Default Cache TTL, can be overridden + * + * @return memory persister ttl + */ + private long getCacheTTL() { + return TimeUnit.HOURS.toSeconds(24); + } + + /** + * Default mem persister is 1, can be overridden otherwise + * + * @return memory persister size + */ + private long getCacheSize() { + return 100; + } + + private TimeUnit getCacheTTLTimeUnit() { + return TimeUnit.SECONDS; + } + + /** + * @return DiskDAO that stores and stores data + */ + Persister persister() { + return persister; + } + + /** + * + */ + Fetcher fetcher() { + return fetcher; + } +} + diff --git a/store/src/main/java/com/nytimes/android/external/store/base/impl/RealStore.java b/store/src/main/java/com/nytimes/android/external/store2/base/impl/RealStore.java similarity index 76% rename from store/src/main/java/com/nytimes/android/external/store/base/impl/RealStore.java rename to store/src/main/java/com/nytimes/android/external/store2/base/impl/RealStore.java index 7b6bd76e..c5b0125d 100644 --- a/store/src/main/java/com/nytimes/android/external/store/base/impl/RealStore.java +++ b/store/src/main/java/com/nytimes/android/external/store2/base/impl/RealStore.java @@ -1,20 +1,21 @@ -package com.nytimes.android.external.store.base.impl; +package com.nytimes.android.external.store2.base.impl; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.InternalStore; -import com.nytimes.android.external.store.base.Parser; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.util.KeyParser; -import com.nytimes.android.external.store.util.NoKeyParser; -import com.nytimes.android.external.store.util.NoopParserFunc; -import com.nytimes.android.external.store.util.NoopPersister; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.InternalStore; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.util.KeyParser; +import com.nytimes.android.external.store2.util.NoKeyParser; +import com.nytimes.android.external.store2.util.NoopParserFunc; +import com.nytimes.android.external.store2.util.NoopPersister; import javax.annotation.Nonnull; -import rx.Observable; -import static com.nytimes.android.external.store.base.impl.StalePolicy.UNSPECIFIED; +import io.reactivex.Maybe; +import io.reactivex.Observable; +import io.reactivex.Single; public class RealStore implements Store { @@ -27,7 +28,7 @@ public RealStore(InternalStore internalStore) { public RealStore(Fetcher fetcher) { final Parser noOpFunc = new NoopParserFunc<>(); internalStore = new RealInternalStore<>(fetcher, NoopPersister.create(), - new NoKeyParser(noOpFunc), UNSPECIFIED); + new NoKeyParser(noOpFunc), StalePolicy.UNSPECIFIED); } public RealStore(Fetcher fetcher, @@ -36,7 +37,7 @@ public RealStore(Fetcher fetcher, internalStore = new RealInternalStore<>(fetcher, persister, new NoKeyParser(noOpFunc), - UNSPECIFIED); + StalePolicy.UNSPECIFIED); } public RealStore(Fetcher fetcher, @@ -45,7 +46,7 @@ public RealStore(Fetcher fetcher, internalStore = new RealInternalStore<>(fetcher, persister, new NoKeyParser(parser), - UNSPECIFIED); + StalePolicy.UNSPECIFIED); } @@ -70,7 +71,7 @@ public RealStore(Fetcher fetcher, @Nonnull @Override - public Observable get(@Nonnull final Key key) { + public Single get(@Nonnull final Key key) { return internalStore.get(key); } @@ -88,7 +89,7 @@ public Observable getRefreshing(@Nonnull Key key) { */ @Nonnull @Override - public Observable fetch(@Nonnull final Key key) { + public Single fetch(@Nonnull final Key key) { return internalStore.fetch(key); } @@ -129,12 +130,12 @@ public void clear(@Nonnull Key key) { internalStore.clear(key); } - protected Observable memory(@Nonnull Key key) { + protected Maybe memory(@Nonnull Key key) { return internalStore.memory(key); } @Nonnull - protected Observable disk(@Nonnull Key key) { + protected Maybe disk(@Nonnull Key key) { return internalStore.disk(key); } diff --git a/store/src/main/java/com/nytimes/android/external/store/base/impl/RealStoreBuilder.java b/store/src/main/java/com/nytimes/android/external/store2/base/impl/RealStoreBuilder.java similarity index 82% rename from store/src/main/java/com/nytimes/android/external/store/base/impl/RealStoreBuilder.java rename to store/src/main/java/com/nytimes/android/external/store2/base/impl/RealStoreBuilder.java index 0714e637..e18423b9 100644 --- a/store/src/main/java/com/nytimes/android/external/store/base/impl/RealStoreBuilder.java +++ b/store/src/main/java/com/nytimes/android/external/store2/base/impl/RealStoreBuilder.java @@ -1,22 +1,24 @@ -package com.nytimes.android.external.store.base.impl; +package com.nytimes.android.external.store2.base.impl; -import com.nytimes.android.external.store.base.DiskRead; -import com.nytimes.android.external.store.base.DiskWrite; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.Parser; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.util.KeyParser; -import com.nytimes.android.external.store.util.NoKeyParser; -import com.nytimes.android.external.store.util.NoopParserFunc; -import com.nytimes.android.external.store.util.NoopPersister; +import com.nytimes.android.external.store2.base.DiskRead; +import com.nytimes.android.external.store2.base.DiskWrite; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.util.KeyParser; +import com.nytimes.android.external.store2.util.NoKeyParser; +import com.nytimes.android.external.store2.util.NoopParserFunc; +import com.nytimes.android.external.store2.util.NoopPersister; import java.util.ArrayList; import java.util.List; import javax.annotation.Nonnull; -import rx.Observable; +import io.reactivex.Maybe; +import io.reactivex.Single; + /** * Builder where there parser is used. @@ -53,13 +55,13 @@ public RealStoreBuilder persister(final @Nonnull DiskRead() { @Nonnull @Override - public Observable read(@Nonnull Key key) { + public Maybe read(@Nonnull Key key) { return diskRead.read(key); } @Nonnull @Override - public Observable write(@Nonnull Key key, @Nonnull Raw raw) { + public Single write(@Nonnull Key key, @Nonnull Raw raw) { return diskWrite.write(key, raw); } }; @@ -80,7 +82,6 @@ public RealStoreBuilder parser(final @Nonnull KeyParser parsers(final @Nonnull List parsers) { diff --git a/store/src/main/java/com/nytimes/android/external/store2/base/impl/RepeatWhenEmits.java b/store/src/main/java/com/nytimes/android/external/store2/base/impl/RepeatWhenEmits.java new file mode 100644 index 00000000..f22276e1 --- /dev/null +++ b/store/src/main/java/com/nytimes/android/external/store2/base/impl/RepeatWhenEmits.java @@ -0,0 +1,44 @@ +package com.nytimes.android.external.store2.base.impl; + +import javax.annotation.Nonnull; + +import io.reactivex.Observable; +import io.reactivex.ObservableSource; +import io.reactivex.ObservableTransformer; +import io.reactivex.annotations.NonNull; +import io.reactivex.functions.Function; + +import static com.nytimes.android.external.cache.Preconditions.checkNotNull; + +/** + * A Transformer that takes a source observable and re-subscribes to the upstream Observable when + * it emits. + */ +final class RepeatWhenEmits implements ObservableTransformer { + + private final Observable source; + + private RepeatWhenEmits(@Nonnull Observable source) { + this.source = source; + } + + @Nonnull + static RepeatWhenEmits from(@Nonnull Observable source) { + return new RepeatWhenEmits<>(checkNotNull(source)); + } + + @Override + public ObservableSource apply(Observable upstream) { + return upstream.repeatWhen(new Function, ObservableSource>() { + @Override + public ObservableSource apply(@NonNull Observable objectObservable) { + return objectObservable.switchMap(new Function>() { + @Override + public ObservableSource apply(@NonNull Object o) { + return source; + } + }); + } + }); + } +} diff --git a/store/src/main/java/com/nytimes/android/external/store/base/impl/StalePolicy.java b/store/src/main/java/com/nytimes/android/external/store2/base/impl/StalePolicy.java similarity index 60% rename from store/src/main/java/com/nytimes/android/external/store/base/impl/StalePolicy.java rename to store/src/main/java/com/nytimes/android/external/store2/base/impl/StalePolicy.java index 6e43f163..4e8cd840 100644 --- a/store/src/main/java/com/nytimes/android/external/store/base/impl/StalePolicy.java +++ b/store/src/main/java/com/nytimes/android/external/store2/base/impl/StalePolicy.java @@ -1,4 +1,4 @@ -package com.nytimes.android.external.store.base.impl; +package com.nytimes.android.external.store2.base.impl; public enum StalePolicy { UNSPECIFIED, REFRESH_ON_STALE, NETWORK_BEFORE_STALE diff --git a/store/src/main/java/com/nytimes/android/external/store/base/impl/Store.java b/store/src/main/java/com/nytimes/android/external/store2/base/impl/Store.java similarity index 89% rename from store/src/main/java/com/nytimes/android/external/store/base/impl/Store.java rename to store/src/main/java/com/nytimes/android/external/store2/base/impl/Store.java index 9a2eb52a..21b82216 100644 --- a/store/src/main/java/com/nytimes/android/external/store/base/impl/Store.java +++ b/store/src/main/java/com/nytimes/android/external/store2/base/impl/Store.java @@ -1,13 +1,15 @@ -package com.nytimes.android.external.store.base.impl; +package com.nytimes.android.external.store2.base.impl; import javax.annotation.Nonnull; -import rx.Observable; -import rx.annotations.Experimental; +import io.reactivex.Observable; +import io.reactivex.Single; +import io.reactivex.annotations.Experimental; + /** - * a {@link com.nytimes.android.external.store.base.impl.StoreBuilder StoreBuilder} + * a {@link StoreBuilder StoreBuilder} * will return an instance of a store *

* A {@link Store Store} can @@ -23,7 +25,7 @@ public interface Store { * Sources are Memory Cache, Disk Cache, Inflight, Network Response */ @Nonnull - Observable get(@Nonnull V key); + Single get(@Nonnull V key); /** * Calls store.get(), additionally will repeat anytime store.clear(barcode) is called @@ -38,7 +40,7 @@ public interface Store { * Return an Observable of T for requested Barcode skipping Memory & Disk Cache */ @Nonnull - Observable fetch(@Nonnull V key); + Single fetch(@Nonnull V key); /** * @return an Observable that emits "fresh" new response from the store that hit the fetcher diff --git a/store/src/main/java/com/nytimes/android/external/store/base/impl/StoreBuilder.java b/store/src/main/java/com/nytimes/android/external/store2/base/impl/StoreBuilder.java similarity index 88% rename from store/src/main/java/com/nytimes/android/external/store/base/impl/StoreBuilder.java rename to store/src/main/java/com/nytimes/android/external/store2/base/impl/StoreBuilder.java index 1b2f5118..c9ac27b8 100644 --- a/store/src/main/java/com/nytimes/android/external/store/base/impl/StoreBuilder.java +++ b/store/src/main/java/com/nytimes/android/external/store2/base/impl/StoreBuilder.java @@ -1,8 +1,8 @@ -package com.nytimes.android.external.store.base.impl; +package com.nytimes.android.external.store2.base.impl; import javax.annotation.Nonnull; -import rx.annotations.Beta; +import io.reactivex.annotations.Beta; /** diff --git a/store/src/main/java/com/nytimes/android/external/store/base/impl/StoreUtil.java b/store/src/main/java/com/nytimes/android/external/store2/base/impl/StoreUtil.java similarity index 52% rename from store/src/main/java/com/nytimes/android/external/store/base/impl/StoreUtil.java rename to store/src/main/java/com/nytimes/android/external/store2/base/impl/StoreUtil.java index 06c12fee..570f2e5f 100644 --- a/store/src/main/java/com/nytimes/android/external/store/base/impl/StoreUtil.java +++ b/store/src/main/java/com/nytimes/android/external/store2/base/impl/StoreUtil.java @@ -1,28 +1,30 @@ -package com.nytimes.android.external.store.base.impl; +package com.nytimes.android.external.store2.base.impl; -import com.nytimes.android.external.store.base.Clearable; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.RecordProvider; -import com.nytimes.android.external.store.base.RecordState; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.RecordProvider; +import com.nytimes.android.external.store2.base.RecordState; import javax.annotation.Nonnull; -import rx.Observable; -import rx.functions.Func1; -import rx.subjects.PublishSubject; +import io.reactivex.Observable; +import io.reactivex.ObservableTransformer; +import io.reactivex.annotations.NonNull; +import io.reactivex.functions.Predicate; +import io.reactivex.subjects.PublishSubject; -import static com.nytimes.android.external.store.base.RecordState.STALE; + +import static com.nytimes.android.external.store2.base.RecordState.STALE; final class StoreUtil { private StoreUtil() { } @Nonnull - static Observable.Transformer + static ObservableTransformer repeatWhenCacheEvicted(PublishSubject refreshSubject, @Nonnull final Key keyForRepeat) { - Observable filter = refreshSubject.filter(new Func1() { + Observable filter = refreshSubject.filter(new Predicate() { @Override - public Boolean call(Key key) { + public boolean test(@NonNull Key key) throws Exception { return key.equals(keyForRepeat); } }); @@ -43,12 +45,4 @@ static boolean persisterIsStale(@Nonnull Key key, Persister } return false; } - - static void clearPersister(Persister persister, @Nonnull Key key) { - boolean isPersisterClearable = persister instanceof Clearable; - - if (isPersisterClearable) { - ((Clearable) persister).clear(key); - } - } } diff --git a/store/src/main/java/com/nytimes/android/external/store2/util/KeyParser.java b/store/src/main/java/com/nytimes/android/external/store2/util/KeyParser.java new file mode 100644 index 00000000..6f7ec7d1 --- /dev/null +++ b/store/src/main/java/com/nytimes/android/external/store2/util/KeyParser.java @@ -0,0 +1,11 @@ +package com.nytimes.android.external.store2.util; + +import io.reactivex.annotations.NonNull; +import io.reactivex.functions.BiFunction; + +public interface KeyParser extends BiFunction { + + @Override + Parsed apply(@NonNull Key key, @NonNull Raw raw) throws ParserException; + +} diff --git a/store/src/main/java/com/nytimes/android/external/store/util/NoKeyParser.java b/store/src/main/java/com/nytimes/android/external/store2/util/NoKeyParser.java similarity index 51% rename from store/src/main/java/com/nytimes/android/external/store/util/NoKeyParser.java rename to store/src/main/java/com/nytimes/android/external/store2/util/NoKeyParser.java index 6b301321..81d57368 100644 --- a/store/src/main/java/com/nytimes/android/external/store/util/NoKeyParser.java +++ b/store/src/main/java/com/nytimes/android/external/store2/util/NoKeyParser.java @@ -1,9 +1,11 @@ -package com.nytimes.android.external.store.util; +package com.nytimes.android.external.store2.util; -import com.nytimes.android.external.store.base.Parser; +import com.nytimes.android.external.store2.base.Parser; import javax.annotation.Nonnull; +import io.reactivex.annotations.NonNull; + public class NoKeyParser implements KeyParser { private final Parser parser; @@ -12,8 +14,7 @@ public NoKeyParser(@Nonnull Parser parser) { } @Override - @Nonnull - public Parsed call(@Nonnull Key key, @Nonnull Raw raw) { - return parser.call(raw); + public Parsed apply(@NonNull Key key, @NonNull Raw raw) throws ParserException { + return parser.apply(raw); } } diff --git a/store/src/main/java/com/nytimes/android/external/store2/util/NoopParserFunc.java b/store/src/main/java/com/nytimes/android/external/store2/util/NoopParserFunc.java new file mode 100644 index 00000000..29665449 --- /dev/null +++ b/store/src/main/java/com/nytimes/android/external/store2/util/NoopParserFunc.java @@ -0,0 +1,16 @@ +package com.nytimes.android.external.store2.util; + +import com.nytimes.android.external.store2.base.Parser; + +import io.reactivex.annotations.NonNull; + +/** + * Pass-through parser for stores that parse externally + */ +public class NoopParserFunc implements Parser { + + @Override + public Parsed apply(@NonNull Raw raw) throws ParserException { + return (Parsed) raw; + } +} diff --git a/store/src/main/java/com/nytimes/android/external/store/util/NoopPersister.java b/store/src/main/java/com/nytimes/android/external/store2/util/NoopPersister.java similarity index 67% rename from store/src/main/java/com/nytimes/android/external/store/util/NoopPersister.java rename to store/src/main/java/com/nytimes/android/external/store2/util/NoopPersister.java index 0bd60215..8c6f1299 100644 --- a/store/src/main/java/com/nytimes/android/external/store/util/NoopPersister.java +++ b/store/src/main/java/com/nytimes/android/external/store2/util/NoopPersister.java @@ -1,23 +1,24 @@ -package com.nytimes.android.external.store.util; - +package com.nytimes.android.external.store2.util; import com.nytimes.android.external.cache.Cache; import com.nytimes.android.external.cache.CacheBuilder; -import com.nytimes.android.external.store.base.Clearable; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.impl.MemoryPolicy; +import com.nytimes.android.external.store2.base.Clearable; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.impl.MemoryPolicy; import java.util.concurrent.TimeUnit; import javax.annotation.Nonnull; -import rx.Observable; +import io.reactivex.Maybe; +import io.reactivex.Single; + /** * Pass-through diskdao for stores that don't want to use persister */ public class NoopPersister implements Persister, Clearable { - protected final Cache> networkResponses; + protected final Cache> networkResponses; NoopPersister(MemoryPolicy memoryPolicy) { this.networkResponses = CacheBuilder @@ -49,16 +50,16 @@ public static NoopPersister create(MemoryPolicy memoryPolic @Nonnull @Override - public Observable read(@Nonnull Key key) { - Observable cachedValue = networkResponses.getIfPresent(key); - return cachedValue == null ? Observable.empty() : cachedValue; + public Maybe read(@Nonnull Key key) { + Maybe cachedValue = networkResponses.getIfPresent(key); + return cachedValue == null ? Maybe.empty() : cachedValue; } @Nonnull @Override - public Observable write(@Nonnull Key key, @Nonnull Raw raw) { - networkResponses.put(key, Observable.just(raw)); - return Observable.just(true); + public Single write(@Nonnull Key key, @Nonnull Raw raw) { + networkResponses.put(key, Maybe.just(raw)); + return Single.just(true); } @Override diff --git a/store/src/main/java/com/nytimes/android/external/store2/util/ParserException.java b/store/src/main/java/com/nytimes/android/external/store2/util/ParserException.java new file mode 100644 index 00000000..ebee0e4c --- /dev/null +++ b/store/src/main/java/com/nytimes/android/external/store2/util/ParserException.java @@ -0,0 +1,19 @@ +package com.nytimes.android.external.store2.util; + +/** + * Exception thrown when one of the provided parsers fails. + */ +public class ParserException extends RuntimeException { + + public ParserException(Throwable cause) { + super(cause); + } + + public ParserException(String message) { + super(message); + } + + public ParserException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/store/src/test/java/com/nytimes/android/external/store/GetRefreshingTest.java b/store/src/test/java/com/nytimes/android/external/store/GetRefreshingTest.java deleted file mode 100644 index 48353c42..00000000 --- a/store/src/test/java/com/nytimes/android/external/store/GetRefreshingTest.java +++ /dev/null @@ -1,134 +0,0 @@ -package com.nytimes.android.external.store; - -import com.nytimes.android.external.store.base.Clearable; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.StoreBuilder; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -import java.util.concurrent.Callable; -import java.util.concurrent.atomic.AtomicInteger; - -import javax.annotation.Nonnull; - -import rx.Observable; -import rx.observers.AssertableSubscriber; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class GetRefreshingTest { - @Mock - ClearingPersister persister; - AtomicInteger networkCalls; - private Store store; - - @Before - public void setUp() { - networkCalls = new AtomicInteger(0); - store = StoreBuilder.barcode() - .fetcher(new Fetcher() { - @Nonnull - @Override - public Observable fetch(@Nonnull BarCode barCode) { - return Observable.fromCallable(new Callable() { - @Override - public Integer call() { - return networkCalls.incrementAndGet(); - } - }); - } - }) - .persister(persister) - .open(); - } - - @Test - public void testRefreshOnClear() { - BarCode barcode = new BarCode("type", "key"); - when(persister.read(barcode)) - .thenReturn(Observable.empty()) //read from disk - .thenReturn(Observable.just(1)) //read from disk after fetching from network - .thenReturn(Observable.empty()) //read from disk after clearing disk cache - .thenReturn(Observable.just(1)); //read from disk after making additional network call - when(persister.write(barcode, 1)).thenReturn(Observable.just(true)); - when(persister.write(barcode, 2)).thenReturn(Observable.just(true)); - - - AssertableSubscriber refreshingObservable = store.getRefreshing(barcode).test(); - assertThat(refreshingObservable.getValueCount()).isEqualTo(1); - assertThat(networkCalls.intValue()).isEqualTo(1); - //clearing the store should produce another network call - store.clear(barcode); - assertThat(refreshingObservable.getValueCount()).isEqualTo(2); - assertThat(networkCalls.intValue()).isEqualTo(2); - - store.get(barcode).test().awaitTerminalEvent(); - assertThat(refreshingObservable.getValueCount()).isEqualTo(2); - assertThat(networkCalls.intValue()).isEqualTo(2); - } - - @Test - public void testRefreshOnClearAll() { - BarCode barcode1 = new BarCode("type", "key"); - BarCode barcode2 = new BarCode("type", "key2"); - - when(persister.read(barcode1)) - .thenReturn(Observable.empty()) //read from disk - .thenReturn(Observable.just(1)) //read from disk after fetching from network - .thenReturn(Observable.empty()) //read from disk after clearing disk cache - .thenReturn(Observable.just(1)); //read from disk after making additional network call - when(persister.write(barcode1, 1)).thenReturn(Observable.just(true)); - when(persister.write(barcode1, 2)).thenReturn(Observable.just(true)); - - when(persister.read(barcode2)) - .thenReturn(Observable.empty()) //read from disk - .thenReturn(Observable.just(1)) //read from disk after fetching from network - .thenReturn(Observable.empty()) //read from disk after clearing disk cache - .thenReturn(Observable.just(1)); //read from disk after making additional network call - - when(persister.write(barcode2, 1)).thenReturn(Observable.just(true)); - when(persister.write(barcode2, 2)).thenReturn(Observable.just(true)); - - AssertableSubscriber testObservable1 = store.getRefreshing(barcode1).test(); - AssertableSubscriber testObservable2 = store.getRefreshing(barcode2).test(); - assertThat(testObservable1.getValueCount()).isEqualTo(1); - assertThat(testObservable2.getValueCount()).isEqualTo(1); - - assertThat(networkCalls.intValue()).isEqualTo(2); - - store.clear(); - assertThat(networkCalls.intValue()).isEqualTo(4); - - - } - - //everything will be mocked - static class ClearingPersister implements Persister, Clearable { - @Override - public void clear(@Nonnull BarCode key) { - throw new RuntimeException(); - } - - @Nonnull - @Override - public Observable read(@Nonnull BarCode barCode) { - throw new RuntimeException(); - } - - @Nonnull - @Override - public Observable write(@Nonnull BarCode barCode, @Nonnull Integer integer) { - throw new RuntimeException(); - } - } - -} diff --git a/store/src/test/java/com/nytimes/android/external/store/SampleParsingStore.java b/store/src/test/java/com/nytimes/android/external/store/SampleParsingStore.java deleted file mode 100644 index b190b246..00000000 --- a/store/src/test/java/com/nytimes/android/external/store/SampleParsingStore.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.nytimes.android.external.store; - -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.Parser; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.RealStore; - - -public class SampleParsingStore extends RealStore { - - public SampleParsingStore(Fetcher fetcher, - Persister persister, - Parser parser) { - super(fetcher, persister, parser); - } -} diff --git a/store/src/test/java/com/nytimes/android/external/store/SampleStore.java b/store/src/test/java/com/nytimes/android/external/store/SampleStore.java deleted file mode 100644 index 15468f07..00000000 --- a/store/src/test/java/com/nytimes/android/external/store/SampleStore.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.nytimes.android.external.store; - -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.RealStore; - - -public class SampleStore extends RealStore { - public SampleStore(Fetcher fetcher, Persister persister) { - super(fetcher, persister); - } -} diff --git a/store/src/test/java/com/nytimes/android/external/store/ClearStoreMemoryTest.java b/store/src/test/java/com/nytimes/android/external/store2/ClearStoreMemoryTest.java similarity index 79% rename from store/src/test/java/com/nytimes/android/external/store/ClearStoreMemoryTest.java rename to store/src/test/java/com/nytimes/android/external/store2/ClearStoreMemoryTest.java index 93b9472c..b8821401 100644 --- a/store/src/test/java/com/nytimes/android/external/store/ClearStoreMemoryTest.java +++ b/store/src/test/java/com/nytimes/android/external/store2/ClearStoreMemoryTest.java @@ -1,9 +1,9 @@ -package com.nytimes.android.external.store; +package com.nytimes.android.external.store2; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.StoreBuilder; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; import org.junit.Before; import org.junit.Test; @@ -12,7 +12,7 @@ import javax.annotation.Nonnull; -import rx.Observable; +import io.reactivex.Single; import static org.assertj.core.api.Assertions.assertThat; @@ -28,8 +28,8 @@ public void setUp() { .fetcher(new Fetcher() { @Nonnull @Override - public Observable fetch(@Nonnull BarCode barCode) { - return Observable.fromCallable(new Callable() { + public Single fetch(@Nonnull BarCode barCode) { + return Single.fromCallable(new Callable() { @Override public Integer call() { return networkCalls++; diff --git a/store/src/test/java/com/nytimes/android/external/store/ClearStoreTest.java b/store/src/test/java/com/nytimes/android/external/store2/ClearStoreTest.java similarity index 54% rename from store/src/test/java/com/nytimes/android/external/store/ClearStoreTest.java rename to store/src/test/java/com/nytimes/android/external/store2/ClearStoreTest.java index 951faa9b..27d842a3 100644 --- a/store/src/test/java/com/nytimes/android/external/store/ClearStoreTest.java +++ b/store/src/test/java/com/nytimes/android/external/store2/ClearStoreTest.java @@ -1,9 +1,9 @@ -package com.nytimes.android.external.store; +package com.nytimes.android.external.store2; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.StoreBuilder; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; import org.junit.Before; import org.junit.Test; @@ -16,9 +16,11 @@ import javax.annotation.Nonnull; -import rx.Observable; -import static com.nytimes.android.external.store.GetRefreshingTest.ClearingPersister; +import io.reactivex.Maybe; +import io.reactivex.Single; + +import static com.nytimes.android.external.store2.GetRefreshingTest.ClearingPersister; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -37,8 +39,8 @@ public void setUp() { .fetcher(new Fetcher() { @Nonnull @Override - public Observable fetch(@Nonnull BarCode barCode) { - return Observable.fromCallable(new Callable() { + public Single fetch(@Nonnull BarCode barCode) { + return Single.fromCallable(new Callable() { @Override public Integer call() { return networkCalls.incrementAndGet(); @@ -56,12 +58,12 @@ public void testClearSingleBarCode() { BarCode barcode = new BarCode("type", "key"); when(persister.read(barcode)) - .thenReturn(Observable.empty()) //read from disk on get - .thenReturn(Observable.just(1)) //read from disk after fetching from network - .thenReturn(Observable.empty()) //read from disk after clearing - .thenReturn(Observable.just(1)); //read from disk after making additional network call - when(persister.write(barcode, 1)).thenReturn(Observable.just(true)); - when(persister.write(barcode, 2)).thenReturn(Observable.just(true)); + .thenReturn(Maybe.empty()) //read from disk on get + .thenReturn(Maybe.just(1)) //read from disk after fetching from network + .thenReturn(Maybe.empty()) //read from disk after clearing + .thenReturn(Maybe.just(1)); //read from disk after making additional network call + when(persister.write(barcode, 1)).thenReturn(Single.just(true)); + when(persister.write(barcode, 2)).thenReturn(Single.just(true)); store.get(barcode).test().awaitTerminalEvent(); @@ -80,21 +82,21 @@ public void testClearAllBarCodes() { BarCode barcode2 = new BarCode("type2", "key2"); when(persister.read(barcode1)) - .thenReturn(Observable.empty()) //read from disk - .thenReturn(Observable.just(1)) //read from disk after fetching from network - .thenReturn(Observable.empty()) //read from disk after clearing disk cache - .thenReturn(Observable.just(1)); //read from disk after making additional network call - when(persister.write(barcode1, 1)).thenReturn(Observable.just(true)); - when(persister.write(barcode1, 2)).thenReturn(Observable.just(true)); + .thenReturn(Maybe.empty()) //read from disk + .thenReturn(Maybe.just(1)) //read from disk after fetching from network + .thenReturn(Maybe.empty()) //read from disk after clearing disk cache + .thenReturn(Maybe.just(1)); //read from disk after making additional network call + when(persister.write(barcode1, 1)).thenReturn(Single.just(true)); + when(persister.write(barcode1, 2)).thenReturn(Single.just(true)); when(persister.read(barcode2)) - .thenReturn(Observable.empty()) //read from disk - .thenReturn(Observable.just(1)) //read from disk after fetching from network - .thenReturn(Observable.empty()) //read from disk after clearing disk cache - .thenReturn(Observable.just(1)); //read from disk after making additional network call + .thenReturn(Maybe.empty()) //read from disk + .thenReturn(Maybe.just(1)) //read from disk after fetching from network + .thenReturn(Maybe.empty()) //read from disk after clearing disk cache + .thenReturn(Maybe.just(1)); //read from disk after making additional network call - when(persister.write(barcode2, 1)).thenReturn(Observable.just(true)); - when(persister.write(barcode2, 2)).thenReturn(Observable.just(true)); + when(persister.write(barcode2, 1)).thenReturn(Single.just(true)); + when(persister.write(barcode2, 2)).thenReturn(Single.just(true)); // each request should produce one call diff --git a/store/src/test/java/com/nytimes/android/external/store/DontCacheErrorsTest.java b/store/src/test/java/com/nytimes/android/external/store2/DontCacheErrorsTest.java similarity index 63% rename from store/src/test/java/com/nytimes/android/external/store/DontCacheErrorsTest.java rename to store/src/test/java/com/nytimes/android/external/store2/DontCacheErrorsTest.java index 89d3b196..0ed07462 100644 --- a/store/src/test/java/com/nytimes/android/external/store/DontCacheErrorsTest.java +++ b/store/src/test/java/com/nytimes/android/external/store2/DontCacheErrorsTest.java @@ -1,9 +1,9 @@ -package com.nytimes.android.external.store; +package com.nytimes.android.external.store2; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.StoreBuilder; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; import org.junit.Before; import org.junit.Test; @@ -12,7 +12,8 @@ import javax.annotation.Nonnull; -import rx.Observable; +import io.reactivex.Single; + public class DontCacheErrorsTest { @@ -25,8 +26,8 @@ public void setUp() { .fetcher(new Fetcher() { @Nonnull @Override - public Observable fetch(@Nonnull BarCode barCode) { - return Observable.fromCallable(new Callable() { + public Single fetch(@Nonnull BarCode barCode) { + return Single.fromCallable(new Callable() { @Override public Integer call() { if (shouldThrow) { @@ -47,12 +48,13 @@ public void testStoreDoesntCacheErrors() throws InterruptedException { shouldThrow = true; store.get(barcode).test() - .awaitTerminalEvent() - .assertError(Exception.class); + .assertTerminated() + .assertError(Exception.class) + .awaitTerminalEvent(); shouldThrow = false; store.get(barcode).test() - .awaitTerminalEvent() - .assertNoErrors(); + .assertNoErrors() + .awaitTerminalEvent(); } } diff --git a/store/src/test/java/com/nytimes/android/external/store2/GetRefreshingTest.java b/store/src/test/java/com/nytimes/android/external/store2/GetRefreshingTest.java new file mode 100644 index 00000000..47bac47f --- /dev/null +++ b/store/src/test/java/com/nytimes/android/external/store2/GetRefreshingTest.java @@ -0,0 +1,135 @@ +package com.nytimes.android.external.store2; + +import com.nytimes.android.external.store2.base.Clearable; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.annotation.Nonnull; + +import io.reactivex.Maybe; +import io.reactivex.Single; +import io.reactivex.observers.TestObserver; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class GetRefreshingTest { + @Mock + ClearingPersister persister; + AtomicInteger networkCalls; + private Store store; + + @Before + public void setUp() { + networkCalls = new AtomicInteger(0); + store = StoreBuilder.barcode() + .fetcher(new Fetcher() { + @Nonnull + @Override + public Single fetch(@Nonnull BarCode barCode) { + return Single.fromCallable(new Callable() { + @Override + public Integer call() { + return networkCalls.incrementAndGet(); + } + }); + } + }) + .persister(persister) + .open(); + } + + @Test + public void testRefreshOnClear() { + BarCode barcode = new BarCode("type", "key"); + when(persister.read(barcode)) + .thenReturn(Maybe.empty()) //read from disk + .thenReturn(Maybe.just(1)) //read from disk after fetching from network + .thenReturn(Maybe.empty()) //read from disk after clearing disk cache + .thenReturn(Maybe.just(1)); //read from disk after making additional network call + when(persister.write(barcode, 1)).thenReturn(Single.just(true)); + when(persister.write(barcode, 2)).thenReturn(Single.just(true)); + + + TestObserver refreshingObservable = store.getRefreshing(barcode).test(); + refreshingObservable.assertValueCount(1); + assertThat(networkCalls.intValue()).isEqualTo(1); + //clearing the store should produce another network call + store.clear(barcode); + refreshingObservable.assertValueCount(2); + assertThat(networkCalls.intValue()).isEqualTo(2); + + store.get(barcode).test().awaitTerminalEvent(); + refreshingObservable.assertValueCount(2); + assertThat(networkCalls.intValue()).isEqualTo(2); + } + + @Test + public void testRefreshOnClearAll() { + BarCode barcode1 = new BarCode("type", "key"); + BarCode barcode2 = new BarCode("type", "key2"); + + when(persister.read(barcode1)) + .thenReturn(Maybe.empty()) //read from disk + .thenReturn(Maybe.just(1)) //read from disk after fetching from network + .thenReturn(Maybe.empty()) //read from disk after clearing disk cache + .thenReturn(Maybe.just(1)); //read from disk after making additional network call + when(persister.write(barcode1, 1)).thenReturn(Single.just(true)); + when(persister.write(barcode1, 2)).thenReturn(Single.just(true)); + + when(persister.read(barcode2)) + .thenReturn(Maybe.empty()) //read from disk + .thenReturn(Maybe.just(1)) //read from disk after fetching from network + .thenReturn(Maybe.empty()) //read from disk after clearing disk cache + .thenReturn(Maybe.just(1)); //read from disk after making additional network call + + when(persister.write(barcode2, 1)).thenReturn(Single.just(true)); + when(persister.write(barcode2, 2)).thenReturn(Single.just(true)); + + TestObserver testObservable1 = store.getRefreshing(barcode1).test(); + TestObserver testObservable2 = store.getRefreshing(barcode2).test(); + testObservable1.assertValueCount(1); + testObservable2.assertValueCount(1); + + assertThat(networkCalls.intValue()).isEqualTo(2); + + store.clear(); + assertThat(networkCalls.intValue()).isEqualTo(4); + + + } + + //everything will be mocked + static class ClearingPersister implements Persister, Clearable { + @Override + public void clear(@Nonnull BarCode key) { + throw new RuntimeException(); + } + + @Nonnull + @Override + public Maybe read(@Nonnull BarCode barCode) { + throw new RuntimeException(); + } + + @Nonnull + @Override + public Single write(@Nonnull BarCode barCode, @Nonnull Integer integer) { + throw new RuntimeException(); + } + } + +} diff --git a/store/src/test/java/com/nytimes/android/external/store/KeyParserTest.java b/store/src/test/java/com/nytimes/android/external/store2/KeyParserTest.java similarity index 56% rename from store/src/test/java/com/nytimes/android/external/store/KeyParserTest.java rename to store/src/test/java/com/nytimes/android/external/store2/KeyParserTest.java index 925b04f0..759c25a0 100644 --- a/store/src/test/java/com/nytimes/android/external/store/KeyParserTest.java +++ b/store/src/test/java/com/nytimes/android/external/store2/KeyParserTest.java @@ -1,9 +1,9 @@ -package com.nytimes.android.external.store; +package com.nytimes.android.external.store2; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.StoreBuilder; -import com.nytimes.android.external.store.util.KeyParser; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; +import com.nytimes.android.external.store2.util.KeyParser; import org.junit.Before; import org.junit.Test; @@ -12,8 +12,10 @@ import javax.annotation.Nonnull; -import rx.Observable; -import rx.observers.AssertableSubscriber; +import io.reactivex.Single; +import io.reactivex.annotations.NonNull; +import io.reactivex.observers.TestObserver; + @RunWith(MockitoJUnitRunner.class) public class KeyParserTest { @@ -27,27 +29,26 @@ public void setUp() throws Exception { store = StoreBuilder.parsedWithKey() .parser(new KeyParser() { @Override - public String call(Integer integer, String s) { + public String apply(@NonNull Integer integer, @NonNull String s) { return s + integer; } }) .fetcher(new Fetcher() { @Nonnull @Override - public Observable fetch(@Nonnull Integer integer) { - return Observable.just(NETWORK); + public Single fetch(@Nonnull Integer integer) { + return Single.just(NETWORK); } }).open(); } @Test + @SuppressWarnings("PMD.SignatureDeclareThrowsException") public void testStoreWithKeyParserFuncNoPersister() throws Exception { - AssertableSubscriber testObservable = store.get(KEY).test().awaitTerminalEvent(); + TestObserver testObservable = store.get(KEY).test().await(); testObservable.assertNoErrors() .assertValues(NETWORK + KEY) - .assertUnsubscribed(); - - + .awaitTerminalEvent(); } } diff --git a/store/src/test/java/com/nytimes/android/external/store2/SampleParsingStore.java b/store/src/test/java/com/nytimes/android/external/store2/SampleParsingStore.java new file mode 100644 index 00000000..9a12b41c --- /dev/null +++ b/store/src/test/java/com/nytimes/android/external/store2/SampleParsingStore.java @@ -0,0 +1,17 @@ +package com.nytimes.android.external.store2; + +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.RealStore; + + +public class SampleParsingStore extends RealStore { + + public SampleParsingStore(Fetcher fetcher, + Persister persister, + Parser parser) { + super(fetcher, persister, parser); + } +} diff --git a/store/src/test/java/com/nytimes/android/external/store2/SampleStore.java b/store/src/test/java/com/nytimes/android/external/store2/SampleStore.java new file mode 100644 index 00000000..c63a6c53 --- /dev/null +++ b/store/src/test/java/com/nytimes/android/external/store2/SampleStore.java @@ -0,0 +1,13 @@ +package com.nytimes.android.external.store2; + +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.RealStore; + + +public class SampleStore extends RealStore { + public SampleStore(Fetcher fetcher, Persister persister) { + super(fetcher, persister); + } +} diff --git a/store/src/test/java/com/nytimes/android/external/store/SequentialTest.java b/store/src/test/java/com/nytimes/android/external/store2/SequentialTest.java similarity index 68% rename from store/src/test/java/com/nytimes/android/external/store/SequentialTest.java rename to store/src/test/java/com/nytimes/android/external/store2/SequentialTest.java index 135b042a..738df9f3 100644 --- a/store/src/test/java/com/nytimes/android/external/store/SequentialTest.java +++ b/store/src/test/java/com/nytimes/android/external/store2/SequentialTest.java @@ -1,9 +1,9 @@ -package com.nytimes.android.external.store; +package com.nytimes.android.external.store2; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.StoreBuilder; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; import org.junit.Before; import org.junit.Test; @@ -12,7 +12,7 @@ import javax.annotation.Nonnull; -import rx.Observable; +import io.reactivex.Single; import static org.assertj.core.api.Assertions.assertThat; @@ -28,8 +28,8 @@ public void setUp() { .fetcher(new Fetcher() { @Nonnull @Override - public Observable fetch(@Nonnull BarCode barCode) { - return Observable.fromCallable(new Callable() { + public Single fetch(@Nonnull BarCode barCode) { + return Single.fromCallable(new Callable() { @Override public Integer call() { return networkCalls++; @@ -52,8 +52,8 @@ public void sequentially() { @Test public void parallel() { BarCode b = new BarCode("one", "two"); - Observable first = store.get(b); - Observable second = store.get(b); + Single first = store.get(b); + Single second = store.get(b); first.test().awaitTerminalEvent(); second.test().awaitTerminalEvent(); diff --git a/store/src/test/java/com/nytimes/android/external/store/StoreBuilderTest.java b/store/src/test/java/com/nytimes/android/external/store2/StoreBuilderTest.java similarity index 52% rename from store/src/test/java/com/nytimes/android/external/store/StoreBuilderTest.java rename to store/src/test/java/com/nytimes/android/external/store2/StoreBuilderTest.java index 8e045e31..0e9effd8 100644 --- a/store/src/test/java/com/nytimes/android/external/store/StoreBuilderTest.java +++ b/store/src/test/java/com/nytimes/android/external/store2/StoreBuilderTest.java @@ -1,12 +1,12 @@ -package com.nytimes.android.external.store; +package com.nytimes.android.external.store2; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.Parser; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.StoreBuilder; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; import org.junit.Test; @@ -14,7 +14,9 @@ import javax.annotation.Nonnull; -import rx.Observable; +import io.reactivex.Maybe; +import io.reactivex.Single; +import io.reactivex.annotations.NonNull; import static org.assertj.core.api.Assertions.assertThat; @@ -29,26 +31,26 @@ public void testBuildersBuildWithCorrectTypes() { .fetcher(new Fetcher() { @Nonnull @Override - public Observable fetch(@Nonnull Integer key) { - return Observable.just(String.valueOf(key)); + public Single fetch(@Nonnull Integer key) { + return Single.just(String.valueOf(key)); } }) .persister(new Persister() { @Nonnull @Override - public Observable read(@Nonnull Integer key) { - return Observable.just(String.valueOf(key)); + public Maybe read(@Nonnull Integer key) { + return Maybe.just(String.valueOf(key)); } @Nonnull @Override - public Observable write(@Nonnull Integer key, @Nonnull String s) { - return Observable.empty(); + public Single write(@Nonnull Integer key, @Nonnull String s) { + return Single.just(true); } }) .parser(new Parser() { @Override - public Date call(String s) { + public Date apply(@NonNull String s) { return DATE; } }) @@ -58,8 +60,8 @@ public Date call(String s) { Store barCodeStore = StoreBuilder.barcode().fetcher(new Fetcher() { @Nonnull @Override - public Observable fetch(@Nonnull BarCode barCode) { - return Observable.just(DATE); + public Single fetch(@Nonnull BarCode barCode) { + return Single.just(DATE); } }).open(); @@ -68,14 +70,14 @@ public Observable fetch(@Nonnull BarCode barCode) { .fetcher(new Fetcher() { @Nonnull @Override - public Observable fetch(@Nonnull Integer key) { - return Observable.just(DATE); + public Single fetch(@Nonnull Integer key) { + return Single.just(DATE); } }) .open(); - Date result = store.get(5).toBlocking().first(); - result = barCodeStore.get(new BarCode("test", "5")).toBlocking().first(); - result = keyStore.get(5).toBlocking().first(); + Date result = store.get(5).blockingGet(); + result = barCodeStore.get(new BarCode("test", "5")).blockingGet(); + result = keyStore.get(5).blockingGet(); assertThat(result).isNotNull(); } diff --git a/store/src/test/java/com/nytimes/android/external/store/StoreTest.java b/store/src/test/java/com/nytimes/android/external/store2/StoreTest.java similarity index 65% rename from store/src/test/java/com/nytimes/android/external/store/StoreTest.java rename to store/src/test/java/com/nytimes/android/external/store2/StoreTest.java index 705394ad..e11d6fc7 100644 --- a/store/src/test/java/com/nytimes/android/external/store/StoreTest.java +++ b/store/src/test/java/com/nytimes/android/external/store2/StoreTest.java @@ -1,14 +1,14 @@ -package com.nytimes.android.external.store; +package com.nytimes.android.external.store2; import com.nytimes.android.external.cache.Cache; import com.nytimes.android.external.cache.CacheBuilder; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.RealStore; -import com.nytimes.android.external.store.base.impl.Store; -import com.nytimes.android.external.store.base.impl.StoreBuilder; -import com.nytimes.android.external.store.util.NoopPersister; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.RealStore; +import com.nytimes.android.external.store2.base.impl.Store; +import com.nytimes.android.external.store2.base.impl.StoreBuilder; +import com.nytimes.android.external.store2.util.NoopPersister; import org.junit.Before; import org.junit.Test; @@ -18,10 +18,12 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import rx.Emitter; -import rx.Observable; -import rx.functions.Action1; -import rx.functions.Func2; +import io.reactivex.Maybe; +import io.reactivex.Single; +import io.reactivex.SingleEmitter; +import io.reactivex.SingleOnSubscribe; +import io.reactivex.annotations.NonNull; +import io.reactivex.functions.BiFunction; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.spy; @@ -56,19 +58,19 @@ public void testSimple() { when(fetcher.fetch(barCode)) - .thenReturn(Observable.just(NETWORK)); + .thenReturn(Single.just(NETWORK)); when(persister.read(barCode)) - .thenReturn(Observable.empty()) - .thenReturn(Observable.just(DISK)); + .thenReturn(Maybe.empty()) + .thenReturn(Maybe.just(DISK)); when(persister.write(barCode, NETWORK)) - .thenReturn(Observable.just(true)); + .thenReturn(Single.just(true)); - String value = simpleStore.get(barCode).toBlocking().first(); + String value = simpleStore.get(barCode).blockingGet(); assertThat(value).isEqualTo(DISK); - value = simpleStore.get(barCode).toBlocking().first(); + value = simpleStore.get(barCode).blockingGet(); assertThat(value).isEqualTo(DISK); verify(fetcher, times(1)).fetch(barCode); } @@ -82,38 +84,38 @@ public void testDoubleTap() { .fetcher(fetcher) .open(); - Observable networkObservable = - Observable.fromEmitter(new Action1>() { + Single networkSingle = + Single.create(new SingleOnSubscribe() { @Override - public void call(Emitter emitter) { + public void subscribe(SingleEmitter emitter) { if (counter.incrementAndGet() == 1) { - emitter.onNext(NETWORK); - + emitter.onSuccess(NETWORK); } else { emitter.onError(new RuntimeException("Yo Dawg your inflight is broken")); } } - }, Emitter.BackpressureMode.NONE); + }); + + when(fetcher.fetch(barCode)) - .thenReturn(networkObservable); + .thenReturn(networkSingle); when(persister.read(barCode)) - .thenReturn(Observable.empty()) - .thenReturn(Observable.just(DISK)); + .thenReturn(Maybe.empty()) + .thenReturn(Maybe.just(DISK)); when(persister.write(barCode, NETWORK)) - .thenReturn(Observable.just(true)); + .thenReturn(Single.just(true)); String response = simpleStore.get(barCode).zipWith(simpleStore.get(barCode), - new Func2() { + new BiFunction() { @Override - public String call(String s, String s2) { + public String apply(@NonNull String s, @NonNull String s2) { return "hello"; } }) - .toBlocking() - .first(); + .blockingGet(); assertThat(response).isEqualTo("hello"); verify(fetcher, times(1)).fetch(barCode); } @@ -126,16 +128,16 @@ public void testSubclass() { simpleStore.clear(); when(fetcher.fetch(barCode)) - .thenReturn(Observable.just(NETWORK)); + .thenReturn(Single.just(NETWORK)); when(persister.read(barCode)) - .thenReturn(Observable.empty()) - .thenReturn(Observable.just(DISK)); - when(persister.write(barCode, NETWORK)).thenReturn(Observable.just(true)); + .thenReturn(Maybe.empty()) + .thenReturn(Maybe.just(DISK)); + when(persister.write(barCode, NETWORK)).thenReturn(Single.just(true)); - String value = simpleStore.get(barCode).toBlocking().first(); + String value = simpleStore.get(barCode).blockingGet(); assertThat(value).isEqualTo(DISK); - value = simpleStore.get(barCode).toBlocking().first(); + value = simpleStore.get(barCode).blockingGet(); assertThat(value).isEqualTo(DISK); verify(fetcher, times(1)).fetch(barCode); } @@ -149,16 +151,16 @@ public void testNoopAndDefault() { when(fetcher.fetch(barCode)) - .thenReturn(Observable.just(NETWORK)); + .thenReturn(Single.just(NETWORK)); - String value = simpleStore.get(barCode).toBlocking().first(); + String value = simpleStore.get(barCode).blockingGet(); verify(fetcher, times(1)).fetch(barCode); verify(persister, times(1)).write(barCode, NETWORK); verify(persister, times(2)).read(barCode); assertThat(value).isEqualTo(NETWORK); - value = simpleStore.get(barCode).toBlocking().first(); + value = simpleStore.get(barCode).blockingGet(); verify(persister, times(2)).read(barCode); verify(persister, times(1)).write(barCode, NETWORK); verify(fetcher, times(1)).fetch(barCode); diff --git a/store/src/test/java/com/nytimes/android/external/store/StoreWithParserTest.java b/store/src/test/java/com/nytimes/android/external/store2/StoreWithParserTest.java similarity index 55% rename from store/src/test/java/com/nytimes/android/external/store/StoreWithParserTest.java rename to store/src/test/java/com/nytimes/android/external/store2/StoreWithParserTest.java index cab9500d..29292b10 100644 --- a/store/src/test/java/com/nytimes/android/external/store/StoreWithParserTest.java +++ b/store/src/test/java/com/nytimes/android/external/store2/StoreWithParserTest.java @@ -1,17 +1,19 @@ -package com.nytimes.android.external.store; +package com.nytimes.android.external.store2; -import com.nytimes.android.external.store.base.Fetcher; -import com.nytimes.android.external.store.base.Parser; -import com.nytimes.android.external.store.base.Persister; -import com.nytimes.android.external.store.base.impl.BarCode; -import com.nytimes.android.external.store.base.impl.ParsingStoreBuilder; -import com.nytimes.android.external.store.base.impl.Store; +import com.nytimes.android.external.store2.base.Fetcher; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.base.Persister; +import com.nytimes.android.external.store2.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.ParsingStoreBuilder; +import com.nytimes.android.external.store2.base.impl.Store; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import rx.Observable; + +import io.reactivex.Maybe; +import io.reactivex.Single; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.times; @@ -32,7 +34,7 @@ public class StoreWithParserTest { private final BarCode barCode = new BarCode("key", "value"); @Test - public void testSimple() { + public void testSimple() throws Exception { MockitoAnnotations.initMocks(this); @@ -43,45 +45,45 @@ public void testSimple() { .open(); when(fetcher.fetch(barCode)) - .thenReturn(Observable.just(NETWORK)); + .thenReturn(Single.just(NETWORK)); when(persister.read(barCode)) - .thenReturn(Observable.empty()) - .thenReturn(Observable.just(DISK)); + .thenReturn(Maybe.empty()) + .thenReturn(Maybe.just(DISK)); when(persister.write(barCode, NETWORK)) - .thenReturn(Observable.just(true)); + .thenReturn(Single.just(true)); - when(parser.call(DISK)).thenReturn(barCode.getKey()); + when(parser.apply(DISK)).thenReturn(barCode.getKey()); - String value = simpleStore.get(barCode).toBlocking().first(); + String value = simpleStore.get(barCode).blockingGet(); assertThat(value).isEqualTo(barCode.getKey()); - value = simpleStore.get(barCode).toBlocking().first(); + value = simpleStore.get(barCode).blockingGet(); assertThat(value).isEqualTo(barCode.getKey()); verify(fetcher, times(1)).fetch(barCode); } @Test - public void testSubclass() { + public void testSubclass() throws Exception { MockitoAnnotations.initMocks(this); Store simpleStore = new SampleParsingStore(fetcher, persister, parser); when(fetcher.fetch(barCode)) - .thenReturn(Observable.just(NETWORK)); + .thenReturn(Single.just(NETWORK)); when(persister.read(barCode)) - .thenReturn(Observable.empty()) - .thenReturn(Observable.just(DISK)); + .thenReturn(Maybe.empty()) + .thenReturn(Maybe.just(DISK)); when(persister.write(barCode, NETWORK)) - .thenReturn(Observable.just(true)); + .thenReturn(Single.just(true)); - when(parser.call(DISK)).thenReturn(barCode.getKey()); + when(parser.apply(DISK)).thenReturn(barCode.getKey()); - String value = simpleStore.get(barCode).toBlocking().first(); + String value = simpleStore.get(barCode).blockingGet(); assertThat(value).isEqualTo(barCode.getKey()); - value = simpleStore.get(barCode).toBlocking().first(); + value = simpleStore.get(barCode).blockingGet(); assertThat(value).isEqualTo(barCode.getKey()); verify(fetcher, times(1)).fetch(barCode); } diff --git a/store/src/test/java/com/nytimes/android/external/store/base/impl/MultiParserTest.java b/store/src/test/java/com/nytimes/android/external/store2/base/impl/MultiParserTest.java similarity index 75% rename from store/src/test/java/com/nytimes/android/external/store/base/impl/MultiParserTest.java rename to store/src/test/java/com/nytimes/android/external/store2/base/impl/MultiParserTest.java index ef5a7f27..5479cbd2 100644 --- a/store/src/test/java/com/nytimes/android/external/store/base/impl/MultiParserTest.java +++ b/store/src/test/java/com/nytimes/android/external/store2/base/impl/MultiParserTest.java @@ -1,9 +1,9 @@ -package com.nytimes.android.external.store.base.impl; +package com.nytimes.android.external.store2.base.impl; -import com.nytimes.android.external.store.base.Parser; -import com.nytimes.android.external.store.util.KeyParser; -import com.nytimes.android.external.store.util.NoKeyParser; -import com.nytimes.android.external.store.util.ParserException; +import com.nytimes.android.external.store2.base.Parser; +import com.nytimes.android.external.store2.util.KeyParser; +import com.nytimes.android.external.store2.util.NoKeyParser; +import com.nytimes.android.external.store2.util.ParserException; import org.junit.Rule; import org.junit.Test; @@ -19,21 +19,21 @@ public class MultiParserTest { private static final Parser PARSER_1 = new Parser() { @Override - public String call(Integer value) { + public String apply(Integer value) { return String.valueOf(value); } }; private static final Parser PARSER_2 = new Parser() { @Override - public BarCode call(String value) { + public BarCode apply(String value) { return new BarCode(value, "KEY"); } }; private static final Parser PARSER_3 = new Parser() { @Override - public UUID call(BarCode barCode) { + public UUID apply(BarCode barCode) { return UUID.randomUUID(); } }; @@ -49,7 +49,7 @@ public void shouldParseChainProperly() { parsersChain.add(new NoKeyParser<>(PARSER_3)); KeyParser parser = new MultiParser<>(parsersChain); - UUID parsed = parser.call(new Object(), 100); + UUID parsed = parser.apply(new Object(), 100); assertNotNull(parsed); } @@ -64,7 +64,7 @@ public void shouldFailIfOneOfParsersIsInvalid() { parsersChain.add(new NoKeyParser<>(PARSER_2)); KeyParser parser = new MultiParser<>(parsersChain); - UUID parsed = parser.call(new Object(), 100); + UUID parsed = parser.apply(new Object(), 100); assertNotNull(parsed); } diff --git a/store/src/test/java/com/nytimes/android/external/store/base/impl/RepeatWhenEmitsTest.java b/store/src/test/java/com/nytimes/android/external/store2/base/impl/RepeatWhenEmitsTest.java similarity index 79% rename from store/src/test/java/com/nytimes/android/external/store/base/impl/RepeatWhenEmitsTest.java rename to store/src/test/java/com/nytimes/android/external/store2/base/impl/RepeatWhenEmitsTest.java index e9e83ba1..ab1dc100 100644 --- a/store/src/test/java/com/nytimes/android/external/store/base/impl/RepeatWhenEmitsTest.java +++ b/store/src/test/java/com/nytimes/android/external/store2/base/impl/RepeatWhenEmitsTest.java @@ -1,12 +1,12 @@ -package com.nytimes.android.external.store.base.impl; +package com.nytimes.android.external.store2.base.impl; import org.junit.Test; import java.util.concurrent.Callable; -import rx.Observable; -import rx.observers.AssertableSubscriber; -import rx.subjects.PublishSubject; +import io.reactivex.Observable; +import io.reactivex.observers.TestObserver; +import io.reactivex.subjects.PublishSubject; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -25,7 +25,7 @@ public void testTransformer() throws Exception { // create an observable and apply the transformer to test PublishSubject source = PublishSubject.create(); - AssertableSubscriber testSubscriber = Observable.fromCallable(mockCallable) + TestObserver testSubscriber = Observable.fromCallable(mockCallable) .compose(RepeatWhenEmits.from(source)) .test(); diff --git a/store/src/test/java/com/nytimes/android/external/store/util/NoopPersisterTest.java b/store/src/test/java/com/nytimes/android/external/store2/util/NoopPersisterTest.java similarity index 68% rename from store/src/test/java/com/nytimes/android/external/store/util/NoopPersisterTest.java rename to store/src/test/java/com/nytimes/android/external/store2/util/NoopPersisterTest.java index 6e374db6..5e805b28 100644 --- a/store/src/test/java/com/nytimes/android/external/store/util/NoopPersisterTest.java +++ b/store/src/test/java/com/nytimes/android/external/store2/util/NoopPersisterTest.java @@ -1,6 +1,6 @@ -package com.nytimes.android.external.store.util; +package com.nytimes.android.external.store2.util; -import com.nytimes.android.external.store.base.impl.BarCode; +import com.nytimes.android.external.store2.base.impl.BarCode; import org.junit.Test; @@ -12,11 +12,10 @@ public class NoopPersisterTest { @Test public void writeReadTest() { - NoopPersister persister = NoopPersister.create(); - boolean success = persister.write(barCode, "foo").toBlocking().first(); + boolean success = persister.write(barCode, "foo").blockingGet(); assertThat(success).isTrue(); - String rawValue = persister.read(barCode).toBlocking().first(); + String rawValue = persister.read(barCode).blockingGet(); assertThat(rawValue).isEqualTo("foo"); } @@ -24,7 +23,7 @@ public void writeReadTest() { public void noopParserFuncTest() { NoopParserFunc noopParserFunc = new NoopParserFunc<>(); String input = "foo"; - String output = (String) noopParserFunc.call(input); + String output = (String) noopParserFunc.apply(input); assertThat(input).isEqualTo(output); //intended object ref comparison assertThat(input).isSameAs(output);