From 48dfdc8b3e81bd2907d2d38bb9385b672a2bc58f Mon Sep 17 00:00:00 2001 From: Atsushi Eno Date: Tue, 5 Mar 2024 14:22:57 +0900 Subject: [PATCH] more CommonRules API refactoring. - PropertyCommonRulesService now simply takes MidiCIDevice at constructor - it will help having more predefined resource properties at device.config. - remove PropertyRulesHelper from public class inheritance --- ktmidi-ci/api/android/ktmidi-ci.api | 25 ++----- ktmidi-ci/api/jvm/ktmidi-ci.api | 25 ++----- .../ktmidi/ci/PropertyHostFacade.kt | 2 +- .../PropertyCommonRules.Client.kt | 22 ++++--- .../PropertyCommonRules.Helper.kt | 66 ++++--------------- .../PropertyCommonRules.Service.kt | 39 +++++++---- 6 files changed, 68 insertions(+), 111 deletions(-) diff --git a/ktmidi-ci/api/android/ktmidi-ci.api b/ktmidi-ci/api/android/ktmidi-ci.api index 84803f010..aa06b9a0a 100644 --- a/ktmidi-ci/api/android/ktmidi-ci.api +++ b/ktmidi-ci/api/android/ktmidi-ci.api @@ -1169,6 +1169,7 @@ public final class dev/atsushieno/ktmidi/ci/ServiceObservablePropertyList : dev/ public fun getMetadataList ()Ljava/util/List; public final fun removeMetadata (Ljava/lang/String;)V public final fun updateMetadata (Ljava/lang/String;Ldev/atsushieno/ktmidi/ci/PropertyMetadata;)V + public final fun updateValue (Ljava/lang/String;Ljava/util/List;Ljava/util/List;)V } public final class dev/atsushieno/ktmidi/ci/SubscriptionActionState : java/lang/Enum { @@ -1281,13 +1282,15 @@ public final class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesKnown public static final field INSTANCE Ldev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesKnownMimeTypes; } -public final class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyClient : dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyHelper, dev/atsushieno/ktmidi/ci/MidiCIClientPropertyRules { +public final class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyClient : dev/atsushieno/ktmidi/ci/MidiCIClientPropertyRules { public fun (Ldev/atsushieno/ktmidi/ci/MidiCIDevice;Ldev/atsushieno/ktmidi/ci/ClientConnection;)V public fun createDataRequestHeader (Ljava/lang/String;Ljava/util/Map;)Ljava/util/List; public fun createStatusHeader (I)Ljava/util/List; public fun createSubscriptionHeader (Ljava/lang/String;Ljava/util/Map;)Ljava/util/List; public fun decodeBody (Ljava/util/List;Ljava/util/List;)Ljava/util/List; public fun encodeBody (Ljava/util/List;Ljava/lang/String;)Ljava/util/List; + public fun getHeaderFieldInteger (Ljava/util/List;Ljava/lang/String;)Ljava/lang/Integer; + public fun getHeaderFieldString (Ljava/util/List;Ljava/lang/String;)Ljava/lang/String; public fun getMetadataList ()Ljava/util/List; public fun getPropertyCatalogUpdated ()Ljava/util/List; public fun getPropertyIdForHeader (Ljava/util/List;)Ljava/lang/String; @@ -1299,18 +1302,6 @@ public final class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPrope public fun requestPropertyList (B)V } -public abstract class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyHelper { - public fun (Ldev/atsushieno/ktmidi/ci/Logger;)V - public final fun createRequestHeaderBytes (Ljava/lang/String;Ljava/util/Map;)Ljava/util/List; - public final fun createSubscribeHeaderBytes (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/util/List; - public final fun getHeaderFieldInteger (Ljava/util/List;Ljava/lang/String;)Ljava/lang/Integer; - public final fun getHeaderFieldString (Ljava/util/List;Ljava/lang/String;)Ljava/lang/String; - protected final fun getLogger ()Ldev/atsushieno/ktmidi/ci/Logger; - public final fun getPropertyIdentifierInternal (Ljava/util/List;)Ljava/lang/String; - public final fun getResourceListRequestBytes ()Ljava/util/List; - public final fun getResourceListRequestJson ()Ldev/atsushieno/ktmidi/ci/json/Json$JsonValue; -} - public final class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyMetadata : dev/atsushieno/ktmidi/ci/PropertyMetadata { public static final field Companion Ldev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyMetadata$Companion; public fun ()V @@ -1371,15 +1362,14 @@ public final class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPrope public static fun values ()[Ldev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyMetadata$Originator; } -public final class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyService : dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyHelper, dev/atsushieno/ktmidi/ci/MidiCIServicePropertyRules { - public fun (Ldev/atsushieno/ktmidi/ci/Logger;ILdev/atsushieno/ktmidi/ci/MidiCIDeviceInfo;Ljava/util/List;Ljava/util/List;Ldev/atsushieno/ktmidi/ci/json/Json$JsonValue;Ldev/atsushieno/ktmidi/ci/json/Json$JsonValue;)V - public synthetic fun (Ldev/atsushieno/ktmidi/ci/Logger;ILdev/atsushieno/ktmidi/ci/MidiCIDeviceInfo;Ljava/util/List;Ljava/util/List;Ldev/atsushieno/ktmidi/ci/json/Json$JsonValue;Ldev/atsushieno/ktmidi/ci/json/Json$JsonValue;ILkotlin/jvm/internal/DefaultConstructorMarker;)V +public final class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyService : dev/atsushieno/ktmidi/ci/MidiCIServicePropertyRules { + public fun (Ldev/atsushieno/ktmidi/ci/MidiCIDevice;)V public fun addMetadata (Ldev/atsushieno/ktmidi/ci/PropertyMetadata;)V public fun createShutdownSubscriptionHeader (Ljava/lang/String;)Ljava/util/List; public fun createUpdateNotificationHeader (Ljava/lang/String;Ljava/util/Map;)Ljava/util/List; public fun decodeBody (Ljava/util/List;Ljava/util/List;)Ljava/util/List; public fun encodeBody (Ljava/util/List;Ljava/lang/String;)Ljava/util/List; - public final fun getDeviceInfo ()Ldev/atsushieno/ktmidi/ci/MidiCIDeviceInfo; + public fun getHeaderFieldString (Ljava/util/List;Ljava/lang/String;)Ljava/lang/String; public final fun getLinkedResources ()Ljava/util/Map; public fun getMetadataList ()Ljava/util/List; public fun getPropertyCatalogUpdated ()Ljava/util/List; @@ -1387,7 +1377,6 @@ public final class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPrope public fun getPropertyIdForHeader (Ljava/util/List;)Ljava/lang/String; public fun getSubscriptions ()Ljava/util/List; public fun removeMetadata (Ljava/lang/String;)V - public final fun setDeviceInfo (Ldev/atsushieno/ktmidi/ci/MidiCIDeviceInfo;)V public fun setPropertyData-IoAF18A (Ldev/atsushieno/ktmidi/ci/Message$SetPropertyData;)Ljava/lang/Object; public final fun setPropertyData-gIAlu-s (Ldev/atsushieno/ktmidi/ci/json/Json$JsonValue;Ljava/util/List;)Ljava/lang/Object; public final fun subscribe (ILdev/atsushieno/ktmidi/ci/json/Json$JsonValue;)Lkotlin/Pair; diff --git a/ktmidi-ci/api/jvm/ktmidi-ci.api b/ktmidi-ci/api/jvm/ktmidi-ci.api index e68c5caab..ed6673287 100644 --- a/ktmidi-ci/api/jvm/ktmidi-ci.api +++ b/ktmidi-ci/api/jvm/ktmidi-ci.api @@ -1169,6 +1169,7 @@ public final class dev/atsushieno/ktmidi/ci/ServiceObservablePropertyList : dev/ public fun getMetadataList ()Ljava/util/List; public final fun removeMetadata (Ljava/lang/String;)V public final fun updateMetadata (Ljava/lang/String;Ldev/atsushieno/ktmidi/ci/PropertyMetadata;)V + public final fun updateValue (Ljava/lang/String;Ljava/util/List;Ljava/util/List;)V } public final class dev/atsushieno/ktmidi/ci/SubscriptionActionState : java/lang/Enum { @@ -1281,13 +1282,15 @@ public final class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesKnown public static final field INSTANCE Ldev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesKnownMimeTypes; } -public final class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyClient : dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyHelper, dev/atsushieno/ktmidi/ci/MidiCIClientPropertyRules { +public final class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyClient : dev/atsushieno/ktmidi/ci/MidiCIClientPropertyRules { public fun (Ldev/atsushieno/ktmidi/ci/MidiCIDevice;Ldev/atsushieno/ktmidi/ci/ClientConnection;)V public fun createDataRequestHeader (Ljava/lang/String;Ljava/util/Map;)Ljava/util/List; public fun createStatusHeader (I)Ljava/util/List; public fun createSubscriptionHeader (Ljava/lang/String;Ljava/util/Map;)Ljava/util/List; public fun decodeBody (Ljava/util/List;Ljava/util/List;)Ljava/util/List; public fun encodeBody (Ljava/util/List;Ljava/lang/String;)Ljava/util/List; + public fun getHeaderFieldInteger (Ljava/util/List;Ljava/lang/String;)Ljava/lang/Integer; + public fun getHeaderFieldString (Ljava/util/List;Ljava/lang/String;)Ljava/lang/String; public fun getMetadataList ()Ljava/util/List; public fun getPropertyCatalogUpdated ()Ljava/util/List; public fun getPropertyIdForHeader (Ljava/util/List;)Ljava/lang/String; @@ -1299,18 +1302,6 @@ public final class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPrope public fun requestPropertyList (B)V } -public abstract class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyHelper { - public fun (Ldev/atsushieno/ktmidi/ci/Logger;)V - public final fun createRequestHeaderBytes (Ljava/lang/String;Ljava/util/Map;)Ljava/util/List; - public final fun createSubscribeHeaderBytes (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/util/List; - public final fun getHeaderFieldInteger (Ljava/util/List;Ljava/lang/String;)Ljava/lang/Integer; - public final fun getHeaderFieldString (Ljava/util/List;Ljava/lang/String;)Ljava/lang/String; - protected final fun getLogger ()Ldev/atsushieno/ktmidi/ci/Logger; - public final fun getPropertyIdentifierInternal (Ljava/util/List;)Ljava/lang/String; - public final fun getResourceListRequestBytes ()Ljava/util/List; - public final fun getResourceListRequestJson ()Ldev/atsushieno/ktmidi/ci/json/Json$JsonValue; -} - public final class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyMetadata : dev/atsushieno/ktmidi/ci/PropertyMetadata { public static final field Companion Ldev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyMetadata$Companion; public fun ()V @@ -1371,15 +1362,14 @@ public final class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPrope public static fun values ()[Ldev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyMetadata$Originator; } -public final class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyService : dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyHelper, dev/atsushieno/ktmidi/ci/MidiCIServicePropertyRules { - public fun (Ldev/atsushieno/ktmidi/ci/Logger;ILdev/atsushieno/ktmidi/ci/MidiCIDeviceInfo;Ljava/util/List;Ljava/util/List;Ldev/atsushieno/ktmidi/ci/json/Json$JsonValue;Ldev/atsushieno/ktmidi/ci/json/Json$JsonValue;)V - public synthetic fun (Ldev/atsushieno/ktmidi/ci/Logger;ILdev/atsushieno/ktmidi/ci/MidiCIDeviceInfo;Ljava/util/List;Ljava/util/List;Ldev/atsushieno/ktmidi/ci/json/Json$JsonValue;Ldev/atsushieno/ktmidi/ci/json/Json$JsonValue;ILkotlin/jvm/internal/DefaultConstructorMarker;)V +public final class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPropertyService : dev/atsushieno/ktmidi/ci/MidiCIServicePropertyRules { + public fun (Ldev/atsushieno/ktmidi/ci/MidiCIDevice;)V public fun addMetadata (Ldev/atsushieno/ktmidi/ci/PropertyMetadata;)V public fun createShutdownSubscriptionHeader (Ljava/lang/String;)Ljava/util/List; public fun createUpdateNotificationHeader (Ljava/lang/String;Ljava/util/Map;)Ljava/util/List; public fun decodeBody (Ljava/util/List;Ljava/util/List;)Ljava/util/List; public fun encodeBody (Ljava/util/List;Ljava/lang/String;)Ljava/util/List; - public final fun getDeviceInfo ()Ldev/atsushieno/ktmidi/ci/MidiCIDeviceInfo; + public fun getHeaderFieldString (Ljava/util/List;Ljava/lang/String;)Ljava/lang/String; public final fun getLinkedResources ()Ljava/util/Map; public fun getMetadataList ()Ljava/util/List; public fun getPropertyCatalogUpdated ()Ljava/util/List; @@ -1387,7 +1377,6 @@ public final class dev/atsushieno/ktmidi/ci/propertycommonrules/CommonRulesPrope public fun getPropertyIdForHeader (Ljava/util/List;)Ljava/lang/String; public fun getSubscriptions ()Ljava/util/List; public fun removeMetadata (Ljava/lang/String;)V - public final fun setDeviceInfo (Ldev/atsushieno/ktmidi/ci/MidiCIDeviceInfo;)V public fun setPropertyData-IoAF18A (Ldev/atsushieno/ktmidi/ci/Message$SetPropertyData;)Ljava/lang/Object; public final fun setPropertyData-gIAlu-s (Ldev/atsushieno/ktmidi/ci/json/Json$JsonValue;Ljava/util/List;)Ljava/lang/Object; public final fun subscribe (ILdev/atsushieno/ktmidi/ci/json/Json$JsonValue;)Lkotlin/Pair; diff --git a/ktmidi-ci/src/commonMain/kotlin/dev/atsushieno/ktmidi/ci/PropertyHostFacade.kt b/ktmidi-ci/src/commonMain/kotlin/dev/atsushieno/ktmidi/ci/PropertyHostFacade.kt index b37b8435f..a1ed68564 100644 --- a/ktmidi-ci/src/commonMain/kotlin/dev/atsushieno/ktmidi/ci/PropertyHostFacade.kt +++ b/ktmidi-ci/src/commonMain/kotlin/dev/atsushieno/ktmidi/ci/PropertyHostFacade.kt @@ -43,7 +43,7 @@ class PropertyHostFacade(private val device: MidiCIDevice) { private val logger by device::logger private val config by device::config - internal val propertyService: MidiCIServicePropertyRules by lazy { CommonRulesPropertyService(logger, muid, device.deviceInfo, config.propertyValues, config.propertyMetadataList) } + internal val propertyService: MidiCIServicePropertyRules by lazy { CommonRulesPropertyService(device) } val properties by lazy { ServiceObservablePropertyList(config.propertyValues, propertyService) } val subscriptions: List by propertyService::subscriptions diff --git a/ktmidi-ci/src/commonMain/kotlin/dev/atsushieno/ktmidi/ci/propertycommonrules/PropertyCommonRules.Client.kt b/ktmidi-ci/src/commonMain/kotlin/dev/atsushieno/ktmidi/ci/propertycommonrules/PropertyCommonRules.Client.kt index 01f840cfa..d8ccab4b2 100644 --- a/ktmidi-ci/src/commonMain/kotlin/dev/atsushieno/ktmidi/ci/propertycommonrules/PropertyCommonRules.Client.kt +++ b/ktmidi-ci/src/commonMain/kotlin/dev/atsushieno/ktmidi/ci/propertycommonrules/PropertyCommonRules.Client.kt @@ -4,21 +4,23 @@ import dev.atsushieno.ktmidi.ci.* import dev.atsushieno.ktmidi.ci.json.Json import dev.atsushieno.ktmidi.ci.json.JsonParserException -class CommonRulesPropertyClient(private val device: MidiCIDevice, private val conn: ClientConnection) : - CommonRulesPropertyHelper(device.logger), MidiCIClientPropertyRules { +class CommonRulesPropertyClient(private val device: MidiCIDevice, private val conn: ClientConnection) + : MidiCIClientPropertyRules { + private val helper = CommonRulesPropertyHelper(device) + private val logger by device::logger override fun createDataRequestHeader(propertyId: String, fields: Map): List = - createRequestHeaderBytes(propertyId, fields) + helper.createRequestHeaderBytes(propertyId, fields) override fun createSubscriptionHeader(propertyId: String, fields: Map): List = - createSubscribeHeaderBytes(propertyId, fields[PropertyCommonHeaderKeys.COMMAND] as String, fields[PropertyCommonHeaderKeys.MUTUAL_ENCODING] as String?) + helper.createSubscribeHeaderBytes(propertyId, fields[PropertyCommonHeaderKeys.COMMAND] as String, fields[PropertyCommonHeaderKeys.MUTUAL_ENCODING] as String?) - override fun getPropertyIdForHeader(header: List) = getPropertyIdentifierInternal(header) + override fun getPropertyIdForHeader(header: List) = helper.getPropertyIdentifierInternal(header) override fun getMetadataList(): List = resourceList override fun requestPropertyList(group: Byte) { - val requestASCIIBytes = getResourceListRequestBytes() + val requestASCIIBytes = helper.getResourceListRequestBytes() val msg = Message.GetPropertyData( Message.Common(device.muid, conn.targetMUID, MidiCIConstants.ADDRESS_FUNCTION_BLOCK, group), device.messenger.requestIdSerial++, @@ -63,6 +65,10 @@ class CommonRulesPropertyClient(private val device: MidiCIDevice, private val co } } + override fun getHeaderFieldInteger(header: List, field: String): Int? = helper.getHeaderFieldInteger(header, field) + + override fun getHeaderFieldString(header: List, field: String): String? = helper.getHeaderFieldString(header, field) + override fun getSubscribedProperty(msg: Message.SubscribeProperty): String? { val subscribeId = getHeaderFieldString(msg.header, PropertyCommonHeaderKeys.SUBSCRIBE_ID) if (subscribeId == null) { @@ -135,8 +141,8 @@ class CommonRulesPropertyClient(private val device: MidiCIDevice, private val co Pair(false, existing.body) } - override fun encodeBody(data: List, encoding: String?): List = encodeBodyInternal(data, encoding) - override fun decodeBody(header: List, body: List): List = decodeBodyInternal(header, body) + override fun encodeBody(data: List, encoding: String?): List = helper.encodeBody(data, encoding) + override fun decodeBody(header: List, body: List): List = helper.decodeBody(header, body) override val propertyCatalogUpdated = mutableListOf<() -> Unit>() diff --git a/ktmidi-ci/src/commonMain/kotlin/dev/atsushieno/ktmidi/ci/propertycommonrules/PropertyCommonRules.Helper.kt b/ktmidi-ci/src/commonMain/kotlin/dev/atsushieno/ktmidi/ci/propertycommonrules/PropertyCommonRules.Helper.kt index fa9e3c6af..167a12f2a 100644 --- a/ktmidi-ci/src/commonMain/kotlin/dev/atsushieno/ktmidi/ci/propertycommonrules/PropertyCommonRules.Helper.kt +++ b/ktmidi-ci/src/commonMain/kotlin/dev/atsushieno/ktmidi/ci/propertycommonrules/PropertyCommonRules.Helper.kt @@ -1,12 +1,14 @@ package dev.atsushieno.ktmidi.ci.propertycommonrules -import dev.atsushieno.ktmidi.ci.Logger import dev.atsushieno.ktmidi.ci.MidiCIConverter +import dev.atsushieno.ktmidi.ci.MidiCIDevice import dev.atsushieno.ktmidi.ci.json.Json import dev.atsushieno.ktmidi.ci.json.JsonParserException import dev.atsushieno.ktmidi.ci.toASCIIByteArray -abstract class CommonRulesPropertyHelper(protected val logger: Logger) { +internal class CommonRulesPropertyHelper(device: MidiCIDevice) { + val logger by device::logger + fun getPropertyIdentifierInternal(header: List): String { val json = try { Json.parse(MidiCIConverter.decodeASCIIToString(header.toByteArray().decodeToString())) @@ -32,7 +34,7 @@ abstract class CommonRulesPropertyHelper(protected val logger: Logger) { return result } - fun getResourceListRequestJson() = createRequestHeaderInternal(PropertyResourceNames.RESOURCE_LIST, mapOf()) + private fun getResourceListRequestJson() = createRequestHeader(PropertyResourceNames.RESOURCE_LIST, mapOf()) fun getResourceListRequestBytes(): List { val json = getResourceListRequestJson() @@ -41,7 +43,7 @@ abstract class CommonRulesPropertyHelper(protected val logger: Logger) { } private val partialSetPair = Pair(Json.JsonValue(PropertyCommonHeaderKeys.SET_PARTIAL), Json.TrueValue) - private fun createRequestHeaderInternal(resourceIdentifier: String, fields: Map): Json.JsonValue { + private fun createRequestHeader(resourceIdentifier: String, fields: Map): Json.JsonValue { val encoding = fields[PropertyCommonHeaderKeys.MUTUAL_ENCODING] as String? val isPartialSet = fields[PropertyCommonHeaderKeys.SET_PARTIAL] as Boolean? val paginateOffset = fields[PropertyCommonHeaderKeys.OFFSET] as Int? @@ -63,12 +65,12 @@ abstract class CommonRulesPropertyHelper(protected val logger: Logger) { } fun createRequestHeaderBytes(resourceIdentifier: String, fields: Map): List { - val json = createRequestHeaderInternal(resourceIdentifier, fields) + val json = createRequestHeader(resourceIdentifier, fields) val requestASCIIBytes = Json.getEscapedString(Json.serialize(json)).toASCIIByteArray().toList() return requestASCIIBytes } - private fun createSubscribeHeaderInternal(resourceIdentifier: String, command: String, mutualEncoding: String?): Json.JsonValue { + private fun createSubscribeHeader(resourceIdentifier: String, command: String, mutualEncoding: String?): Json.JsonValue { val resource = Pair( Json.JsonValue(PropertyCommonHeaderKeys.RESOURCE), Json.JsonValue(resourceIdentifier) @@ -87,7 +89,7 @@ abstract class CommonRulesPropertyHelper(protected val logger: Logger) { } fun createSubscribeHeaderBytes(resourceIdentifier: String, command: String, mutualEncoding: String?): List { - val json = createSubscribeHeaderInternal(resourceIdentifier, command, mutualEncoding) + val json = createSubscribeHeader(resourceIdentifier, command, mutualEncoding) val requestASCIIBytes = Json.getEscapedString(Json.serialize(json)).toASCIIByteArray().toList() return requestASCIIBytes } @@ -134,7 +136,7 @@ abstract class CommonRulesPropertyHelper(protected val logger: Logger) { return requestASCIIBytes } - internal fun encodeBodyInternal(data: List, encoding: String?): List { + internal fun encodeBody(data: List, encoding: String?): List { return when (encoding) { PropertyDataEncoding.ASCII -> data PropertyDataEncoding.MCODED7 -> PropertyCommonConverter.encodeToMcoded7(data) @@ -147,9 +149,9 @@ abstract class CommonRulesPropertyHelper(protected val logger: Logger) { } } - internal fun decodeBodyInternal(header: List, body: List): List = - decodeBodyInternal(getHeaderFieldString(header, PropertyCommonHeaderKeys.MUTUAL_ENCODING), body) - internal fun decodeBodyInternal(encoding: String?, body: List): List { + internal fun decodeBody(header: List, body: List): List = + decodeBody(getHeaderFieldString(header, PropertyCommonHeaderKeys.MUTUAL_ENCODING), body) + internal fun decodeBody(encoding: String?, body: List): List { return when (encoding) { PropertyDataEncoding.ASCII -> body PropertyDataEncoding.MCODED7 -> PropertyCommonConverter.decodeMcoded7(body) @@ -163,45 +165,3 @@ abstract class CommonRulesPropertyHelper(protected val logger: Logger) { } } -object PropertyPartialUpdater { - fun parseJsonPointer(s: String): List = - if (s.isNotEmpty() && s[0] == '/') - s.substring(1).split('/').map { it.replace("~1", "/").replace("~0", "~") } - else listOf() - - fun applyPartialUpdate(obj: Json.JsonValue, path: String, value: Json.JsonValue): Json.JsonValue = - applyPartialUpdate(obj, parseJsonPointer(path), value) - - fun applyPartialUpdate(obj: Json.JsonValue, jsonPointerPath: List, value: Json.JsonValue): Json.JsonValue = - patch(obj, jsonPointerPath, value) - - private fun patch(obj: Json.JsonValue, path: List, value: Json.JsonValue): Json.JsonValue { - val entry = path.firstOrNull() ?: return obj // path is empty - if (obj.token.type != Json.TokenType.Object) // obj is not an object - return obj - - val contextKey = obj.objectValue.keys.firstOrNull { it.stringValue == entry } - ?: return obj // specified path entry does not match - // replace context entry with new object which might be recursively alter the content with the new value - val replacement = if (path.size == 1) value else patch(obj.objectValue[contextKey]!!, path.drop(1), value) - val newMap = obj.objectValue.keys.map { - Pair(it, if (it == contextKey) replacement else obj.objectValue[it]!!) - } - return Json.JsonValue(newMap.toMap()) - } - - fun applyPartialUpdates(existingJson: Json.JsonValue, partialSpecJson: Json.JsonValue): Pair { - val failureReturn = Pair(false, existingJson) - if (partialSpecJson.token.type != Json.TokenType.Object) - return failureReturn // context should be JSON object - - var target = existingJson - // apply all partial updates - partialSpecJson.objectValue.keys.forEach { key -> - val path = if (key.token.type == Json.TokenType.String) key.stringValue else return Pair(false, existingJson) - val newValue = partialSpecJson.objectValue[key]!! - target = applyPartialUpdate(target, path, newValue) - } - return Pair(true, target) - } -} \ No newline at end of file diff --git a/ktmidi-ci/src/commonMain/kotlin/dev/atsushieno/ktmidi/ci/propertycommonrules/PropertyCommonRules.Service.kt b/ktmidi-ci/src/commonMain/kotlin/dev/atsushieno/ktmidi/ci/propertycommonrules/PropertyCommonRules.Service.kt index 5011efa71..3564b5c56 100644 --- a/ktmidi-ci/src/commonMain/kotlin/dev/atsushieno/ktmidi/ci/propertycommonrules/PropertyCommonRules.Service.kt +++ b/ktmidi-ci/src/commonMain/kotlin/dev/atsushieno/ktmidi/ci/propertycommonrules/PropertyCommonRules.Service.kt @@ -3,6 +3,7 @@ package dev.atsushieno.ktmidi.ci.propertycommonrules import dev.atsushieno.ktmidi.ci.* import dev.atsushieno.ktmidi.ci.json.Json import dev.atsushieno.ktmidi.ci.json.JsonParserException +import kotlin.jvm.JvmName import kotlin.random.Random private val defaultPropertyList = listOf( @@ -45,21 +46,33 @@ fun CommonRulesPropertyMetadata.toJsonValue(): Json.JsonValue = Json.JsonValue( }.toMap() ) -class CommonRulesPropertyService(logger: Logger, private val muid: Int, var deviceInfo: MidiCIDeviceInfo, - private val values: MutableList, - private val metadataList: MutableList = mutableListOf(), - private val channelList: Json.JsonValue? = null, - private val jsonSchema: Json.JsonValue? = null - ) - : CommonRulesPropertyHelper(logger), MidiCIServicePropertyRules { +class CommonRulesPropertyService(private val device: MidiCIDevice) + : MidiCIServicePropertyRules { + private val helper = CommonRulesPropertyHelper(device) + private val logger by device::logger + private val muid by device::muid + internal var deviceInfo + @JvmName("get_deviceInfo") + get() = device.config.deviceInfo + @JvmName("set_deviceInfo") + set(value) { device.config.deviceInfo = value } + private val values + @JvmName("get_propertyValues") + get() = device.config.propertyValues + private val metadataList + @JvmName("get_metadataList") + get() = device.config.propertyMetadataList + private val channelList: Json.JsonValue? = null + private val jsonSchema: Json.JsonValue? = null // MidiCIPropertyService implementation override val subscriptions = mutableListOf() - override fun getPropertyIdForHeader(header: List) = getPropertyIdentifierInternal(header) + override fun getPropertyIdForHeader(header: List) = helper.getPropertyIdentifierInternal(header) + override fun getHeaderFieldString(header: List, field: String) = helper.getHeaderFieldString(header, field) override fun createUpdateNotificationHeader(propertyId: String, fields: Map) = - createSubscribePropertyHeaderBytes( + helper.createSubscribePropertyHeaderBytes( fields[PropertyCommonHeaderKeys.SUBSCRIBE_ID] as String, if (fields[PropertyCommonHeaderKeys.SET_PARTIAL] as Boolean) MidiCISubscriptionCommand.PARTIAL else MidiCISubscriptionCommand.FULL @@ -136,7 +149,7 @@ class CommonRulesPropertyService(logger: Logger, private val muid: Int, var devi override fun createShutdownSubscriptionHeader(propertyId: String): List { val sub = subscriptions.firstOrNull { it.resource == propertyId } ?: throw MidiCIException("Specified property $propertyId is not at subscribed state") - val header = createSubscribePropertyHeaderBytes(sub.subscribeId, MidiCISubscriptionCommand.END) + val header = helper.createSubscribePropertyHeaderBytes(sub.subscribeId, MidiCISubscriptionCommand.END) subscriptions.remove(sub) return header } @@ -301,7 +314,7 @@ class CommonRulesPropertyService(logger: Logger, private val muid: Int, var devi return Pair(getReplyHeaderJson(PropertyCommonReplyHeader(PropertyExchangeStatus.OK, subscribeId = subscribeId)), Json.JsonValue(mapOf())) } - override fun encodeBody(data: List, encoding: String?): List = encodeBodyInternal(data, encoding) - override fun decodeBody(header: List, body: List): List = decodeBodyInternal(header, body) - private fun decodeBody(mutualEncoding: String?, body: List): List = decodeBodyInternal(mutualEncoding, body) + override fun encodeBody(data: List, encoding: String?): List = helper.encodeBody(data, encoding) + override fun decodeBody(header: List, body: List): List = helper.decodeBody(header, body) + private fun decodeBody(mutualEncoding: String?, body: List): List = helper.decodeBody(mutualEncoding, body) } \ No newline at end of file