diff --git a/paperdb/build.gradle b/paperdb/build.gradle index 682b014..3a221cc 100644 --- a/paperdb/build.gradle +++ b/paperdb/build.gradle @@ -37,6 +37,7 @@ dependencies { androidTestCompile 'com.orhanobut:hawk:1.14' androidTestCompile 'com.android.support.test:runner:0.3' androidTestCompile 'com.squareup.assertj:assertj-android:1.0.0' + androidTestCompile 'joda-time:joda-time:2.9.1' } apply from: '../publish.gradle' diff --git a/paperdb/src/androidTest/java/io/paperdb/PaperTest.java b/paperdb/src/androidTest/java/io/paperdb/PaperTest.java index 6b9ac23..9cf1f83 100644 --- a/paperdb/src/androidTest/java/io/paperdb/PaperTest.java +++ b/paperdb/src/androidTest/java/io/paperdb/PaperTest.java @@ -2,15 +2,18 @@ import android.support.test.runner.AndroidJUnit4; +import org.joda.time.DateTime; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.util.List; +import de.javakaffee.kryoserializers.jodatime.JodaDateTimeSerializer; import io.paperdb.testdata.TestDataGenerator; import static android.support.test.InstrumentationRegistry.getTargetContext; +import static junit.framework.Assert.assertEquals; import static junit.framework.TestCase.assertTrue; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertFalse; @@ -167,5 +170,13 @@ public void testGetAllKeys() { assertThat(allKeys.contains("city1")).isTrue(); assertThat(allKeys.contains("city2")).isTrue(); } - + + @Test + public void testCustomSerializer() { + Paper.addSerializer(DateTime.class, new JodaDateTimeSerializer()); + + DateTime now = DateTime.now(); + Paper.book().write("joda-datetime", now); + assertEquals(Paper.book().read("joda-datetime"), now); + } } \ No newline at end of file diff --git a/paperdb/src/main/java/io/paperdb/Book.java b/paperdb/src/main/java/io/paperdb/Book.java index 5429e3e..fd3c887 100644 --- a/paperdb/src/main/java/io/paperdb/Book.java +++ b/paperdb/src/main/java/io/paperdb/Book.java @@ -1,15 +1,17 @@ package io.paperdb; import android.content.Context; +import com.esotericsoftware.kryo.Serializer; +import java.util.HashMap; import java.util.List; public class Book { private final Storage mStorage; - protected Book(Context context, String dbName) { - mStorage = new DbStoragePlainFile(context.getApplicationContext(), dbName); + protected Book(Context context, String dbName, HashMap serializers) { + mStorage = new DbStoragePlainFile(context.getApplicationContext(), dbName, serializers); } /** diff --git a/paperdb/src/main/java/io/paperdb/DbStoragePlainFile.java b/paperdb/src/main/java/io/paperdb/DbStoragePlainFile.java index dc3dd6e..9226020 100644 --- a/paperdb/src/main/java/io/paperdb/DbStoragePlainFile.java +++ b/paperdb/src/main/java/io/paperdb/DbStoragePlainFile.java @@ -5,6 +5,7 @@ import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryo.KryoException; +import com.esotericsoftware.kryo.Serializer; import com.esotericsoftware.kryo.io.Input; import com.esotericsoftware.kryo.io.Output; import com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer; @@ -16,12 +17,14 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.UUID; import de.javakaffee.kryoserializers.ArraysAsListSerializer; import de.javakaffee.kryoserializers.SynchronizedCollectionsSerializer; +import de.javakaffee.kryoserializers.UUIDSerializer; import de.javakaffee.kryoserializers.UnmodifiableCollectionsSerializer; import io.paperdb.serializer.NoArgCollectionSerializer; @@ -31,6 +34,7 @@ public class DbStoragePlainFile implements Storage { private final Context mContext; private final String mDbName; + private final HashMap mCustomSerializers; private String mFilesDir; private boolean mPaperDirIsCreated; @@ -65,12 +69,22 @@ private Kryo createKryoInstance() { new NoArgCollectionSerializer()); // To keep backward compatibility don't change the order of serializers above + // UUID support + kryo.register(UUID.class, new UUIDSerializer()); + + for (Class clazz : mCustomSerializers.keySet()) + kryo.register(clazz, mCustomSerializers.get(clazz)); + return kryo; } - public DbStoragePlainFile(Context context, String dbName) { + public DbStoragePlainFile( + Context context, + String dbName, + HashMap serializers) { mContext = context; mDbName = dbName; + mCustomSerializers = serializers; } @Override diff --git a/paperdb/src/main/java/io/paperdb/Paper.java b/paperdb/src/main/java/io/paperdb/Paper.java index 05e03c0..ef0cc0a 100644 --- a/paperdb/src/main/java/io/paperdb/Paper.java +++ b/paperdb/src/main/java/io/paperdb/Paper.java @@ -4,6 +4,9 @@ import android.content.Context; import android.os.Bundle; +import com.esotericsoftware.kryo.Serializer; + +import java.util.HashMap; import java.util.concurrent.ConcurrentHashMap; /** @@ -26,6 +29,7 @@ public class Paper { private static Context mContext; private static final ConcurrentHashMap mBookMap = new ConcurrentHashMap<>(); + private static final HashMap mCustomSerializers = new HashMap<>(); /** * Lightweight method to init Paper instance. Should be executed in {@link Application#onCreate()} @@ -66,7 +70,7 @@ private static Book getBook(String name) { synchronized (mBookMap) { Book book = mBookMap.get(name); if (book == null) { - book = new Book(mContext, name); + book = new Book(mContext, name, mCustomSerializers); mBookMap.put(name, book); } return book; @@ -116,4 +120,17 @@ public static void clear(Context context) { init(context); book().destroy(); } + + /** + * Add a custom serializer for a class without no-arg constructor. + * When used, must be called right after Paper.init() + * + * @param clazz type of the custom serializer + * @param serializer the serializer instance + * @param type of the serializer + */ + public static void addSerializer(Class clazz, Serializer serializer) { + if (!mCustomSerializers.containsKey(clazz)) + mCustomSerializers.put(clazz, serializer); + } }