Hide implementation under typealias.
Though it is not working for java interop. Signed-off-by: Yahor Berdnikau <egorr.berd@gmail.com>
This commit is contained in:
parent
8076956786
commit
72743346dc
|
@ -6,6 +6,8 @@ import com.twitter.serial.stream.Serial
|
||||||
import com.twitter.serial.stream.bytebuffer.ByteBufferSerial
|
import com.twitter.serial.stream.bytebuffer.ByteBufferSerial
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
typealias DomainEntitySerializer<T> = Serializer<T>
|
||||||
|
|
||||||
internal const val STORAGE_DIR_NAME = "persistent_storage"
|
internal const val STORAGE_DIR_NAME = "persistent_storage"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,7 +16,7 @@ internal const val STORAGE_DIR_NAME = "persistent_storage"
|
||||||
* [serverId] is currently active server. Should be unique per server so stored data will not
|
* [serverId] is currently active server. Should be unique per server so stored data will not
|
||||||
* interfere with other server data.
|
* interfere with other server data.
|
||||||
*
|
*
|
||||||
* Look at [org.moire.ultrasonic.cache.serializers] package for available [Serializer]s.
|
* Look at [org.moire.ultrasonic.cache.serializers] package for available [DomainEntitySerializer]s.
|
||||||
*/
|
*/
|
||||||
class PermanentFileStorage(
|
class PermanentFileStorage(
|
||||||
private val directories: Directories,
|
private val directories: Directories,
|
||||||
|
@ -34,7 +36,7 @@ class PermanentFileStorage(
|
||||||
fun <T> store(
|
fun <T> store(
|
||||||
name: String,
|
name: String,
|
||||||
objectToStore: T,
|
objectToStore: T,
|
||||||
objectSerializer: Serializer<T>
|
objectSerializer: DomainEntitySerializer<T>
|
||||||
) {
|
) {
|
||||||
val storeFile = getFile(name)
|
val storeFile = getFile(name)
|
||||||
if (!storeFile.exists()) storeFile.createNewFile()
|
if (!storeFile.exists()) storeFile.createNewFile()
|
||||||
|
@ -46,7 +48,7 @@ class PermanentFileStorage(
|
||||||
*/
|
*/
|
||||||
fun <T> load(
|
fun <T> load(
|
||||||
name: String,
|
name: String,
|
||||||
objectDeserializer: Serializer<T>
|
objectDeserializer: DomainEntitySerializer<T>
|
||||||
): T? {
|
): T? {
|
||||||
val storeFile = getFile(name)
|
val storeFile = getFile(name)
|
||||||
if (!storeFile.exists()) return null
|
if (!storeFile.exists()) return null
|
||||||
|
|
|
@ -8,14 +8,12 @@ import com.twitter.serial.serializer.SerializationContext
|
||||||
import com.twitter.serial.stream.SerializerDefs
|
import com.twitter.serial.stream.SerializerDefs
|
||||||
import com.twitter.serial.stream.SerializerInput
|
import com.twitter.serial.stream.SerializerInput
|
||||||
import com.twitter.serial.stream.SerializerOutput
|
import com.twitter.serial.stream.SerializerOutput
|
||||||
|
import org.moire.ultrasonic.cache.DomainEntitySerializer
|
||||||
import org.moire.ultrasonic.domain.Artist
|
import org.moire.ultrasonic.domain.Artist
|
||||||
|
|
||||||
private const val SERIALIZER_VERSION = 1
|
private const val SERIALIZER_VERSION = 1
|
||||||
|
|
||||||
/**
|
private val artistSerializer get() = object : ObjectSerializer<Artist>(SERIALIZER_VERSION) {
|
||||||
* Serializer/deserializer for [Artist] domain entity.
|
|
||||||
*/
|
|
||||||
val artistSerializer get() = object : ObjectSerializer<Artist>(SERIALIZER_VERSION) {
|
|
||||||
override fun serializeObject(
|
override fun serializeObject(
|
||||||
context: SerializationContext,
|
context: SerializationContext,
|
||||||
output: SerializerOutput<out SerializerOutput<*>>,
|
output: SerializerOutput<out SerializerOutput<*>>,
|
||||||
|
@ -54,7 +52,14 @@ val artistSerializer get() = object : ObjectSerializer<Artist>(SERIALIZER_VERSIO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializer/deserializer for [Artist] domain entity.
|
||||||
|
*/
|
||||||
|
fun getArtistsSerializer(): DomainEntitySerializer<Artist> = artistSerializer
|
||||||
|
|
||||||
|
private val artistListSerializer = CollectionSerializers.getListSerializer(artistSerializer)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serializer/deserializer for list of [Artist] domain entities.
|
* Serializer/deserializer for list of [Artist] domain entities.
|
||||||
*/
|
*/
|
||||||
val artistListSerializer = CollectionSerializers.getListSerializer(artistSerializer)
|
fun getArtistListSerializer(): DomainEntitySerializer<List<Artist>> = artistListSerializer
|
||||||
|
|
|
@ -2,28 +2,27 @@
|
||||||
@file:JvmName("DomainSerializers")
|
@file:JvmName("DomainSerializers")
|
||||||
package org.moire.ultrasonic.cache.serializers
|
package org.moire.ultrasonic.cache.serializers
|
||||||
|
|
||||||
import com.twitter.serial.serializer.CollectionSerializers
|
|
||||||
import com.twitter.serial.serializer.ObjectSerializer
|
import com.twitter.serial.serializer.ObjectSerializer
|
||||||
import com.twitter.serial.serializer.SerializationContext
|
import com.twitter.serial.serializer.SerializationContext
|
||||||
import com.twitter.serial.stream.SerializerInput
|
import com.twitter.serial.stream.SerializerInput
|
||||||
import com.twitter.serial.stream.SerializerOutput
|
import com.twitter.serial.stream.SerializerOutput
|
||||||
|
import org.moire.ultrasonic.cache.DomainEntitySerializer
|
||||||
import org.moire.ultrasonic.domain.Artist
|
import org.moire.ultrasonic.domain.Artist
|
||||||
import org.moire.ultrasonic.domain.Indexes
|
import org.moire.ultrasonic.domain.Indexes
|
||||||
|
|
||||||
private const val SERIALIZATION_VERSION = 1
|
private const val SERIALIZATION_VERSION = 1
|
||||||
|
|
||||||
val indexesSerializer get() = object : ObjectSerializer<Indexes>(SERIALIZATION_VERSION) {
|
private val indexesSerializer get() = object : ObjectSerializer<Indexes>(SERIALIZATION_VERSION) {
|
||||||
override fun serializeObject(
|
override fun serializeObject(
|
||||||
context: SerializationContext,
|
context: SerializationContext,
|
||||||
output: SerializerOutput<out SerializerOutput<*>>,
|
output: SerializerOutput<out SerializerOutput<*>>,
|
||||||
item: Indexes
|
item: Indexes
|
||||||
) {
|
) {
|
||||||
|
val artistListSerializer = getArtistListSerializer()
|
||||||
output.writeLong(item.lastModified)
|
output.writeLong(item.lastModified)
|
||||||
.writeString(item.ignoredArticles)
|
.writeString(item.ignoredArticles)
|
||||||
.writeObject<MutableList<Artist>>(context, item.shortcuts,
|
.writeObject<MutableList<Artist>>(context, item.shortcuts, artistListSerializer)
|
||||||
CollectionSerializers.getListSerializer(artistSerializer))
|
.writeObject<MutableList<Artist>>(context, item.artists, artistListSerializer)
|
||||||
.writeObject<MutableList<Artist>>(context, item.artists,
|
|
||||||
CollectionSerializers.getListSerializer(artistSerializer))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun deserializeObject(
|
override fun deserializeObject(
|
||||||
|
@ -33,12 +32,17 @@ val indexesSerializer get() = object : ObjectSerializer<Indexes>(SERIALIZATION_V
|
||||||
): Indexes? {
|
): Indexes? {
|
||||||
if (versionNumber != SERIALIZATION_VERSION) return null
|
if (versionNumber != SERIALIZATION_VERSION) return null
|
||||||
|
|
||||||
|
val artistListDeserializer = getArtistListSerializer()
|
||||||
val lastModified = input.readLong()
|
val lastModified = input.readLong()
|
||||||
val ignoredArticles = input.readString() ?: return null
|
val ignoredArticles = input.readString() ?: return null
|
||||||
val shortcutsList = input.readObject(context,
|
val shortcutsList = input.readObject(context, artistListDeserializer) ?: return null
|
||||||
CollectionSerializers.getListSerializer(artistSerializer)) ?: return null
|
val artistsList = input.readObject(context, artistListDeserializer) ?: return null
|
||||||
val artistsList = input.readObject(context,
|
return Indexes(lastModified, ignoredArticles, shortcutsList.toMutableList(),
|
||||||
CollectionSerializers.getListSerializer(artistSerializer)) ?: return null
|
artistsList.toMutableList())
|
||||||
return Indexes(lastModified, ignoredArticles, shortcutsList, artistsList)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get serializer/deserializer for [Indexes] entity.
|
||||||
|
*/
|
||||||
|
fun getIndexesSerializer(): DomainEntitySerializer<Indexes> = indexesSerializer
|
||||||
|
|
|
@ -7,14 +7,12 @@ import com.twitter.serial.serializer.ObjectSerializer
|
||||||
import com.twitter.serial.serializer.SerializationContext
|
import com.twitter.serial.serializer.SerializationContext
|
||||||
import com.twitter.serial.stream.SerializerInput
|
import com.twitter.serial.stream.SerializerInput
|
||||||
import com.twitter.serial.stream.SerializerOutput
|
import com.twitter.serial.stream.SerializerOutput
|
||||||
|
import org.moire.ultrasonic.cache.DomainEntitySerializer
|
||||||
import org.moire.ultrasonic.domain.MusicFolder
|
import org.moire.ultrasonic.domain.MusicFolder
|
||||||
|
|
||||||
private const val SERIALIZATION_VERSION = 1
|
private const val SERIALIZATION_VERSION = 1
|
||||||
|
|
||||||
/**
|
private val musicFolderSerializer = object : ObjectSerializer<MusicFolder>(SERIALIZATION_VERSION) {
|
||||||
* Serializer/deserializer for [MusicFolder] domain entity.
|
|
||||||
*/
|
|
||||||
val musicFolderSerializer = object : ObjectSerializer<MusicFolder>(SERIALIZATION_VERSION) {
|
|
||||||
|
|
||||||
override fun serializeObject(
|
override fun serializeObject(
|
||||||
context: SerializationContext,
|
context: SerializationContext,
|
||||||
|
@ -37,7 +35,16 @@ val musicFolderSerializer = object : ObjectSerializer<MusicFolder>(SERIALIZATION
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializer/deserializer for [MusicFolder] domain entity.
|
||||||
|
*/
|
||||||
|
fun getMusicFolderSerializer(): DomainEntitySerializer<MusicFolder> = musicFolderSerializer
|
||||||
|
|
||||||
|
private val musicFolderListSerializer =
|
||||||
|
CollectionSerializers.getListSerializer(musicFolderSerializer)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serializer/deserializer for [List] of [MusicFolder] items.
|
* Serializer/deserializer for [List] of [MusicFolder] items.
|
||||||
*/
|
*/
|
||||||
val musicFolderListSerializer = CollectionSerializers.getListSerializer(musicFolderSerializer)
|
fun getMusicFolderListSerializer(): DomainEntitySerializer<List<MusicFolder>> =
|
||||||
|
musicFolderListSerializer
|
||||||
|
|
|
@ -4,7 +4,7 @@ import org.amshove.kluent.`should contain`
|
||||||
import org.amshove.kluent.`should equal to`
|
import org.amshove.kluent.`should equal to`
|
||||||
import org.amshove.kluent.`should equal`
|
import org.amshove.kluent.`should equal`
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.moire.ultrasonic.cache.serializers.musicFolderSerializer
|
import org.moire.ultrasonic.cache.serializers.getMusicFolderSerializer
|
||||||
import org.moire.ultrasonic.domain.MusicFolder
|
import org.moire.ultrasonic.domain.MusicFolder
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ class PermanentFileStorageTest : BaseStorageTest() {
|
||||||
@Test
|
@Test
|
||||||
fun `Should create storage dir if it is not exist`() {
|
fun `Should create storage dir if it is not exist`() {
|
||||||
val item = MusicFolder("1", "2")
|
val item = MusicFolder("1", "2")
|
||||||
storage.store("test", item, musicFolderSerializer)
|
storage.store("test", item, getMusicFolderSerializer())
|
||||||
|
|
||||||
storageDir.exists() `should equal to` true
|
storageDir.exists() `should equal to` true
|
||||||
getServerStorageDir().exists() `should equal to` true
|
getServerStorageDir().exists() `should equal to` true
|
||||||
|
@ -29,7 +29,7 @@ class PermanentFileStorageTest : BaseStorageTest() {
|
||||||
val item = MusicFolder("1", "23")
|
val item = MusicFolder("1", "23")
|
||||||
val name = "some-name"
|
val name = "some-name"
|
||||||
|
|
||||||
storage.store(name, item, musicFolderSerializer)
|
storage.store(name, item, getMusicFolderSerializer())
|
||||||
|
|
||||||
val storageFiles = getServerStorageDir().listFiles()
|
val storageFiles = getServerStorageDir().listFiles()
|
||||||
storageFiles.size `should equal to` 1
|
storageFiles.size `should equal to` 1
|
||||||
|
@ -40,9 +40,9 @@ class PermanentFileStorageTest : BaseStorageTest() {
|
||||||
fun `Should deserialize stored object`() {
|
fun `Should deserialize stored object`() {
|
||||||
val item = MusicFolder("some", "nice")
|
val item = MusicFolder("some", "nice")
|
||||||
val name = "some-name"
|
val name = "some-name"
|
||||||
storage.store(name, item, musicFolderSerializer)
|
storage.store(name, item, getMusicFolderSerializer())
|
||||||
|
|
||||||
val loadedItem = storage.load(name, musicFolderSerializer)
|
val loadedItem = storage.load(name, getMusicFolderSerializer())
|
||||||
|
|
||||||
loadedItem `should equal` item
|
loadedItem `should equal` item
|
||||||
}
|
}
|
||||||
|
@ -52,18 +52,18 @@ class PermanentFileStorageTest : BaseStorageTest() {
|
||||||
val name = "some-nice-name"
|
val name = "some-nice-name"
|
||||||
val item1 = MusicFolder("1", "1")
|
val item1 = MusicFolder("1", "1")
|
||||||
val item2 = MusicFolder("2", "2")
|
val item2 = MusicFolder("2", "2")
|
||||||
storage.store(name, item1, musicFolderSerializer)
|
storage.store(name, item1, getMusicFolderSerializer())
|
||||||
storage.store(name, item2, musicFolderSerializer)
|
storage.store(name, item2, getMusicFolderSerializer())
|
||||||
|
|
||||||
val loadedItem = storage.load(name, musicFolderSerializer)
|
val loadedItem = storage.load(name, getMusicFolderSerializer())
|
||||||
|
|
||||||
loadedItem `should equal` item2
|
loadedItem `should equal` item2
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `Should clear all files when clearAll is called`() {
|
fun `Should clear all files when clearAll is called`() {
|
||||||
storage.store("name1", MusicFolder("1", "1"), musicFolderSerializer)
|
storage.store("name1", MusicFolder("1", "1"), getMusicFolderSerializer())
|
||||||
storage.store("name2", MusicFolder("2", "2"), musicFolderSerializer)
|
storage.store("name2", MusicFolder("2", "2"), getMusicFolderSerializer())
|
||||||
|
|
||||||
storage.clearAll()
|
storage.clearAll()
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ class PermanentFileStorageTest : BaseStorageTest() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `Should return null if serialized file not available`() {
|
fun `Should return null if serialized file not available`() {
|
||||||
val loadedItem = storage.load("some-name", musicFolderSerializer)
|
val loadedItem = storage.load("some-name", getMusicFolderSerializer())
|
||||||
|
|
||||||
loadedItem `should equal` null
|
loadedItem `should equal` null
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ class ArtistSerializerTest : BaseStorageTest() {
|
||||||
fun `Should correctly serialize Artist object`() {
|
fun `Should correctly serialize Artist object`() {
|
||||||
val item = Artist("id", "name", "index", "coverArt", 1, 0)
|
val item = Artist("id", "name", "index", "coverArt", 1, 0)
|
||||||
|
|
||||||
storage.store("some-name", item, artistSerializer)
|
storage.store("some-name", item, getArtistsSerializer())
|
||||||
|
|
||||||
validateSerializedData()
|
validateSerializedData()
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,9 @@ class ArtistSerializerTest : BaseStorageTest() {
|
||||||
fun `Should correctly deserialize Artist object`() {
|
fun `Should correctly deserialize Artist object`() {
|
||||||
val itemName = "some-name"
|
val itemName = "some-name"
|
||||||
val item = Artist("id", "name", "index", "coverArt", null, 0)
|
val item = Artist("id", "name", "index", "coverArt", null, 0)
|
||||||
storage.store(itemName, item, artistSerializer)
|
storage.store(itemName, item, getArtistsSerializer())
|
||||||
|
|
||||||
val loadedItem = storage.load(itemName, artistSerializer)
|
val loadedItem = storage.load(itemName, getArtistsSerializer())
|
||||||
|
|
||||||
loadedItem `should equal` item
|
loadedItem `should equal` item
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ class ArtistSerializerTest : BaseStorageTest() {
|
||||||
Artist(id = "2", name = "some")
|
Artist(id = "2", name = "some")
|
||||||
)
|
)
|
||||||
|
|
||||||
storage.store("some-name", itemsList, artistListSerializer)
|
storage.store("some-name", itemsList, getArtistListSerializer())
|
||||||
|
|
||||||
validateSerializedData()
|
validateSerializedData()
|
||||||
}
|
}
|
||||||
|
@ -48,9 +48,9 @@ class ArtistSerializerTest : BaseStorageTest() {
|
||||||
Artist(id = "1"),
|
Artist(id = "1"),
|
||||||
Artist(id = "2", name = "some")
|
Artist(id = "2", name = "some")
|
||||||
)
|
)
|
||||||
storage.store(name, itemsList, artistListSerializer)
|
storage.store(name, itemsList, getArtistListSerializer())
|
||||||
|
|
||||||
val loadedItems = storage.load(name, artistListSerializer)
|
val loadedItems = storage.load(name, getArtistListSerializer())
|
||||||
|
|
||||||
loadedItems `should equal` itemsList
|
loadedItems `should equal` itemsList
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ class IndexesSerializerTest : BaseStorageTest() {
|
||||||
Artist("233", "some")
|
Artist("233", "some")
|
||||||
))
|
))
|
||||||
|
|
||||||
storage.store("some-name", item, indexesSerializer)
|
storage.store("some-name", item, getIndexesSerializer())
|
||||||
|
|
||||||
validateSerializedData()
|
validateSerializedData()
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,9 @@ class IndexesSerializerTest : BaseStorageTest() {
|
||||||
), mutableListOf(
|
), mutableListOf(
|
||||||
Artist("233", "some")
|
Artist("233", "some")
|
||||||
))
|
))
|
||||||
storage.store(name, item, indexesSerializer)
|
storage.store(name, item, getIndexesSerializer())
|
||||||
|
|
||||||
val loadedItem = storage.load(name, indexesSerializer)
|
val loadedItem = storage.load(name, getIndexesSerializer())
|
||||||
|
|
||||||
loadedItem `should equal` item
|
loadedItem `should equal` item
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ class MusicFolderSerializerTest : BaseStorageTest() {
|
||||||
fun `Should correctly serialize MusicFolder object`() {
|
fun `Should correctly serialize MusicFolder object`() {
|
||||||
val item = MusicFolder("Music", "Folder")
|
val item = MusicFolder("Music", "Folder")
|
||||||
|
|
||||||
storage.store("some-name", item, musicFolderSerializer)
|
storage.store("some-name", item, getMusicFolderSerializer())
|
||||||
|
|
||||||
validateSerializedData()
|
validateSerializedData()
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,9 @@ class MusicFolderSerializerTest : BaseStorageTest() {
|
||||||
fun `Should correctly deserialize MusicFolder object`() {
|
fun `Should correctly deserialize MusicFolder object`() {
|
||||||
val name = "name"
|
val name = "name"
|
||||||
val item = MusicFolder("some", "none")
|
val item = MusicFolder("some", "none")
|
||||||
storage.store(name, item, musicFolderSerializer)
|
storage.store(name, item, getMusicFolderSerializer())
|
||||||
|
|
||||||
val loadedItem = storage.load(name, musicFolderSerializer)
|
val loadedItem = storage.load(name, getMusicFolderSerializer())
|
||||||
|
|
||||||
loadedItem `should equal` item
|
loadedItem `should equal` item
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ class MusicFolderSerializerTest : BaseStorageTest() {
|
||||||
MusicFolder("2", "2")
|
MusicFolder("2", "2")
|
||||||
)
|
)
|
||||||
|
|
||||||
storage.store("some-name", itemsList, musicFolderListSerializer)
|
storage.store("some-name", itemsList, getMusicFolderListSerializer())
|
||||||
|
|
||||||
validateSerializedData()
|
validateSerializedData()
|
||||||
}
|
}
|
||||||
|
@ -48,9 +48,9 @@ class MusicFolderSerializerTest : BaseStorageTest() {
|
||||||
MusicFolder("1", "1"),
|
MusicFolder("1", "1"),
|
||||||
MusicFolder("2", "2")
|
MusicFolder("2", "2")
|
||||||
)
|
)
|
||||||
storage.store(name, itemsList, musicFolderListSerializer)
|
storage.store(name, itemsList, getMusicFolderListSerializer())
|
||||||
|
|
||||||
val loadedItem = storage.load(name, musicFolderListSerializer)
|
val loadedItem = storage.load(name, getMusicFolderListSerializer())
|
||||||
|
|
||||||
loadedItem `should equal` itemsList
|
loadedItem `should equal` itemsList
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue