Ensure Filter model match the spec and add Javadoc
This commit is contained in:
parent
e793a46576
commit
6e57b06673
@ -35,7 +35,7 @@ internal fun FilterEntity.Companion.get(realm: Realm): FilterEntity? {
|
||||
internal fun FilterEntity.Companion.getOrCreate(realm: Realm): FilterEntity {
|
||||
return get(realm) ?: realm.createObject<FilterEntity>()
|
||||
.apply {
|
||||
filterBodyJson = FilterFactory.createDefaultFilterBody().toJSONString()
|
||||
filterBodyJson = FilterFactory.createDefaultFilter().toJSONString()
|
||||
roomEventFilterJson = FilterFactory.createDefaultRoomFilter().toJSONString()
|
||||
filterId = ""
|
||||
}
|
||||
|
||||
@ -28,25 +28,25 @@ import javax.inject.Inject
|
||||
|
||||
internal class DefaultFilterRepository @Inject constructor(private val monarchy: Monarchy) : FilterRepository {
|
||||
|
||||
override suspend fun storeFilter(filterBody: FilterBody, roomEventFilter: RoomEventFilter): Boolean {
|
||||
override suspend fun storeFilter(filter: Filter, roomEventFilter: RoomEventFilter): Boolean {
|
||||
return Realm.getInstance(monarchy.realmConfiguration).use { realm ->
|
||||
val filter = FilterEntity.get(realm)
|
||||
val filterEntity = FilterEntity.get(realm)
|
||||
// Filter has changed, or no filter Id yet
|
||||
filter == null
|
||||
|| filter.filterBodyJson != filterBody.toJSONString()
|
||||
|| filter.filterId.isBlank()
|
||||
filterEntity == null
|
||||
|| filterEntity.filterBodyJson != filter.toJSONString()
|
||||
|| filterEntity.filterId.isBlank()
|
||||
}.also { hasChanged ->
|
||||
if (hasChanged) {
|
||||
// Filter is new or has changed, store it and reset the filter Id.
|
||||
// This has to be done outside of the Realm.use(), because awaitTransaction change the current thread
|
||||
monarchy.awaitTransaction { realm ->
|
||||
// We manage only one filter for now
|
||||
val filterBodyJson = filterBody.toJSONString()
|
||||
val filterJson = filter.toJSONString()
|
||||
val roomEventFilterJson = roomEventFilter.toJSONString()
|
||||
|
||||
val filterEntity = FilterEntity.getOrCreate(realm)
|
||||
|
||||
filterEntity.filterBodyJson = filterBodyJson
|
||||
filterEntity.filterBodyJson = filterJson
|
||||
filterEntity.roomEventFilterJson = roomEventFilterJson
|
||||
// Reset filterId
|
||||
filterEntity.filterId = ""
|
||||
@ -55,14 +55,14 @@ internal class DefaultFilterRepository @Inject constructor(private val monarchy:
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun storeFilterId(filterBody: FilterBody, filterId: String) {
|
||||
override suspend fun storeFilterId(filter: Filter, filterId: String) {
|
||||
monarchy.awaitTransaction {
|
||||
// We manage only one filter for now
|
||||
val filterBodyJson = filterBody.toJSONString()
|
||||
val filterJson = filter.toJSONString()
|
||||
|
||||
// Update the filter id, only if the filter body matches
|
||||
it.where<FilterEntity>()
|
||||
.equalTo(FilterEntityFields.FILTER_BODY_JSON, filterBodyJson)
|
||||
.equalTo(FilterEntityFields.FILTER_BODY_JSON, filterJson)
|
||||
?.findFirst()
|
||||
?.filterId = filterId
|
||||
}
|
||||
|
||||
@ -43,10 +43,10 @@ internal class DefaultSaveFilterTask @Inject constructor(
|
||||
override suspend fun execute(params: SaveFilterTask.Params) {
|
||||
val filterBody = when (params.filterPreset) {
|
||||
FilterService.FilterPreset.RiotFilter -> {
|
||||
FilterFactory.createRiotFilterBody()
|
||||
FilterFactory.createRiotFilter()
|
||||
}
|
||||
FilterService.FilterPreset.NoFilter -> {
|
||||
FilterFactory.createDefaultFilterBody()
|
||||
FilterFactory.createDefaultFilter()
|
||||
}
|
||||
}
|
||||
val roomFilter = when (params.filterPreset) {
|
||||
|
||||
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.internal.session.filter
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
/**
|
||||
* Represents "Filter" as mentioned in the SPEC
|
||||
* https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-user-userid-filter
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class EventFilter(
|
||||
/**
|
||||
* The maximum number of events to return.
|
||||
*/
|
||||
@Json(name = "limit") val limit: Int? = null,
|
||||
/**
|
||||
* A list of senders IDs to include. If this list is absent then all senders are included.
|
||||
*/
|
||||
@Json(name = "senders") val senders: List<String>? = null,
|
||||
/**
|
||||
* A list of sender IDs to exclude. If this list is absent then no senders are excluded.
|
||||
* A matching sender will be excluded even if it is listed in the 'senders' filter.
|
||||
*/
|
||||
@Json(name = "not_senders") val notSenders: List<String>? = null,
|
||||
/**
|
||||
* A list of event types to include. If this list is absent then all event types are included.
|
||||
* A '*' can be used as a wildcard to match any sequence of characters.
|
||||
*/
|
||||
@Json(name = "types") val types: List<String>? = null,
|
||||
/**
|
||||
* A list of event types to exclude. If this list is absent then no event types are excluded.
|
||||
* A matching type will be excluded even if it is listed in the 'types' filter.
|
||||
* A '*' can be used as a wildcard to match any sequence of characters.
|
||||
*/
|
||||
@Json(name = "not_types") val notTypes: List<String>? = null
|
||||
) {
|
||||
fun hasData(): Boolean {
|
||||
return limit != null
|
||||
|| senders != null
|
||||
|| notSenders != null
|
||||
|| types != null
|
||||
|| notTypes != null
|
||||
}
|
||||
}
|
||||
@ -17,28 +17,42 @@ package im.vector.matrix.android.internal.session.filter
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import im.vector.matrix.android.internal.di.MoshiProvider
|
||||
|
||||
/**
|
||||
* Represents "Filter" as mentioned in the SPEC
|
||||
* Class which can be parsed to a filter json string. Used for POST and GET
|
||||
* Have a look here for further information:
|
||||
* https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-user-userid-filter
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Filter(
|
||||
@Json(name = "limit") val limit: Int? = null,
|
||||
@Json(name = "senders") val senders: List<String>? = null,
|
||||
@Json(name = "not_senders") val notSenders: List<String>? = null,
|
||||
@Json(name = "types") val types: List<String>? = null,
|
||||
@Json(name = "not_types") val notTypes: List<String>? = null,
|
||||
@Json(name = "rooms") val rooms: List<String>? = null,
|
||||
@Json(name = "not_rooms") val notRooms: List<String>? = null
|
||||
internal data class Filter(
|
||||
/**
|
||||
* List of event fields to include. If this list is absent then all fields are included. The entries may
|
||||
* include '.' characters to indicate sub-fields. So ['content.body'] will include the 'body' field of the
|
||||
* 'content' object. A literal '.' character in a field name may be escaped using a '\'. A server may
|
||||
* include more fields than were requested.
|
||||
*/
|
||||
@Json(name = "event_fields") val eventFields: List<String>? = null,
|
||||
/**
|
||||
* The format to use for events. 'client' will return the events in a format suitable for clients.
|
||||
* 'federation' will return the raw event as received over federation. The default is 'client'. One of: ["client", "federation"]
|
||||
*/
|
||||
@Json(name = "event_format") val eventFormat: String? = null,
|
||||
/**
|
||||
* The presence updates to include.
|
||||
*/
|
||||
@Json(name = "presence") val presence: EventFilter? = null,
|
||||
/**
|
||||
* The user account data that isn't associated with rooms to include.
|
||||
*/
|
||||
@Json(name = "account_data") val accountData: EventFilter? = null,
|
||||
/**
|
||||
* Filters to be applied to room data.
|
||||
*/
|
||||
@Json(name = "room") val room: RoomFilter? = null
|
||||
) {
|
||||
fun hasData(): Boolean {
|
||||
return (limit != null
|
||||
|| senders != null
|
||||
|| notSenders != null
|
||||
|| types != null
|
||||
|| notTypes != null
|
||||
|| rooms != null
|
||||
|| notRooms != null)
|
||||
|
||||
fun toJSONString(): String {
|
||||
return MoshiProvider.providesMoshi().adapter(Filter::class.java).toJson(this)
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ internal interface FilterApi {
|
||||
* @param body the Json representation of a FilterBody object
|
||||
*/
|
||||
@POST(NetworkConstants.URI_API_PREFIX_PATH_R0 + "user/{userId}/filter")
|
||||
fun uploadFilter(@Path("userId") userId: String, @Body body: FilterBody): Call<FilterResponse>
|
||||
fun uploadFilter(@Path("userId") userId: String, @Body body: Filter): Call<FilterResponse>
|
||||
|
||||
/**
|
||||
* Gets a filter with a given filterId from the homeserver
|
||||
@ -42,6 +42,5 @@ internal interface FilterApi {
|
||||
* @return Filter
|
||||
*/
|
||||
@GET(NetworkConstants.URI_API_PREFIX_PATH_R0 + "user/{userId}/filter/{filterId}")
|
||||
fun getFilterById(@Path("userId") userId: String, @Path("filterId")
|
||||
filterId: String): Call<FilterBody>
|
||||
fun getFilterById(@Path("userId") userId: String, @Path("filterId") filterId: String): Call<Filter>
|
||||
}
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package im.vector.matrix.android.internal.session.filter
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import im.vector.matrix.android.internal.di.MoshiProvider
|
||||
|
||||
/**
|
||||
* Class which can be parsed to a filter json string. Used for POST and GET
|
||||
* Have a look here for further information:
|
||||
* https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-user-userid-filter
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class FilterBody(
|
||||
@Json(name = "event_fields") val eventFields: List<String>? = null,
|
||||
@Json(name = "event_format") val eventFormat: String? = null,
|
||||
@Json(name = "presence") val presence: Filter? = null,
|
||||
@Json(name = "account_data") val accountData: Filter? = null,
|
||||
@Json(name = "room") val room: RoomFilter? = null
|
||||
) {
|
||||
|
||||
fun toJSONString(): String {
|
||||
return MoshiProvider.providesMoshi().adapter(FilterBody::class.java).toJson(this)
|
||||
}
|
||||
}
|
||||
@ -20,12 +20,12 @@ import im.vector.matrix.android.api.session.events.model.EventType
|
||||
|
||||
internal object FilterFactory {
|
||||
|
||||
fun createDefaultFilterBody(): FilterBody {
|
||||
return FilterUtil.enableLazyLoading(FilterBody(), true)
|
||||
fun createDefaultFilter(): Filter {
|
||||
return FilterUtil.enableLazyLoading(Filter(), true)
|
||||
}
|
||||
|
||||
fun createRiotFilterBody(): FilterBody {
|
||||
return FilterBody(
|
||||
fun createRiotFilter(): Filter {
|
||||
return Filter(
|
||||
room = RoomFilter(
|
||||
timeline = createRiotTimelineFilter(),
|
||||
state = createRiotStateFilter()
|
||||
|
||||
@ -21,12 +21,12 @@ internal interface FilterRepository {
|
||||
/**
|
||||
* Return true if the filterBody has changed, or need to be sent to the server
|
||||
*/
|
||||
suspend fun storeFilter(filterBody: FilterBody, roomEventFilter: RoomEventFilter): Boolean
|
||||
suspend fun storeFilter(filter: Filter, roomEventFilter: RoomEventFilter): Boolean
|
||||
|
||||
/**
|
||||
* Set the filterId of this filter
|
||||
*/
|
||||
suspend fun storeFilterId(filterBody: FilterBody, filterId: String)
|
||||
suspend fun storeFilterId(filter: Filter, filterId: String)
|
||||
|
||||
/**
|
||||
* Return filter json or filter id
|
||||
|
||||
@ -24,5 +24,10 @@ import com.squareup.moshi.JsonClass
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class FilterResponse(
|
||||
/**
|
||||
* Required. The ID of the filter that was created. Cannot start with a { as this character
|
||||
* is used to determine if the filter provided is inline JSON or a previously declared
|
||||
* filter by homeservers on some APIs.
|
||||
*/
|
||||
@Json(name = "filter_id") val filterId: String
|
||||
)
|
||||
|
||||
@ -81,30 +81,30 @@ internal object FilterUtil {
|
||||
} */
|
||||
|
||||
/**
|
||||
* Compute a new filterBody to enable or disable the lazy loading
|
||||
* Compute a new filter to enable or disable the lazy loading
|
||||
*
|
||||
*
|
||||
* If lazy loading is on, the filterBody will looks like
|
||||
* If lazy loading is on, the filter will looks like
|
||||
* {"room":{"state":{"lazy_load_members":true})}
|
||||
*
|
||||
* @param filterBody filterBody to patch
|
||||
* @param filter filter to patch
|
||||
* @param useLazyLoading true to enable lazy loading
|
||||
*/
|
||||
fun enableLazyLoading(filterBody: FilterBody, useLazyLoading: Boolean): FilterBody {
|
||||
fun enableLazyLoading(filter: Filter, useLazyLoading: Boolean): Filter {
|
||||
if (useLazyLoading) {
|
||||
// Enable lazy loading
|
||||
return filterBody.copy(
|
||||
room = filterBody.room?.copy(
|
||||
state = filterBody.room.state?.copy(lazyLoadMembers = true)
|
||||
return filter.copy(
|
||||
room = filter.room?.copy(
|
||||
state = filter.room.state?.copy(lazyLoadMembers = true)
|
||||
?: RoomEventFilter(lazyLoadMembers = true)
|
||||
)
|
||||
?: RoomFilter(state = RoomEventFilter(lazyLoadMembers = true))
|
||||
)
|
||||
} else {
|
||||
val newRoomEventFilter = filterBody.room?.state?.copy(lazyLoadMembers = null)?.takeIf { it.hasData() }
|
||||
val newRoomFilter = filterBody.room?.copy(state = newRoomEventFilter)?.takeIf { it.hasData() }
|
||||
val newRoomEventFilter = filter.room?.state?.copy(lazyLoadMembers = null)?.takeIf { it.hasData() }
|
||||
val newRoomFilter = filter.room?.copy(state = newRoomEventFilter)?.takeIf { it.hasData() }
|
||||
|
||||
return filterBody.copy(
|
||||
return filter.copy(
|
||||
room = newRoomFilter
|
||||
)
|
||||
}
|
||||
|
||||
@ -25,14 +25,46 @@ import im.vector.matrix.android.internal.di.MoshiProvider
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class RoomEventFilter(
|
||||
/**
|
||||
* The maximum number of events to return.
|
||||
*/
|
||||
@Json(name = "limit") var limit: Int? = null,
|
||||
/**
|
||||
* A list of sender IDs to exclude. If this list is absent then no senders are excluded. A matching sender will
|
||||
* be excluded even if it is listed in the 'senders' filter.
|
||||
*/
|
||||
@Json(name = "not_senders") val notSenders: List<String>? = null,
|
||||
/**
|
||||
* A list of event types to exclude. If this list is absent then no event types are excluded. A matching type will
|
||||
* be excluded even if it is listed in the 'types' filter. A '*' can be used as a wildcard to match any sequence of characters.
|
||||
*/
|
||||
@Json(name = "not_types") val notTypes: List<String>? = null,
|
||||
/**
|
||||
* A list of senders IDs to include. If this list is absent then all senders are included.
|
||||
*/
|
||||
@Json(name = "senders") val senders: List<String>? = null,
|
||||
/**
|
||||
* A list of event types to include. If this list is absent then all event types are included. A '*' can be used as
|
||||
* a wildcard to match any sequence of characters.
|
||||
*/
|
||||
@Json(name = "types") val types: List<String>? = null,
|
||||
/**
|
||||
* A list of room IDs to include. If this list is absent then all rooms are included.
|
||||
*/
|
||||
@Json(name = "rooms") val rooms: List<String>? = null,
|
||||
/**
|
||||
* A list of room IDs to exclude. If this list is absent then no rooms are excluded. A matching room will be excluded
|
||||
* even if it is listed in the 'rooms' filter.
|
||||
*/
|
||||
@Json(name = "not_rooms") val notRooms: List<String>? = null,
|
||||
/**
|
||||
* If true, includes only events with a url key in their content. If false, excludes those events. If omitted, url
|
||||
* key is not considered for filtering.
|
||||
*/
|
||||
@Json(name = "contains_url") val containsUrl: Boolean? = null,
|
||||
/**
|
||||
* If true, enables lazy-loading of membership events. See Lazy-loading room members for more information. Defaults to false.
|
||||
*/
|
||||
@Json(name = "lazy_load_members") val lazyLoadMembers: Boolean? = null
|
||||
) {
|
||||
|
||||
|
||||
@ -24,12 +24,37 @@ import com.squareup.moshi.JsonClass
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class RoomFilter(
|
||||
/**
|
||||
* A list of room IDs to exclude. If this list is absent then no rooms are excluded.
|
||||
* A matching room will be excluded even if it is listed in the 'rooms' filter.
|
||||
* This filter is applied before the filters in ephemeral, state, timeline or account_data
|
||||
*/
|
||||
@Json(name = "not_rooms") val notRooms: List<String>? = null,
|
||||
/**
|
||||
* A list of room IDs to include. If this list is absent then all rooms are included.
|
||||
* This filter is applied before the filters in ephemeral, state, timeline or account_data
|
||||
*/
|
||||
@Json(name = "rooms") val rooms: List<String>? = null,
|
||||
/**
|
||||
* The events that aren't recorded in the room history, e.g. typing and receipts, to include for rooms.
|
||||
*/
|
||||
@Json(name = "ephemeral") val ephemeral: RoomEventFilter? = null,
|
||||
/**
|
||||
* Include rooms that the user has left in the sync, default false
|
||||
*/
|
||||
@Json(name = "include_leave") val includeLeave: Boolean? = null,
|
||||
/**
|
||||
* The state events to include for rooms.
|
||||
* Developer remark: StateFilter is exactly the same than RoomEventFilter
|
||||
*/
|
||||
@Json(name = "state") val state: RoomEventFilter? = null,
|
||||
/**
|
||||
* The message and state update events to include for rooms.
|
||||
*/
|
||||
@Json(name = "timeline") val timeline: RoomEventFilter? = null,
|
||||
/**
|
||||
* The per user account data to include for rooms.
|
||||
*/
|
||||
@Json(name = "account_data") val accountData: RoomEventFilter? = null
|
||||
) {
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user