Skip to content
This repository has been archived by the owner on Aug 9, 2020. It is now read-only.

Commit

Permalink
Merge pull request #39 from VictorAlbertos/decouple_gson
Browse files Browse the repository at this point in the history
Decouple gson
  • Loading branch information
VictorAlbertos authored Jun 18, 2016
2 parents ffb588b + 2491d87 commit e2c91b2
Show file tree
Hide file tree
Showing 29 changed files with 188 additions and 197 deletions.
30 changes: 22 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,27 @@ allprojects {
And add next dependencies in the build.gradle of the module:
```gradle
dependencies {
compile "com.github.VictorAlbertos.RxCache:core:1.4.8"
compile "com.github.VictorAlbertos.RxCache:core:1.5.0"
compile "io.reactivex:rxjava:1.1.5"
}
```

Because RxCache uses internally [Jolyglot](https://github.com/VictorAlbertos/Jolyglot) to serialize and deserialize objects, you need to add the next dependency to gradle in case you want RxCache uses Gson as its json library.
```gradle
dependencies {
compile 'com.github.VictorAlbertos.Jolyglot:gson:0.0.1'
}
```

If you prefer that RxCache uses Jackson, add this other dependency:
```gradle
dependencies {
compile 'com.github.VictorAlbertos.Jolyglot:jackson:0.0.1'
}
```

Moshi is not supported for now.

## Usage

Define an `interface` with as much methods as needed to create the caching providers:
Expand Down Expand Up @@ -94,7 +110,7 @@ Finally, instantiate the Providers `interface` using `RxCache.Builder` and suppl
```java
File cacheDir = getFilesDir();
Providers providers = new RxCache.Builder()
.persistence(cacheDir)
.persistence(cacheDir, new GsonSpeaker())
.using(Providers.class);
```

Expand All @@ -116,7 +132,7 @@ public class Repository {

public Repository(File cacheDir) {
providers = new RxCache.Builder()
.persistence(cacheDir)
.persistence(cacheDir, new GsonSpeaker())
.using(Providers.class);
}

Expand All @@ -140,14 +156,12 @@ public class Repository {
}
```


## Use cases

* Using classic API RxCache for read actions with little write needs.
* Using actionable API RxCache, exclusive for write actions.


## Classic API RxCache:

Following use cases illustrate some common scenarios which will help to understand the usage of `DynamicKey` and `DynamicKeyGroup` classes along with evicting scopes.

### List
Expand Down Expand Up @@ -255,7 +269,7 @@ apply plugin: 'com.neenbedankt.android-apt'
dependencies {
// apt command comes from the android-apt plugin
apt "com.github.VictorAlbertos.RxCache:compiler:1.4.8"
apt "com.github.VictorAlbertos.RxCache:compiler:1.5.0"
}
```

Expand Down Expand Up @@ -444,7 +458,7 @@ You can check an [example](https://github.com/VictorAlbertos/RxCacheSamples/blob
RxCache serves the data from one of its three layers:

* A memory layer -> Powered by [Apache ReferenceMap](https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/map/ReferenceMap.html).
* A persisting layer -> RxCache uses internally [Gson](https://github.com/google/gson) for serialize and deserialize objects.
* A persisting layer -> RxCache uses internally [Jolyglot](https://github.com/VictorAlbertos/Jolyglot) for serialize and deserialize objects.
* A loader layer (the observable supplied by the client library)

The policy is very simple:
Expand Down
1 change: 1 addition & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':core')
apt project(':compiler')
compile 'com.github.VictorAlbertos.Jolyglot:gson:0.0.1'

testCompile 'junit:junit:4.12'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.List;

import io.rx_cache.internal.RxCache;
import io.victoralbertos.jolyglot.GsonSpeaker;
import rx.Observable;

/**
Expand All @@ -22,7 +23,7 @@ public class MainActivity extends Activity {

final RxProviders rxProviders = new RxCache.Builder()
.setMaxMBPersistenceCache(50)
.persistence(getApplicationContext().getFilesDir())
.persistence(getApplicationContext().getFilesDir(), new GsonSpeaker())
.using(RxProviders.class);

/* for (int i = 0; i < 1000; i++) {
Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ buildscript {
allprojects {
repositories {
jcenter()
maven { url 'https://jitpack.io' }
}
}

Expand Down
8 changes: 5 additions & 3 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,16 @@ artifacts {
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])

apt "com.google.dagger:dagger-compiler:2.4"
compile "com.google.dagger:dagger:2.4"
compile "org.glassfish:javax.annotation:10.0-b28"

compile "io.reactivex:rxjava:1.1.5"
compile 'com.google.code.gson:gson:2.5'
compile 'com.github.VictorAlbertos.Jolyglot:api:0.0.1'

testCompile 'com.github.VictorAlbertos.Jolyglot:gson:0.0.1'
testCompile 'com.github.VictorAlbertos.Jolyglot:jackson:0.0.1'
testCompile 'com.github.VictorAlbertos.Jolyglot:moshi:0.0.1'

testCompile "junit:junit:4.12"
}
117 changes: 27 additions & 90 deletions core/src/main/java/io/rx_cache/internal/Disk.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

package io.rx_cache.internal;

import com.google.gson.Gson;
import com.google.gson.internal.$Gson$Types;

import java.io.BufferedReader;
import java.io.File;
Expand All @@ -34,17 +32,20 @@
import javax.inject.Inject;

import io.rx_cache.internal.encrypt.FileEncryptor;
import io.victoralbertos.jolyglot.Jolyglot;

/**
* Save objects in disk and evict them too. It uses Gson as json parser.
*/
public final class Disk implements Persistence {
private final File cacheDirectory;
private final FileEncryptor fileEncryptor;
private final Jolyglot jolyglot;

@Inject public Disk(File cacheDirectory, FileEncryptor fileEncryptor) {
@Inject public Disk(File cacheDirectory, FileEncryptor fileEncryptor, Jolyglot jolyglot) {
this.cacheDirectory = cacheDirectory;
this.fileEncryptor = fileEncryptor;
this.jolyglot = jolyglot;
}

/** Save in disk the Record passed.
Expand Down Expand Up @@ -100,7 +101,7 @@ public final class Disk implements Persistence {
* @param encryptKey The key used to encrypt/decrypt the record to be persisted. See {@link io.rx_cache.EncryptKey}
* */
public void save(String key, Object data, boolean isEncrypted, String encryptKey) {
String wrapperJSONSerialized = new Gson().toJson(data);
String wrapperJSONSerialized = jolyglot.toJson(data);
FileWriter fileWriter = null;

try {
Expand All @@ -115,7 +116,7 @@ public void save(String key, Object data, boolean isEncrypted, String encryptKey
fileEncryptor.encrypt(encryptKey, new File(cacheDirectory, key));

} catch (Exception e) {
throw new RuntimeException(e.getMessage());
throw new RuntimeException(e);
} finally {
try {
if (fileWriter != null) {
Expand Down Expand Up @@ -152,32 +153,18 @@ public void save(String key, Object data, boolean isEncrypted, String encryptKey
* */
public <T> T retrieve(String key, final Class<T> clazz, boolean isEncrypted, String encryptKey) {
File file = new File(cacheDirectory, key);
BufferedReader bufferedReader = null;

if (isEncrypted)
file = fileEncryptor.decrypt(encryptKey, file);

try {
bufferedReader = new BufferedReader(new FileReader(file.getAbsoluteFile()));
T data = new Gson().fromJson(bufferedReader, clazz);

if (isEncrypted)
file.delete();

T data = jolyglot.fromJson(file, clazz);
return data;
} catch (Exception ignore) {
return null;
} finally {
if (isEncrypted)
file.delete();

try {
if (bufferedReader != null) {
bufferedReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

Expand All @@ -187,19 +174,18 @@ public <T> T retrieve(String key, final Class<T> clazz, boolean isEncrypted, Str
* @param encryptKey The key used to encrypt/decrypt the record to be persisted. See {@link io.rx_cache.EncryptKey}
* */
@Override public <T> Record<T> retrieveRecord(String key, boolean isEncrypted, String encryptKey) {
BufferedReader readerTempRecord = null;
BufferedReader reader = null;
File file = new File(cacheDirectory, key);

try {
if (isEncrypted)
file = fileEncryptor.decrypt(encryptKey, file);

readerTempRecord = new BufferedReader(new FileReader(file.getAbsoluteFile()));
Record tempDiskRecord = new Gson().fromJson(readerTempRecord, Record.class);
readerTempRecord.close();
/* Scanner scanner = new Scanner(file);
String text = scanner.useDelimiter("\\A").next();
scanner.close();*/

Record tempDiskRecord = jolyglot.fromJson(file, Record.class);

reader = new BufferedReader(new FileReader(file.getAbsoluteFile()));
Class classData = Class.forName(tempDiskRecord.getDataClassName());
Class classCollectionData = tempDiskRecord.getDataCollectionClassName() == null
? Object.class : Class.forName(tempDiskRecord.getDataCollectionClassName());
Expand All @@ -210,20 +196,20 @@ public <T> T retrieve(String key, final Class<T> clazz, boolean isEncrypted, Str
Record<T> diskRecord;

if (isCollection) {
Type typeCollection = $Gson$Types.newParameterizedTypeWithOwner(null, classCollectionData, classData);
Type typeRecord = $Gson$Types.newParameterizedTypeWithOwner(null, Record.class, typeCollection, classData);
diskRecord = new Gson().fromJson(reader, typeRecord);
Type typeCollection = jolyglot.newParameterizedType(classCollectionData, classData);
Type typeRecord = jolyglot.newParameterizedType(Record.class, typeCollection);
diskRecord = jolyglot.fromJson(file.getAbsoluteFile(), typeRecord);
} else if (isArray) {
Type typeRecord = $Gson$Types.newParameterizedTypeWithOwner(null, Record.class, classCollectionData);
diskRecord = new Gson().fromJson(reader, typeRecord);
Type typeRecord = jolyglot.newParameterizedType(Record.class, classCollectionData);
diskRecord = jolyglot.fromJson(file.getAbsoluteFile(), typeRecord);
} else if (isMap) {
Class classKeyMap = Class.forName(tempDiskRecord.getDataKeyMapClassName());
Type typeMap = $Gson$Types.newParameterizedTypeWithOwner(null, classCollectionData, classKeyMap, classData);
Type typeRecord = $Gson$Types.newParameterizedTypeWithOwner(null, Record.class, typeMap, classData);
diskRecord = new Gson().fromJson(reader, typeRecord);
Type typeMap = jolyglot.newParameterizedType(classCollectionData, classKeyMap, classData);
Type typeRecord = jolyglot.newParameterizedType(Record.class, typeMap);
diskRecord = jolyglot.fromJson(file.getAbsoluteFile(), typeRecord);
} else {
Type type = $Gson$Types.newParameterizedTypeWithOwner(null, Record.class, classData);
diskRecord = new Gson().fromJson(reader, type);
Type type = jolyglot.newParameterizedType(Record.class, classData);
diskRecord = jolyglot.fromJson(file.getAbsoluteFile(), type);
}

diskRecord.setSizeOnMb(file.length()/1024f/1024f);
Expand All @@ -232,17 +218,6 @@ public <T> T retrieve(String key, final Class<T> clazz, boolean isEncrypted, Str
} catch (Exception ignore) {
return null;
} finally {
try {
if (readerTempRecord != null) {
readerTempRecord.close();
}
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}

if (isEncrypted)
file.delete();
}
Expand Down Expand Up @@ -280,27 +255,13 @@ private String getFileContent(File file) {
* @param classData type class contained by the collection, not the collection itself
* */
public <C extends Collection<T>, T> C retrieveCollection(String key, Class<C> classCollection, Class<T> classData) {
BufferedReader reader = null;

try {
File file = new File(cacheDirectory, key);
reader = new BufferedReader(new FileReader(file.getAbsoluteFile()));

Type typeCollection = $Gson$Types.newParameterizedTypeWithOwner(null, classCollection, classData);
T data = new Gson().fromJson(reader, typeCollection);

Type typeCollection = jolyglot.newParameterizedType(classCollection, classData);
T data = jolyglot.fromJson(file, typeCollection);
return (C) data;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

Expand All @@ -311,27 +272,15 @@ public <C extends Collection<T>, T> C retrieveCollection(String key, Class<C> cl
* @param classMapValue type class of the Map value
* */
public <M extends Map<K,V>, K, V> M retrieveMap(String key, Class classMap, Class<K> classMapKey, Class<V> classMapValue) {
BufferedReader reader = null;

try {
File file = new File(cacheDirectory, key);
reader = new BufferedReader(new FileReader(file.getAbsoluteFile()));

Type typeMap = $Gson$Types.newParameterizedTypeWithOwner(null, classMap, classMapKey, classMapValue);
Object data = new Gson().fromJson(reader, typeMap);
Type typeMap = jolyglot.newParameterizedType(classMap, classMapKey, classMapValue);
Object data = jolyglot.fromJson(file, typeMap);

return (M) data;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

Expand All @@ -340,27 +289,15 @@ public <M extends Map<K,V>, K, V> M retrieveMap(String key, Class classMap, Clas
* @param classData type class contained by the Array
* */
public <T> T[] retrieveArray(String key, Class<T> classData) {
BufferedReader reader = null;

try {
File file = new File(cacheDirectory, key);
reader = new BufferedReader(new FileReader(file.getAbsoluteFile()));

Class<?> clazzArray = Array.newInstance(classData, 1).getClass();
Object data = new Gson().fromJson(reader, clazzArray);
Object data = jolyglot.fromJson(file, clazzArray);

return (T[]) data;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/io/rx_cache/internal/Locale.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public interface Locale {
String INVALID_RETURN_TYPE = " needs to return an Observable<T> or Observable<Reply<T>>" ;
String NOT_DATA_RETURN_WHEN_CALLING_OBSERVABLE_LOADER = "The Loader provided did not return any data and there is not data to load from the Cache";
String REPOSITORY_DISK_ADAPTER_CAN_NOT_BE_NULL = "File cache directory can not be null";
String PERSISTENCE_CAN_NOT_BE_NULL = "Persistence can not be null";
String JSON_CONVERTER_CAN_NOT_BE_NULL = "JsonConverter can not be null";
String NOT_OBSERVABLE_LOADER_FOUND = " requires an instance of type observable";
String JUST_ONE_INSTANCE = " requires just one instance of type ";
String EVICT_DYNAMIC_KEY_PROVIDED_BUT_NOT_PROVIDED_ANY_DYNAMIC_KEY = " EvictDynamicKey was provided but not was provided any DynamicKey";
Expand Down
Loading

0 comments on commit e2c91b2

Please sign in to comment.