├── dualcache-demoapp ├── .gitignore ├── src │ └── main │ │ ├── res │ │ ├── drawable-hdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-mdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-xhdpi │ │ │ └── ic_launcher.png │ │ ├── drawable-xxhdpi │ │ │ └── ic_launcher.png │ │ ├── values │ │ │ ├── styles.xml │ │ │ ├── dimens.xml │ │ │ └── strings.xml │ │ ├── values-w820dp │ │ │ └── dimens.xml │ │ └── layout │ │ │ ├── activity_settings.xml │ │ │ └── activity_demo.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── vincentbrison │ │ └── openlibraries │ │ └── android │ │ └── dualcache │ │ ├── SettingsActivity.java │ │ └── DemoActivity.java ├── proguard │ └── proguard-project.pro └── build.gradle ├── dualcache-library ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ └── values │ │ │ │ └── strings.xml │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── com │ │ │ └── vincentbrison │ │ │ └── openlibraries │ │ │ └── android │ │ │ └── dualcache │ │ │ ├── DualCacheDiskMode.java │ │ │ ├── SizeOf.java │ │ │ ├── DualCacheRamMode.java │ │ │ ├── LoggerHelper.java │ │ │ ├── ReferenceLruCache.java │ │ │ ├── DualCacheLock.java │ │ │ ├── StringLruCache.java │ │ │ ├── Logger.java │ │ │ ├── Builder.java │ │ │ ├── DualCache.java │ │ │ └── RamLruCache.java │ └── androidTest │ │ └── java │ │ └── com │ │ └── vincentbrison │ │ └── openlibraries │ │ └── android │ │ └── dualcache │ │ └── lib │ │ ├── testobjects │ │ ├── AbstractCar.java │ │ ├── CoolCar.java │ │ ├── CoolBike.java │ │ ├── AbstractMotorBike.java │ │ └── AbstractVehicule.java │ │ ├── configurationsToTest │ │ ├── RamReferenceNoDisk.java │ │ ├── RamDefaultSerializerNoDisk.java │ │ ├── RamCustomSerializerNoDisk.java │ │ ├── NoRamDiskDefaultSerializer.java │ │ ├── RamReferenceDiskDefaultSerializer.java │ │ ├── RamDefaultSerializerDiskDefaultSerializer.java │ │ ├── RamCustomSerializerDiskCustomSerializer.java │ │ ├── RamCustomSerializerDiskDefaultSerializer.java │ │ ├── RamDefaultSerializerDiskCustomSerializer.java │ │ ├── RamReferenceDiskCustomSerializer.java │ │ └── NoRamDiskCustomSerializer.java │ │ ├── TestIssue11.java │ │ └── DualCacheTest.java ├── proguard-rules.txt ├── gradle.properties └── build.gradle ├── dualcache-jsonserializer ├── .gitignore ├── build.gradle ├── gradle.properties └── src │ └── main │ └── java │ └── com │ └── vincentbrison │ └── openlibraries │ └── android │ └── dualcache │ └── JsonSerializer.java ├── dualcache-serializerinterface ├── .gitignore ├── build.gradle ├── gradle.properties └── src │ └── main │ └── java │ └── com │ └── vincentbrison │ └── openlibraries │ └── android │ └── dualcache │ └── CacheSerializer.java ├── .gitignore ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── doc-assets ├── dualcache-serializer.png └── dualcache-serializer-ref.png ├── settings.gradle ├── gradle.properties ├── .travis.yml ├── upload.sh ├── dependencies.gradle ├── quality ├── checkstyle │ ├── suppressions.xml │ └── checkstyle.xml ├── findbugs │ └── findbugs-filter.xml ├── pmd │ └── pmd-ruleset.xml ├── quality.gradle └── lint │ └── lint.xml ├── gradlew.bat ├── maven_push_java.gradle ├── maven_push.gradle ├── gradlew ├── README.md └── LICENSE.txt /dualcache-demoapp/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /dualcache-library/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /dualcache-jsonserializer/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /dualcache-serializerinterface/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | .idea 4 | **/*.iml 5 | .DS_Store 6 | /build 7 | 8 | *.hprof 9 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vincentbrison/dualcache/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /doc-assets/dualcache-serializer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vincentbrison/dualcache/HEAD/doc-assets/dualcache-serializer.png -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':dualcache-demoapp', ':dualcache-library', ':dualcache-serializerinterface', ':dualcache-jsonserializer' 2 | -------------------------------------------------------------------------------- /doc-assets/dualcache-serializer-ref.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vincentbrison/dualcache/HEAD/doc-assets/dualcache-serializer-ref.png -------------------------------------------------------------------------------- /dualcache-library/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | DualCacheLib 3 | 4 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | VERSION_NAME=3.1.1 2 | VERSION_CODE=1 3 | GROUP=com.vincentbrison.openlibraries.android 4 | 5 | org.gradle.jvmargs=-Xmx1536M 6 | -------------------------------------------------------------------------------- /dualcache-demoapp/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vincentbrison/dualcache/HEAD/dualcache-demoapp/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /dualcache-demoapp/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vincentbrison/dualcache/HEAD/dualcache-demoapp/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /dualcache-demoapp/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vincentbrison/dualcache/HEAD/dualcache-demoapp/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /dualcache-demoapp/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vincentbrison/dualcache/HEAD/dualcache-demoapp/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /dualcache-serializerinterface/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | apply from: '../maven_push_java.gradle' 3 | 4 | dependencies { 5 | sourceCompatibility = project.javaVersion 6 | targetCompatibility = project.javaVersion 7 | } 8 | -------------------------------------------------------------------------------- /dualcache-demoapp/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /dualcache-demoapp/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Nov 26 21:25:44 CET 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 7 | -------------------------------------------------------------------------------- /dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/testobjects/AbstractCar.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache.lib.testobjects; 2 | 3 | public abstract class AbstractCar extends AbstractVehicule { 4 | 5 | public AbstractCar() { 6 | mWheels = 4; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /dualcache-library/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/testobjects/CoolCar.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache.lib.testobjects; 2 | 3 | public class CoolCar extends AbstractCar { 4 | public CoolCar() { 5 | super(); 6 | mName = CoolCar.class.getSimpleName(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/testobjects/CoolBike.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache.lib.testobjects; 2 | 3 | public class CoolBike extends AbstractMotorBike { 4 | public CoolBike() { 5 | super(); 6 | mName = CoolBike.class.getSimpleName(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | jdk: 3 | - oraclejdk8 4 | android: 5 | components: 6 | - tools 7 | - platform-tools 8 | - build-tools-25.0.1 9 | - android-25 10 | - extra-google-m2repository 11 | - extra-android-m2repository 12 | 13 | script: 14 | - ./gradlew clean 15 | - ./gradlew dualcache-library:check -Ptravis 16 | -------------------------------------------------------------------------------- /dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/testobjects/AbstractMotorBike.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache.lib.testobjects; 2 | 3 | 4 | public abstract class AbstractMotorBike extends AbstractVehicule { 5 | 6 | public AbstractMotorBike() { 7 | mWheels = 2; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /dualcache-demoapp/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DualCacheDemo 5 | Settings 6 | Hello world! 7 | Settings 8 | 9 | 10 | -------------------------------------------------------------------------------- /upload.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | read -s -p "Sonatype pwd ?" sonatypePwd 3 | read -s -p "Key pwd ?" keyPwd 4 | ./gradlew dualcache-library:uploadArchives -PsonatypePwd=$sonatypePwd -PkeyPwd=$keyPwd 5 | ./gradlew dualcache-jsonserializer:uploadArchives -PsonatypePwd=$sonatypePwd -PkeyPwd=$keyPwd 6 | ./gradlew dualcache-serializerinterface:uploadArchives -PsonatypePwd=$sonatypePwd -PkeyPwd=$keyPwd 7 | -------------------------------------------------------------------------------- /dualcache-jsonserializer/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | apply from: '../maven_push_java.gradle' 3 | 4 | dependencies { 5 | compile "com.fasterxml.jackson.core:jackson-databind:${jacksonDatabindVersion}" 6 | compile project(path: ':dualcache-serializerinterface') 7 | 8 | sourceCompatibility = project.javaVersion 9 | targetCompatibility = project.javaVersion 10 | } 11 | -------------------------------------------------------------------------------- /dependencies.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | compileSdkVersion = 25 3 | buildToolsVersion = '25.0.1' 4 | minSdkVersion = 12 5 | targetSdkVersion = 25 6 | 7 | javaVersion = 1.7 8 | 9 | diskLruVersion = '2.0.2' 10 | jacksonDatabindVersion = '2.4.2' 11 | 12 | androidSupportTestRunner = '0.5' 13 | 14 | dualcacheVersion = '3.1.1' 15 | 16 | butterknifeVersion = '8.4.0' 17 | } 18 | -------------------------------------------------------------------------------- /dualcache-demoapp/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/DualCacheDiskMode.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache; 2 | 3 | /** 4 | * Define the behaviour of the disk layer. 5 | */ 6 | public enum DualCacheDiskMode { 7 | /** 8 | * Means that object will be serialized with a specific serializer in disk. 9 | */ 10 | ENABLE_WITH_SPECIFIC_SERIALIZER, 11 | 12 | /** 13 | * The disk layer is not used. 14 | */ 15 | DISABLE 16 | } 17 | -------------------------------------------------------------------------------- /quality/checkstyle/suppressions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /quality/findbugs/findbugs-filter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/SizeOf.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache; 2 | 3 | /** 4 | * Interface used to describe how to compute the size of an object in RAM. 5 | * @param is the class of object on which this computation is done. 6 | */ 7 | public interface SizeOf { 8 | 9 | /** 10 | * Compute the amount of RAM in bytes used by this object. 11 | * @param object is the instance against the computation has to be done. 12 | * @return the size in bytes of the object in RAM. 13 | */ 14 | int sizeOf(T object); 15 | } 16 | -------------------------------------------------------------------------------- /dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/DualCacheRamMode.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache; 2 | 3 | /** 4 | * Define the behaviour of the RAM layer. 5 | */ 6 | public enum DualCacheRamMode { 7 | /** 8 | * Means that object will be serialized with a specific serializer in RAM. 9 | */ 10 | ENABLE_WITH_SPECIFIC_SERIALIZER, 11 | 12 | /** 13 | * Means that only references to objects will be stored in the RAM layer. 14 | */ 15 | ENABLE_WITH_REFERENCE, 16 | 17 | /** 18 | * The RAM layer is not used. 19 | */ 20 | DISABLE 21 | } 22 | -------------------------------------------------------------------------------- /dualcache-jsonserializer/gradle.properties: -------------------------------------------------------------------------------- 1 | VERSION_CODE=1 2 | 3 | POM_DESCRIPTION=Json serializer for Android Dual Cache 4 | POM_URL=https://github.com/vincentbrison/android-dual-cache 5 | POM_SCM_URL=https://github.com/vincentbrison/android-dual-cache 6 | POM_SCM_CONNECTION=scm:git@github.com:vincentbrison/android-dual-cache.git 7 | POM_SCM_DEV_CONNECTION=scm:git@github.com:vincentbrison/android-dual-cache.git 8 | POM_LICENCE_NAME=The Apache Software License, Version 2.0 9 | POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt 10 | POM_LICENCE_DIST=repo 11 | POM_DEVELOPER_ID=vbrison 12 | POM_DEVELOPER_NAME=Vincent Brison 13 | POM_NAME=Android Dual Cache 14 | POM_ARTIFACT_ID=dualcache-jsonserializer 15 | POM_PACKAGING=aar 16 | 17 | -------------------------------------------------------------------------------- /dualcache-serializerinterface/gradle.properties: -------------------------------------------------------------------------------- 1 | VERSION_CODE=1 2 | 3 | POM_DESCRIPTION=Json serializer for Android Dual Cache 4 | POM_URL=https://github.com/vincentbrison/android-dual-cache 5 | POM_SCM_URL=https://github.com/vincentbrison/android-dual-cache 6 | POM_SCM_CONNECTION=scm:git@github.com:vincentbrison/android-dual-cache.git 7 | POM_SCM_DEV_CONNECTION=scm:git@github.com:vincentbrison/android-dual-cache.git 8 | POM_LICENCE_NAME=The Apache Software License, Version 2.0 9 | POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt 10 | POM_LICENCE_DIST=repo 11 | POM_DEVELOPER_ID=vbrison 12 | POM_DEVELOPER_NAME=Vincent Brison 13 | POM_NAME=Android Dual Cache 14 | POM_ARTIFACT_ID=dualcache-serializerinterface 15 | POM_PACKAGING=jar 16 | 17 | -------------------------------------------------------------------------------- /dualcache-library/proguard-rules.txt: -------------------------------------------------------------------------------- 1 | # Proguard configuration for Jackson 2.x (fasterxml package instead of codehaus package) 2 | 3 | -keepnames class com.fasterxml.jackson.annotation.** { *; } 4 | -keep public class your.package.with.jackson.pojos.* { 5 | public void set*(*); 6 | public ** get*(); 7 | } 8 | -dontwarn org.w3c.dom.bootstrap.DOMImplementationRegistry 9 | -dontwarn java.beans.Transient 10 | -dontwarn java.beans.ConstructorProperties 11 | 12 | # Not sure if those are needed in other configurations 13 | -keep class com.fasterxml.jackson.databind.ObjectMapper { 14 | public ; 15 | protected ; 16 | } 17 | -keep class com.fasterxml.jackson.databind.ObjectWriter { 18 | public ** writeValueAsString(**); 19 | } 20 | -------------------------------------------------------------------------------- /dualcache-library/gradle.properties: -------------------------------------------------------------------------------- 1 | VERSION_CODE=1 2 | 3 | POM_DESCRIPTION=Dual Cache is an Android library which provide easy to use and effective caching solution for Android. 4 | POM_URL=https://github.com/vincentbrison/android-dual-cache 5 | POM_SCM_URL=https://github.com/vincentbrison/android-dual-cache 6 | POM_SCM_CONNECTION=scm:git@github.com:vincentbrison/android-dual-cache.git 7 | POM_SCM_DEV_CONNECTION=scm:git@github.com:vincentbrison/android-dual-cache.git 8 | POM_LICENCE_NAME=The Apache Software License, Version 2.0 9 | POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt 10 | POM_LICENCE_DIST=repo 11 | POM_DEVELOPER_ID=vbrison 12 | POM_DEVELOPER_NAME=Vincent Brison 13 | POM_NAME=Android Dual Cache 14 | POM_ARTIFACT_ID=dualcache 15 | POM_PACKAGING=aar 16 | 17 | -------------------------------------------------------------------------------- /dualcache-demoapp/proguard/proguard-project.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/tokou/android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | -ignorewarnings 20 | -dontpreverify 21 | -dontoptimize 22 | -------------------------------------------------------------------------------- /dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamReferenceNoDisk.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache.lib.configurationsToTest; 2 | 3 | import com.vincentbrison.openlibraries.android.dualcache.Builder; 4 | import com.vincentbrison.openlibraries.android.dualcache.lib.DualCacheTest; 5 | import com.vincentbrison.openlibraries.android.dualcache.lib.testobjects.AbstractVehicule; 6 | 7 | public class RamReferenceNoDisk extends DualCacheTest { 8 | 9 | @Override 10 | public void setUp() throws Exception { 11 | super.setUp(); 12 | cache = new Builder(CACHE_NAME, TEST_APP_VERSION) 13 | .enableLog() 14 | .useReferenceInRam(RAM_MAX_SIZE, new SizeOfVehiculeForTesting()) 15 | .noDisk() 16 | .build(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamDefaultSerializerNoDisk.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache.lib.configurationsToTest; 2 | 3 | import com.vincentbrison.openlibraries.android.dualcache.Builder; 4 | import com.vincentbrison.openlibraries.android.dualcache.lib.DualCacheTest; 5 | import com.vincentbrison.openlibraries.android.dualcache.lib.testobjects.AbstractVehicule; 6 | 7 | public class RamDefaultSerializerNoDisk extends DualCacheTest { 8 | 9 | @Override 10 | public void setUp() throws Exception { 11 | super.setUp(); 12 | cache = new Builder(CACHE_NAME, TEST_APP_VERSION) 13 | .enableLog() 14 | .useSerializerInRam(RAM_MAX_SIZE, defaultCacheSerializer) 15 | .noDisk() 16 | .build(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dualcache-serializerinterface/src/main/java/com/vincentbrison/openlibraries/android/dualcache/CacheSerializer.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache; 2 | 3 | /** 4 | * This cache interface describe the way an object should be serialized/deserialized into a 5 | * byte array. 6 | * @param is the class of object to serialized/deserialized. 7 | */ 8 | public interface CacheSerializer { 9 | /** 10 | * Deserialization of a String into an object. 11 | * @param data is the byte array representing the serialized data. 12 | * @return the deserialized data. 13 | */ 14 | T fromString(String data); 15 | 16 | /** 17 | * Serialization of an object into String. 18 | * @param object is the object to serialize. 19 | * @return the result of the serialization into a byte array. 20 | */ 21 | String toString(T object); 22 | } 23 | -------------------------------------------------------------------------------- /dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamCustomSerializerNoDisk.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache.lib.configurationsToTest; 2 | 3 | import com.vincentbrison.openlibraries.android.dualcache.Builder; 4 | import com.vincentbrison.openlibraries.android.dualcache.lib.DualCacheTest; 5 | import com.vincentbrison.openlibraries.android.dualcache.lib.testobjects.AbstractVehicule; 6 | 7 | public class RamCustomSerializerNoDisk extends DualCacheTest { 8 | 9 | @Override 10 | public void setUp() throws Exception { 11 | super.setUp(); 12 | cache = new Builder(CACHE_NAME, TEST_APP_VERSION) 13 | .enableLog() 14 | .useSerializerInRam(RAM_MAX_SIZE, new SerializerForTesting()) 15 | .noDisk() 16 | .build(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/NoRamDiskDefaultSerializer.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache.lib.configurationsToTest; 2 | 3 | import com.vincentbrison.openlibraries.android.dualcache.Builder; 4 | import com.vincentbrison.openlibraries.android.dualcache.lib.DualCacheTest; 5 | import com.vincentbrison.openlibraries.android.dualcache.lib.testobjects.AbstractVehicule; 6 | 7 | public class NoRamDiskDefaultSerializer extends DualCacheTest { 8 | 9 | @Override 10 | public void setUp() throws Exception { 11 | super.setUp(); 12 | cache = new Builder(CACHE_NAME, TEST_APP_VERSION) 13 | .enableLog() 14 | .noRam() 15 | .useSerializerInDisk(DISK_MAX_SIZE, true, defaultCacheSerializer, getContext()) 16 | .build(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/testobjects/AbstractVehicule.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache.lib.testobjects; 2 | 3 | public abstract class AbstractVehicule { 4 | protected String mName; 5 | protected int mWheels; 6 | 7 | public String getName() { 8 | return mName; 9 | } 10 | 11 | public int getWheels() { 12 | return mWheels; 13 | } 14 | 15 | @Override 16 | public boolean equals(Object o) { 17 | if (o instanceof AbstractVehicule) { 18 | if (mName.equals(((AbstractVehicule) o).getName()) 19 | && mWheels == ((AbstractVehicule) o).getWheels()) { 20 | return true; 21 | } else { 22 | return false; 23 | } 24 | } else { 25 | return super.equals(o); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamReferenceDiskDefaultSerializer.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache.lib.configurationsToTest; 2 | 3 | import com.vincentbrison.openlibraries.android.dualcache.Builder; 4 | import com.vincentbrison.openlibraries.android.dualcache.lib.DualCacheTest; 5 | import com.vincentbrison.openlibraries.android.dualcache.lib.testobjects.AbstractVehicule; 6 | 7 | public class RamReferenceDiskDefaultSerializer extends DualCacheTest { 8 | 9 | @Override 10 | public void setUp() throws Exception { 11 | super.setUp(); 12 | cache = new Builder(CACHE_NAME, TEST_APP_VERSION) 13 | .enableLog() 14 | .useReferenceInRam(RAM_MAX_SIZE, new SizeOfVehiculeForTesting()) 15 | .useSerializerInDisk(DISK_MAX_SIZE, true, defaultCacheSerializer, getContext()) 16 | .build(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamDefaultSerializerDiskDefaultSerializer.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache.lib.configurationsToTest; 2 | 3 | import com.vincentbrison.openlibraries.android.dualcache.Builder; 4 | import com.vincentbrison.openlibraries.android.dualcache.lib.DualCacheTest; 5 | import com.vincentbrison.openlibraries.android.dualcache.lib.testobjects.AbstractVehicule; 6 | 7 | public class RamDefaultSerializerDiskDefaultSerializer extends DualCacheTest { 8 | 9 | @Override 10 | public void setUp() throws Exception { 11 | super.setUp(); 12 | cache = new Builder(CACHE_NAME, TEST_APP_VERSION) 13 | .enableLog() 14 | .useSerializerInRam(RAM_MAX_SIZE, defaultCacheSerializer) 15 | .useSerializerInDisk(DISK_MAX_SIZE, true, defaultCacheSerializer, getContext()) 16 | .build(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamCustomSerializerDiskCustomSerializer.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache.lib.configurationsToTest; 2 | 3 | import com.vincentbrison.openlibraries.android.dualcache.Builder; 4 | import com.vincentbrison.openlibraries.android.dualcache.lib.DualCacheTest; 5 | import com.vincentbrison.openlibraries.android.dualcache.lib.testobjects.AbstractVehicule; 6 | 7 | public class RamCustomSerializerDiskCustomSerializer extends DualCacheTest { 8 | 9 | @Override 10 | public void setUp() throws Exception { 11 | super.setUp(); 12 | cache = new Builder(CACHE_NAME, TEST_APP_VERSION) 13 | .enableLog() 14 | .useSerializerInRam(RAM_MAX_SIZE, new SerializerForTesting()) 15 | .useSerializerInDisk(DISK_MAX_SIZE, true, new SerializerForTesting(), getContext()) 16 | .build(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamCustomSerializerDiskDefaultSerializer.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache.lib.configurationsToTest; 2 | 3 | import com.vincentbrison.openlibraries.android.dualcache.Builder; 4 | import com.vincentbrison.openlibraries.android.dualcache.lib.DualCacheTest; 5 | import com.vincentbrison.openlibraries.android.dualcache.lib.testobjects.AbstractVehicule; 6 | 7 | public class RamCustomSerializerDiskDefaultSerializer extends DualCacheTest { 8 | 9 | @Override 10 | public void setUp() throws Exception { 11 | super.setUp(); 12 | cache = new Builder(CACHE_NAME, TEST_APP_VERSION) 13 | .enableLog() 14 | .useSerializerInRam(RAM_MAX_SIZE, new SerializerForTesting()) 15 | .useSerializerInDisk(DISK_MAX_SIZE, true, defaultCacheSerializer, getContext()) 16 | .build(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamDefaultSerializerDiskCustomSerializer.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache.lib.configurationsToTest; 2 | 3 | import com.vincentbrison.openlibraries.android.dualcache.Builder; 4 | import com.vincentbrison.openlibraries.android.dualcache.lib.DualCacheTest; 5 | import com.vincentbrison.openlibraries.android.dualcache.lib.testobjects.AbstractVehicule; 6 | 7 | public class RamDefaultSerializerDiskCustomSerializer extends DualCacheTest { 8 | 9 | @Override 10 | public void setUp() throws Exception { 11 | super.setUp(); 12 | cache = new Builder(CACHE_NAME, TEST_APP_VERSION) 13 | .enableLog() 14 | .useSerializerInRam(RAM_MAX_SIZE, defaultCacheSerializer) 15 | .useSerializerInDisk(DISK_MAX_SIZE, true, new SerializerForTesting(), getContext()) 16 | .build(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamReferenceDiskCustomSerializer.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache.lib.configurationsToTest; 2 | 3 | import com.vincentbrison.openlibraries.android.dualcache.Builder; 4 | import com.vincentbrison.openlibraries.android.dualcache.lib.DualCacheTest; 5 | import com.vincentbrison.openlibraries.android.dualcache.lib.testobjects.AbstractVehicule; 6 | 7 | public class RamReferenceDiskCustomSerializer extends DualCacheTest { 8 | 9 | @Override 10 | public void setUp() throws Exception { 11 | super.setUp(); 12 | cache = new Builder(CACHE_NAME, TEST_APP_VERSION) 13 | .enableLog() 14 | .useReferenceInRam(RAM_MAX_SIZE, new SizeOfVehiculeForTesting()) 15 | .useSerializerInDisk(DISK_MAX_SIZE, true, new DualCacheTest.SerializerForTesting(), getContext()) 16 | .build(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/NoRamDiskCustomSerializer.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache.lib.configurationsToTest; 2 | 3 | import com.vincentbrison.openlibraries.android.dualcache.Builder; 4 | import com.vincentbrison.openlibraries.android.dualcache.lib.DualCacheTest; 5 | import com.vincentbrison.openlibraries.android.dualcache.lib.testobjects.AbstractVehicule; 6 | 7 | public class NoRamDiskCustomSerializer extends DualCacheTest { 8 | 9 | @Override 10 | public void setUp() throws Exception { 11 | super.setUp(); 12 | cache = new Builder(CACHE_NAME, TEST_APP_VERSION) 13 | .enableLog() 14 | .noRam() 15 | .useSerializerInDisk( 16 | DISK_MAX_SIZE, 17 | true, 18 | new DualCacheTest.SerializerForTesting(), 19 | getContext()) 20 | .build(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/LoggerHelper.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache; 2 | 3 | class LoggerHelper { 4 | 5 | private static final String LOG_PREFIX = "Entry for "; 6 | 7 | private final Logger logger; 8 | 9 | LoggerHelper(Logger logger) { 10 | this.logger = logger; 11 | } 12 | 13 | void logEntrySavedForKey(String key) { 14 | logger.logInfo(LOG_PREFIX + key + " is saved in cache."); 15 | } 16 | 17 | void logEntryForKeyIsInRam(String key) { 18 | logger.logInfo(LOG_PREFIX + key + " is in RAM."); 19 | } 20 | 21 | void logEntryForKeyIsNotInRam(String key) { 22 | logger.logInfo(LOG_PREFIX + key + " is not in RAM."); 23 | } 24 | 25 | void logEntryForKeyIsOnDisk(String key) { 26 | logger.logInfo(LOG_PREFIX + key + " is on disk."); 27 | } 28 | 29 | void logEntryForKeyIsNotOnDisk(String key) { 30 | logger.logInfo(LOG_PREFIX + key + " is not on disk."); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /dualcache-demoapp/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 14 | 15 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/ReferenceLruCache.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache; 2 | 3 | /** 4 | * This is the LRU cache used for the RAM layer when configured to used references. 5 | * @param is the class of object stored in the cache. 6 | */ 7 | public class ReferenceLruCache extends RamLruCache { 8 | 9 | private SizeOf mHandlerSizeOf; 10 | 11 | /** 12 | * @param maxSize for caches that do not override {@link #sizeOf}, this is 13 | * the maximum number of entries in the cache. For all other caches, 14 | * this is the maximum sum of the sizes of the entries in this cache. 15 | * 16 | * @param handler computes the size of each object stored in the RAM cache layer. 17 | */ 18 | public ReferenceLruCache(int maxSize, SizeOf handler) { 19 | super(maxSize); 20 | mHandlerSizeOf = handler; 21 | } 22 | 23 | @Override 24 | protected int sizeOf(String key, T value) { 25 | return mHandlerSizeOf.sizeOf(value); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/DualCacheLock.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache; 2 | 3 | import java.util.concurrent.ConcurrentHashMap; 4 | import java.util.concurrent.ConcurrentMap; 5 | import java.util.concurrent.locks.Lock; 6 | import java.util.concurrent.locks.ReadWriteLock; 7 | import java.util.concurrent.locks.ReentrantLock; 8 | import java.util.concurrent.locks.ReentrantReadWriteLock; 9 | 10 | class DualCacheLock { 11 | 12 | private final ConcurrentMap editionLocks = new ConcurrentHashMap<>(); 13 | private final ReadWriteLock invalidationReadWriteLock = new ReentrantReadWriteLock(); 14 | 15 | void lockDiskEntryWrite(String key) { 16 | invalidationReadWriteLock.readLock().lock(); 17 | getLockForGivenDiskEntry(key).lock(); 18 | } 19 | 20 | void unLockDiskEntryWrite(String key) { 21 | getLockForGivenDiskEntry(key).unlock(); 22 | invalidationReadWriteLock.readLock().unlock(); 23 | } 24 | 25 | void lockFullDiskWrite() { 26 | invalidationReadWriteLock.writeLock().lock(); 27 | } 28 | 29 | void unLockFullDiskWrite() { 30 | invalidationReadWriteLock.writeLock().unlock(); 31 | } 32 | 33 | private Lock getLockForGivenDiskEntry(String key) { 34 | if (!editionLocks.containsKey(key)) { 35 | editionLocks.putIfAbsent(key, new ReentrantLock()); 36 | } 37 | return editionLocks.get(key); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/StringLruCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Vincent Brison. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.vincentbrison.openlibraries.android.dualcache; 18 | 19 | import java.nio.charset.Charset; 20 | 21 | /** 22 | * LRU cache used by the RAM cache layer when storing serialized object. 23 | */ 24 | class StringLruCache extends RamLruCache { 25 | 26 | /** 27 | * @param maxSize for caches that do not override {@link #sizeOf}, this is 28 | * the maximum number of entries in the cache. For all other caches, 29 | * this is the maximum sum of the sizes of the entries in this cache. 30 | */ 31 | public StringLruCache(int maxSize) { 32 | super(maxSize); 33 | } 34 | 35 | @Override 36 | protected int sizeOf(String key, String value) { 37 | return value.getBytes(Charset.defaultCharset()).length; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /dualcache-library/build.gradle: -------------------------------------------------------------------------------- 1 | import com.android.builder.core.BuilderConstants 2 | 3 | apply plugin: 'com.android.library' 4 | apply from: '../quality/quality.gradle' 5 | apply from: '../maven_push.gradle' 6 | 7 | android { 8 | compileSdkVersion project.compileSdkVersion 9 | buildToolsVersion project.buildToolsVersion 10 | 11 | defaultConfig { 12 | minSdkVersion project.minSdkVersion 13 | targetSdkVersion project.targetSdkVersion 14 | versionCode Integer.parseInt(project.VERSION_CODE) 15 | versionName project.VERSION_NAME 16 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 17 | consumerProguardFiles 'proguard-rules.txt' 18 | } 19 | 20 | packagingOptions { 21 | exclude 'META-INF/LICENSE.txt' 22 | exclude 'META-INF/NOTICE.txt' 23 | exclude 'META-INF/ASL2.0' 24 | exclude 'META-INF/LICENSE' 25 | exclude 'META-INF/NOTICE' 26 | } 27 | } 28 | 29 | dependencies { 30 | compile project (':dualcache-serializerinterface') 31 | compile "com.jakewharton:disklrucache:${project.diskLruVersion}" 32 | 33 | androidTestCompile "com.android.support.test:runner:${project.androidSupportTestRunner}" 34 | androidTestCompile project (':dualcache-jsonserializer') 35 | } 36 | 37 | android.libraryVariants.all { variant -> 38 | def name = variant.buildType.name 39 | if (name.equals(BuilderConstants.DEBUG)) { 40 | return; // Skip debug builds. 41 | } 42 | def task = project.tasks.create "jar${name.capitalize()}", Jar 43 | task.dependsOn variant.javaCompile 44 | task.from variant.javaCompile.destinationDir 45 | artifacts.add('archives', task); 46 | } 47 | -------------------------------------------------------------------------------- /dualcache-jsonserializer/src/main/java/com/vincentbrison/openlibraries/android/dualcache/JsonSerializer.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache; 2 | 3 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 4 | import com.fasterxml.jackson.annotation.PropertyAccessor; 5 | import com.fasterxml.jackson.core.JsonProcessingException; 6 | import com.fasterxml.jackson.databind.ObjectMapper; 7 | 8 | import java.io.IOException; 9 | 10 | /** 11 | * Serializer which will serialize and deserialize object using Jackson 12 | * converter. 13 | * @param is the class of object to serialize/deserialize. 14 | */ 15 | public class JsonSerializer implements CacheSerializer { 16 | private final ObjectMapper mapper; 17 | private final Class clazz; 18 | 19 | /** 20 | * Default constructor. 21 | * @param clazz is the class of object to serialize/deserialize. 22 | */ 23 | public JsonSerializer(Class clazz) { 24 | this.clazz = clazz; 25 | mapper = new ObjectMapper(); 26 | mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE); 27 | mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); 28 | mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 29 | } 30 | 31 | @Override 32 | public T fromString(String data) { 33 | try { 34 | return mapper.readValue(data, clazz); 35 | } catch (IOException e) { 36 | e.printStackTrace(); 37 | } 38 | throw new IllegalStateException(); 39 | } 40 | 41 | @Override 42 | public String toString(T object) { 43 | try { 44 | return mapper.writeValueAsString(object); 45 | } catch (JsonProcessingException e) { 46 | e.printStackTrace(); 47 | } 48 | throw new IllegalStateException(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /dualcache-demoapp/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'com.neenbedankt.android-apt' 3 | apply from: '../quality/quality.gradle' 4 | 5 | android { 6 | compileSdkVersion project.compileSdkVersion 7 | buildToolsVersion project.buildToolsVersion 8 | 9 | defaultConfig { 10 | minSdkVersion project.minSdkVersion 11 | targetSdkVersion project.targetSdkVersion 12 | versionCode Integer.parseInt(project.VERSION_CODE) 13 | versionName project.VERSION_NAME 14 | } 15 | productFlavors { 16 | local 17 | remote 18 | } 19 | buildTypes { 20 | proguard { 21 | initWith debug 22 | minifyEnabled true 23 | proguardFiles getDefaultProguardFile('proguard-android.txt') 24 | proguardFiles getProguardConfigForLibraries() 25 | } 26 | } 27 | 28 | packagingOptions { 29 | exclude 'META-INF/services/javax.annotation.processing.Processor' 30 | exclude 'META-INF/LICENSE.txt' 31 | exclude 'META-INF/NOTICE.txt' 32 | exclude 'META-INF/ASL2.0' 33 | exclude 'META-INF/LICENSE' 34 | exclude 'META-INF/NOTICE' 35 | } 36 | } 37 | 38 | dependencies { 39 | localCompile project(path: ':dualcache-library') 40 | localCompile project(path: ':dualcache-jsonserializer') 41 | 42 | remoteCompile "com.vincentbrison.openlibraries.android:dualcache:${project.dualcacheVersion}" 43 | remoteCompile "com.vincentbrison.openlibraries.android:dualcache-jsonserializer:${project.dualcacheVersion}" 44 | 45 | apt "com.jakewharton:butterknife-compiler:${project.butterknifeVersion}" 46 | compile "com.jakewharton:butterknife:${project.butterknifeVersion}" 47 | } 48 | 49 | private Object[] getProguardConfigForLibraries() { 50 | // Get library specific files from here: 51 | // https://github.com/krschultz/android-proguard-snippets/tree/master/libraries 52 | // Adding .asList().toArray() as a workaround for this issue 53 | // https://code.google.com/p/android/issues/detail?id=212882 54 | fileTree(dir: 'proguard', include: ['*.pro']).asList().toArray() 55 | } 56 | -------------------------------------------------------------------------------- /quality/pmd/pmd-ruleset.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 22 | 23 | Custom ruleset for Android application 24 | 25 | .*/R.java 26 | .*/gen/.* 27 | .*/RamLruCache.java 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /quality/quality.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'checkstyle' 2 | apply plugin: 'findbugs' 3 | apply plugin: 'pmd' 4 | 5 | // Add checkstyle, findbugs, pmd and lint to the check task. 6 | check.dependsOn 'checkstyle', 'findbugs', 'pmd', 'lint' 7 | 8 | task checkstyle(type: Checkstyle) { 9 | configFile file("${project.rootDir}/quality/checkstyle/checkstyle.xml") 10 | configProperties.checkstyleSuppressionsPath = file("${project.rootDir}/quality/checkstyle/suppressions.xml").absolutePath 11 | source 'src/main/java' 12 | include '**/*.java' 13 | exclude '**/gen/**' 14 | 15 | classpath = files() 16 | } 17 | 18 | 19 | task findbugs(type: FindBugs, dependsOn: "assembleDebug") { 20 | ignoreFailures = false 21 | effort = "max" 22 | reportLevel = "high" 23 | excludeFilter = new File("${project.rootDir}/quality/findbugs/findbugs-filter.xml") 24 | classes = files("${project.rootDir}/dualcache-library/build/intermediates/classes") 25 | 26 | source 'src/main/java' 27 | include '**/*.java' 28 | exclude '**/gen/**' 29 | 30 | reports { 31 | xml.enabled = false 32 | html.enabled = true 33 | xml { 34 | destination "$project.buildDir/reports/findbugs/findbugs.xml" 35 | } 36 | html { 37 | destination "$project.buildDir/reports/findbugs/findbugs.html" 38 | } 39 | } 40 | 41 | classpath = files() 42 | } 43 | 44 | task pmd(type: Pmd) { 45 | ruleSetFiles = files("${project.rootDir}/quality/pmd/pmd-ruleset.xml") 46 | ignoreFailures = false 47 | ruleSets = [] 48 | 49 | source 'src/main/java' 50 | include '**/*.java' 51 | exclude '**/gen/**' 52 | 53 | reports { 54 | xml.enabled = false 55 | html.enabled = true 56 | xml { 57 | destination "$project.buildDir/reports/pmd/pmd.xml" 58 | } 59 | html { 60 | destination "$project.buildDir/reports/pmd/pmd.html" 61 | } 62 | } 63 | } 64 | 65 | 66 | android { 67 | lintOptions { 68 | abortOnError true 69 | 70 | lintConfig file("${project.rootDir}/quality/lint/lint.xml") 71 | 72 | // if true, generate an HTML report (with issue explanations, sourcecode, etc) 73 | htmlReport true 74 | // optional path to report (default will be lint-results.html in the builddir) 75 | htmlOutput file("$project.buildDir/reports/lint/lint.html") 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /dualcache-demoapp/src/main/java/com/vincentbrison/openlibraries/android/dualcache/SettingsActivity.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.Button; 8 | import android.widget.EditText; 9 | 10 | import com.vb.openlibraries.android.dualcache.R; 11 | 12 | import butterknife.BindView; 13 | import butterknife.ButterKnife; 14 | 15 | /** 16 | * This activity ask user input to configure the demo. 17 | */ 18 | public class SettingsActivity extends Activity { 19 | 20 | //CHECKSTYLE:OFF 21 | @BindView(R.id.activity_settings_edittext_ram_cache_size) protected EditText mEditTextSizeRam; 22 | @BindView(R.id.activity_settings_edittext_disk_cache_size) protected EditText mEditTextSizeDisk; 23 | @BindView(R.id.activity_settings_edittext_cache_id) protected EditText mEditTextIdCache; 24 | @BindView(R.id.activity_settings_button_demo) protected Button mButtonDemo; 25 | //CHECKSTYLE:ON 26 | 27 | @Override 28 | protected void onCreate(Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | 31 | setContentView(R.layout.activity_settings); 32 | ButterKnife.bind(this); 33 | 34 | mButtonDemo.setOnClickListener(new View.OnClickListener() { 35 | @Override 36 | public void onClick(View view) { 37 | Intent intent = new Intent(SettingsActivity.this, DemoActivity.class); 38 | intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); 39 | 40 | intent.putExtra( 41 | DemoActivity.EXTRA_DISK_CACHE_SIZE, 42 | tryGetNumber(mEditTextSizeDisk, 100) 43 | ); 44 | intent.putExtra( 45 | DemoActivity.EXTRA_RAM_CACHE_SIZE, 46 | tryGetNumber(mEditTextSizeRam, 50) 47 | ); 48 | intent.putExtra(DemoActivity.EXTRA_ID_CACHE, mEditTextIdCache.getText().toString()); 49 | startActivity(intent); 50 | } 51 | }); 52 | } 53 | 54 | private int tryGetNumber(EditText editText, int defaultValue) { 55 | try { 56 | return Integer.parseInt(editText.getText().toString()); 57 | } catch (NumberFormatException exception) { 58 | return defaultValue; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/Logger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 Vincent Brison. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.vincentbrison.openlibraries.android.dualcache; 18 | 19 | import android.util.Log; 20 | 21 | /** 22 | * This class provide a logging instance to the library. 23 | */ 24 | final class Logger { 25 | 26 | private static final String DEFAULT_LOG_TAG = "dualcache"; 27 | private final boolean isLogEnable; 28 | 29 | Logger(boolean isLogEnable) { 30 | this.isLogEnable = isLogEnable; 31 | } 32 | 33 | private void log(int lvl, String tag, String msg) { 34 | if (isLogEnable) { 35 | Log.println(lvl, tag, msg); 36 | } 37 | } 38 | 39 | /** 40 | * Log with level info. 41 | * @param tag is the tag to used. 42 | * @param msg is the msg to log. 43 | */ 44 | void logInfo(String tag, String msg) { 45 | log(Log.INFO, tag, msg); 46 | } 47 | 48 | /** 49 | * Default log info using tag {@link #DEFAULT_LOG_TAG}. 50 | * @param msg is the msg to log. 51 | */ 52 | void logInfo(String msg) { 53 | log(Log.INFO, DEFAULT_LOG_TAG, msg); 54 | } 55 | 56 | /** 57 | * Log with level verbose and tag {@link #DEFAULT_LOG_TAG}. 58 | * @param msg is the msg to log. 59 | */ 60 | void logVerbose(String msg) { 61 | log(Log.VERBOSE, DEFAULT_LOG_TAG, msg); 62 | } 63 | 64 | /** 65 | * Log with level warning and tag {@link #DEFAULT_LOG_TAG}. 66 | * @param msg is the msg to log. 67 | */ 68 | void logWarning(String msg) { 69 | log(Log.WARN, DEFAULT_LOG_TAG, msg); 70 | } 71 | 72 | /** 73 | * Log with level error and tag {@link #DEFAULT_LOG_TAG}. 74 | * @param error is the error to log. 75 | */ 76 | void logError(Throwable error) { 77 | if (isLogEnable) { 78 | Log.e(DEFAULT_LOG_TAG, "error : ", error); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /maven_push_java.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'maven' 2 | apply plugin: 'signing' 3 | 4 | def safePwd(String name) { 5 | def safeVar 6 | if (!project.hasProperty(name)) { 7 | safeVar = "" 8 | } else { 9 | safeVar = project.getProperties().get(name) 10 | } 11 | return safeVar 12 | } 13 | 14 | def sonatypeRepositoryUrl 15 | if (isReleaseBuild()) { 16 | println 'RELEASE BUILD' 17 | sonatypeRepositoryUrl = hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL 18 | : "https://oss.sonatype.org/service/local/staging/deploy/maven2/" 19 | } else { 20 | println 'SNAPSHOT BUILD' 21 | sonatypeRepositoryUrl = hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL 22 | : "https://oss.sonatype.org/content/repositories/snapshots/" 23 | 24 | } 25 | 26 | afterEvaluate { project -> 27 | uploadArchives { 28 | repositories { 29 | mavenDeployer { 30 | beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } 31 | 32 | pom.groupId = GROUP 33 | pom.artifactId = POM_ARTIFACT_ID 34 | pom.version = VERSION_NAME 35 | 36 | repository(url: sonatypeRepositoryUrl) { 37 | authentication(userName: "vbrison", password: safePwd("sonatypePwd")) 38 | } 39 | 40 | pom.project { 41 | name POM_NAME 42 | packaging POM_PACKAGING 43 | description POM_DESCRIPTION 44 | url POM_URL 45 | 46 | scm { 47 | url POM_SCM_URL 48 | connection POM_SCM_CONNECTION 49 | developerConnection POM_SCM_DEV_CONNECTION 50 | } 51 | 52 | licenses { 53 | license { 54 | name POM_LICENCE_NAME 55 | url POM_LICENCE_URL 56 | distribution POM_LICENCE_DIST 57 | } 58 | } 59 | 60 | developers { 61 | developer { 62 | id POM_DEVELOPER_ID 63 | name POM_DEVELOPER_NAME 64 | } 65 | } 66 | } 67 | } 68 | } 69 | } 70 | 71 | signing { 72 | allprojects { 73 | ext."signing.password" = safePwd("keyPwd") 74 | ext."signing.keyId" = "D376F8F6" 75 | //ext."signing.secretKeyRingFile" = "C:/Users/Brize/AppData/Roaming/gnupg/secring.gpg" 76 | ext."signing.secretKeyRingFile" = "/Users/vincentbrison/.gnupg/secring.gpg" 77 | } 78 | required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") } 79 | sign configurations.archives 80 | } 81 | 82 | task javadocsJar(type: Jar) { 83 | classifier = 'javadoc' 84 | from javadoc 85 | } 86 | 87 | task sourceJar (type : Jar) { 88 | classifier = 'sources' 89 | from sourceSets.main.allSource 90 | } 91 | 92 | artifacts { 93 | archives javadocsJar 94 | archives sourceJar 95 | } 96 | } 97 | 98 | -------------------------------------------------------------------------------- /maven_push.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'maven' 2 | apply plugin: 'signing' 3 | 4 | def safePwd(String name) { 5 | def safeVar 6 | if (!project.hasProperty(name)) { 7 | safeVar = "" 8 | } else { 9 | safeVar = project.getProperties().get(name) 10 | } 11 | return safeVar 12 | } 13 | 14 | def sonatypeRepositoryUrl 15 | if (isReleaseBuild()) { 16 | println 'RELEASE BUILD' 17 | sonatypeRepositoryUrl = hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL 18 | : "https://oss.sonatype.org/service/local/staging/deploy/maven2/" 19 | } else { 20 | println 'SNAPSHOT BUILD' 21 | sonatypeRepositoryUrl = hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL 22 | : "https://oss.sonatype.org/content/repositories/snapshots/" 23 | 24 | } 25 | 26 | afterEvaluate { project -> 27 | uploadArchives { 28 | repositories { 29 | mavenDeployer { 30 | beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } 31 | 32 | pom.groupId = GROUP 33 | pom.artifactId = POM_ARTIFACT_ID 34 | pom.version = VERSION_NAME 35 | 36 | repository(url: sonatypeRepositoryUrl) { 37 | authentication(userName: "vbrison", password: safePwd("sonatypePwd")) 38 | } 39 | 40 | pom.project { 41 | name POM_NAME 42 | packaging POM_PACKAGING 43 | description POM_DESCRIPTION 44 | url POM_URL 45 | 46 | scm { 47 | url POM_SCM_URL 48 | connection POM_SCM_CONNECTION 49 | developerConnection POM_SCM_DEV_CONNECTION 50 | } 51 | 52 | licenses { 53 | license { 54 | name POM_LICENCE_NAME 55 | url POM_LICENCE_URL 56 | distribution POM_LICENCE_DIST 57 | } 58 | } 59 | 60 | developers { 61 | developer { 62 | id POM_DEVELOPER_ID 63 | name POM_DEVELOPER_NAME 64 | } 65 | } 66 | } 67 | } 68 | } 69 | } 70 | 71 | signing { 72 | allprojects { 73 | ext."signing.password" = safePwd("keyPwd") 74 | ext."signing.keyId" = "D376F8F6" 75 | //ext."signing.secretKeyRingFile" = "C:/Users/Brize/AppData/Roaming/gnupg/secring.gpg" 76 | ext."signing.secretKeyRingFile" = "/Users/vincentbrison/.gnupg/secring.gpg" 77 | } 78 | required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") } 79 | sign configurations.archives 80 | } 81 | 82 | task androidJavadocs(type: Javadoc) { 83 | source = android.sourceSets.main.java.srcDirs 84 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 85 | } 86 | 87 | task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) { 88 | classifier = 'javadoc' 89 | from androidJavadocs.destinationDir 90 | } 91 | 92 | task androidSourcesJar(type: Jar) { 93 | classifier = 'sources' 94 | from android.sourceSets.main.java.sourceFiles 95 | } 96 | 97 | artifacts { 98 | archives androidSourcesJar 99 | archives androidJavadocsJar 100 | } 101 | } 102 | 103 | -------------------------------------------------------------------------------- /dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/TestIssue11.java: -------------------------------------------------------------------------------- 1 | package com.vincentbrison.openlibraries.android.dualcache.lib; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import com.vincentbrison.openlibraries.android.dualcache.Builder; 8 | import com.vincentbrison.openlibraries.android.dualcache.CacheSerializer; 9 | import com.vincentbrison.openlibraries.android.dualcache.DualCache; 10 | import com.vincentbrison.openlibraries.android.dualcache.JsonSerializer; 11 | 12 | import org.junit.After; 13 | import org.junit.Before; 14 | import org.junit.Test; 15 | import org.junit.runner.RunWith; 16 | 17 | import java.io.File; 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | 21 | import static org.junit.Assert.assertFalse; 22 | 23 | /** 24 | * Test issue 11. 25 | */ 26 | @RunWith(AndroidJUnit4.class) 27 | public class TestIssue11 { 28 | private static final int CACHE_SIZE = 10 * 1024 * 1024; // 10 MB 29 | private static final int CACHE_RAM_ENTRIES = 25; 30 | protected static final String CACHE_NAME = "test"; 31 | protected static final int TEST_APP_VERSION = 0; 32 | protected DualCache mCache; 33 | 34 | @Before 35 | public void setUp() throws Exception { 36 | Context context = InstrumentationRegistry.getTargetContext(); 37 | File cacheDir = new File(context.getCacheDir(), CACHE_NAME); 38 | CacheSerializer jsonSerializer = new JsonSerializer<>(String.class); 39 | mCache = new Builder(CACHE_NAME, 0) 40 | .enableLog() 41 | .useSerializerInRam(CACHE_RAM_ENTRIES, jsonSerializer) 42 | .useSerializerInDisk(CACHE_SIZE, cacheDir, jsonSerializer) 43 | .build(); 44 | } 45 | 46 | @After 47 | public void tearDown() throws Exception { 48 | mCache.invalidate(); 49 | } 50 | 51 | @Test 52 | public void testConcurrentAccess() { 53 | List threads = new ArrayList<>(); 54 | for (int i = 0; i < 10; i++) { 55 | threads.add(createWrokerThread(mCache)); 56 | } 57 | for (Thread thread : threads) { 58 | thread.start(); 59 | } 60 | 61 | for (Thread thread : threads) { 62 | try { 63 | thread.join(); 64 | } catch (InterruptedException e) { 65 | e.printStackTrace(); 66 | } 67 | } 68 | assertFalse("test", false); 69 | } 70 | 71 | private Thread createWrokerThread(final DualCache cache) { 72 | return new Thread() { 73 | int sMaxNumberOfRun = 1000; 74 | @Override 75 | public void run() { 76 | try { 77 | int numberOfRun = 0; 78 | while (numberOfRun++ < sMaxNumberOfRun) { 79 | Thread.sleep((long) (Math.random() * 2)); 80 | double choice = Math.random(); 81 | if (choice < 0.4) { 82 | cache.put("key", "test"); 83 | } else if (choice < 0.5) { 84 | cache.delete("key"); 85 | } else if (choice < 0.8) { 86 | cache.get("key"); 87 | } else if (choice < 1) { 88 | cache.invalidate(); 89 | } else { 90 | // do nothing 91 | } 92 | } 93 | } catch (InterruptedException e) { 94 | e.printStackTrace(); 95 | } 96 | } 97 | }; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /dualcache-demoapp/src/main/res/layout/activity_settings.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 17 | 18 | 33 | 34 | 43 | 44 | 58 | 59 | 68 | 69 | 82 | 83 |