From 0f667fe6e8a00e4aff9903372129fbe5ee2aea46 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 17 Dec 2018 18:24:01 +0100 Subject: [PATCH] Introduce ContentMapper, allowing to map a content directly without going through an event entity. --- .../internal/database/mapper/ContentMapper.kt | 20 +++++++ .../internal/database/mapper/EventMapper.kt | 34 ++++-------- .../session/events/prune/PruneEventWorker.kt | 55 +++++++++---------- 3 files changed, 57 insertions(+), 52 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/ContentMapper.kt diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/ContentMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/ContentMapper.kt new file mode 100644 index 0000000000..063cabe2fd --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/ContentMapper.kt @@ -0,0 +1,20 @@ +package im.vector.matrix.android.internal.database.mapper + +import im.vector.matrix.android.api.session.events.model.Content +import im.vector.matrix.android.api.session.events.model.Event +import im.vector.matrix.android.internal.di.MoshiProvider + +internal object ContentMapper { + + private val moshi = MoshiProvider.providesMoshi() + private val adapter = moshi.adapter(Event.CONTENT_TYPE) + + fun map(content: String?): Content? { + return adapter.fromJson(content ?: "") + } + + fun map(content: Content?): String { + return adapter.toJson(content) + } + +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/EventMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/EventMapper.kt index fcbea5fcc5..5d1669b9a5 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/EventMapper.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/mapper/EventMapper.kt @@ -3,17 +3,23 @@ package im.vector.matrix.android.internal.database.mapper import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.UnsignedData import im.vector.matrix.android.internal.database.model.EventEntity -import im.vector.matrix.android.internal.di.MoshiProvider internal object EventMapper { - private val moshi = MoshiProvider.providesMoshi() - private val adapter = moshi.adapter>(Event.CONTENT_TYPE) fun map(event: Event): EventEntity { val eventEntity = EventEntity() - fill(eventEntity, with = event) + eventEntity.eventId = event.eventId ?: "" + eventEntity.content = ContentMapper.map(event.content) + val resolvedPrevContent = event.prevContent ?: event.unsignedData?.prevContent + eventEntity.prevContent = ContentMapper.map(resolvedPrevContent) + eventEntity.stateKey = event.stateKey + eventEntity.type = event.type + eventEntity.sender = event.sender + eventEntity.originServerTs = event.originServerTs + eventEntity.redacts = event.redacts + eventEntity.age = event.unsignedData?.age ?: event.originServerTs return eventEntity } @@ -21,8 +27,8 @@ internal object EventMapper { return Event( type = eventEntity.type, eventId = eventEntity.eventId, - content = adapter.fromJson(eventEntity.content), - prevContent = adapter.fromJson(eventEntity.prevContent ?: ""), + content = ContentMapper.map(eventEntity.content), + prevContent = ContentMapper.map(eventEntity.prevContent), originServerTs = eventEntity.originServerTs, sender = eventEntity.sender, stateKey = eventEntity.stateKey, @@ -32,18 +38,6 @@ internal object EventMapper { ) } - fun fill(eventEntity: EventEntity, with: Event) { - eventEntity.eventId = with.eventId ?: "" - eventEntity.content = adapter.toJson(with.content) - val resolvedPrevContent = with.prevContent ?: with.unsignedData?.prevContent - eventEntity.prevContent = adapter.toJson(resolvedPrevContent) - eventEntity.stateKey = with.stateKey - eventEntity.type = with.type - eventEntity.sender = with.sender - eventEntity.originServerTs = with.originServerTs - eventEntity.redacts = with.redacts - eventEntity.age = with.unsignedData?.age ?: with.originServerTs - } } @@ -54,7 +48,3 @@ internal fun EventEntity.asDomain(): Event { internal fun Event.asEntity(): EventEntity { return EventMapper.map(this) } - -internal fun EventEntity.fillWith(event: Event) { - EventMapper.fill(this, with = event) -} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/events/prune/PruneEventWorker.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/events/prune/PruneEventWorker.kt index 0f158d6103..9be00e75c0 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/events/prune/PruneEventWorker.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/events/prune/PruneEventWorker.kt @@ -3,13 +3,11 @@ package im.vector.matrix.android.internal.session.events.prune import android.content.Context import androidx.work.Worker import androidx.work.WorkerParameters -import arrow.core.Option import com.squareup.moshi.JsonClass import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.EventType -import im.vector.matrix.android.internal.database.mapper.asDomain -import im.vector.matrix.android.internal.database.mapper.asEntity +import im.vector.matrix.android.internal.database.mapper.ContentMapper import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.util.WorkerParamsFactory @@ -33,7 +31,7 @@ internal class PruneEventWorker(context: Context, override fun doWork(): Result { val params = WorkerParamsFactory.fromData(inputData) - ?: return Result.failure() + ?: return Result.failure() val result = monarchy.tryTransactionAsync { realm -> params.updateIndexes.forEach { index -> @@ -48,39 +46,36 @@ internal class PruneEventWorker(context: Context, if (redactionEvent == null || redactionEvent.redacts.isNullOrEmpty()) { return } - val eventToPrune = EventEntity.where(realm, eventId = redactionEvent.redacts).findFirst()?.asDomain() - ?: return + val eventToPrune = EventEntity.where(realm, eventId = redactionEvent.redacts).findFirst() + ?: return val allowedKeys = computeAllowedKeys(eventToPrune.type) - val prunedContent = allowedKeys.fold( - { eventToPrune.content }, - { eventToPrune.content?.filterKeys { key -> it.contains(key) } } - ) - val eventToPruneEntity = eventToPrune.copy(content = prunedContent).asEntity() - realm.insertOrUpdate(eventToPruneEntity) + if (allowedKeys.isNotEmpty()) { + val prunedContent = ContentMapper.map(eventToPrune.content)?.filterKeys { key -> allowedKeys.contains(key) } + eventToPrune.content = ContentMapper.map(prunedContent) + } } - private fun computeAllowedKeys(type: String): Option> { + private fun computeAllowedKeys(type: String): List { // Add filtered content, allowed keys in content depends on the event type - val result = when (type) { - EventType.STATE_ROOM_MEMBER -> listOf("membership") - EventType.STATE_ROOM_CREATE -> listOf("creator") - EventType.STATE_ROOM_JOIN_RULES -> listOf("join_rule") + return when (type) { + EventType.STATE_ROOM_MEMBER -> listOf("membership") + EventType.STATE_ROOM_CREATE -> listOf("creator") + EventType.STATE_ROOM_JOIN_RULES -> listOf("join_rule") EventType.STATE_ROOM_POWER_LEVELS -> listOf("users", - "users_default", - "events", - "events_default", - "state_default", - "ban", - "kick", - "redact", - "invite") - EventType.STATE_ROOM_ALIASES -> listOf("aliases") - EventType.STATE_CANONICAL_ALIAS -> listOf("alias") - EventType.FEEDBACK -> listOf("type", "target_event_id") - else -> null + "users_default", + "events", + "events_default", + "state_default", + "ban", + "kick", + "redact", + "invite") + EventType.STATE_ROOM_ALIASES -> listOf("aliases") + EventType.STATE_CANONICAL_ALIAS -> listOf("alias") + EventType.FEEDBACK -> listOf("type", "target_event_id") + else -> emptyList() } - return Option.fromNullable(result) } } \ No newline at end of file