diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/json/JsonVssParser.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/json/JsonVssParser.kt index 64c00c8b..ee256f67 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/json/JsonVssParser.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/json/JsonVssParser.kt @@ -35,9 +35,8 @@ import org.eclipse.kuksa.vssprocessor.parser.ROOT_KEY_VEHICLE import org.eclipse.kuksa.vssprocessor.parser.VSS_DATA_KEYS import org.eclipse.kuksa.vssprocessor.parser.VssParser import org.eclipse.kuksa.vssprocessor.spec.VssDataType -import org.eclipse.kuksa.vssprocessor.spec.VssNodeProperty +import org.eclipse.kuksa.vssprocessor.spec.VssNodePropertiesBuilder import org.eclipse.kuksa.vssprocessor.spec.VssNodeSpecModel -import org.eclipse.kuksa.vssprocessor.spec.VssSignalProperty import java.io.File import java.io.IOException @@ -111,16 +110,14 @@ internal class JsonVssParser : VssParser { val vssDataType = VssDataType.find(datatype) val valueDataType = vssDataType.valueDataType - val vssNodeProperties = mutableSetOf( - VssNodeProperty(vssPath, KEY_DATA_UUID, uuid, String::class), - VssNodeProperty(vssPath, KEY_DATA_TYPE, type, String::class), - VssNodeProperty(vssPath, KEY_DATA_DESCRIPTION, description, String::class), - VssNodeProperty(vssPath, KEY_DATA_COMMENT, comment, String::class), - VssSignalProperty(vssPath, KEY_DATA_DATATYPE, datatype, valueDataType), - VssSignalProperty(vssPath, KEY_DATA_UNIT, unit, String::class), - VssSignalProperty(vssPath, KEY_DATA_MIN, min, valueDataType), - VssSignalProperty(vssPath, KEY_DATA_MAX, max, valueDataType), - ) + val vssNodeProperties = VssNodePropertiesBuilder(uuid, type) + .withDescription(description) + .withComment(comment) + .withDataType(datatype) + .withUnit(unit) + .withMin(min, valueDataType) + .withMax(max, valueDataType) + .build() return VssNodeSpecModel(vssPath, vssNodeProperties) } diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/yaml/YamlVssParser.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/yaml/YamlVssParser.kt index ca66dc0b..7f5c981c 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/yaml/YamlVssParser.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/yaml/YamlVssParser.kt @@ -30,9 +30,8 @@ import org.eclipse.kuksa.vssprocessor.parser.KEY_DATA_UNIT import org.eclipse.kuksa.vssprocessor.parser.KEY_DATA_UUID import org.eclipse.kuksa.vssprocessor.parser.VssParser import org.eclipse.kuksa.vssprocessor.spec.VssDataType -import org.eclipse.kuksa.vssprocessor.spec.VssNodeProperty +import org.eclipse.kuksa.vssprocessor.spec.VssNodePropertiesBuilder import org.eclipse.kuksa.vssprocessor.spec.VssNodeSpecModel -import org.eclipse.kuksa.vssprocessor.spec.VssSignalProperty import java.io.File import java.io.IOException @@ -102,16 +101,14 @@ internal class YamlVssParser(private val elementDelimiter: String = "") : VssPar val vssDataType = VssDataType.find(datatype) val valueDataType = vssDataType.valueDataType - val vssNodeProperties = mutableSetOf( - VssNodeProperty(vssPath, KEY_DATA_UUID, uuid, String::class), - VssNodeProperty(vssPath, KEY_DATA_TYPE, type, String::class), - VssNodeProperty(vssPath, KEY_DATA_DESCRIPTION, description, String::class), - VssNodeProperty(vssPath, KEY_DATA_COMMENT, comment, String::class), - VssSignalProperty(vssPath, KEY_DATA_DATATYPE, datatype, valueDataType), - VssSignalProperty(vssPath, KEY_DATA_UNIT, unit, String::class), - VssSignalProperty(vssPath, KEY_DATA_MIN, min, valueDataType), - VssSignalProperty(vssPath, KEY_DATA_MAX, max, valueDataType), - ) + val vssNodeProperties = VssNodePropertiesBuilder(uuid, type) + .withDescription(description) + .withComment(comment) + .withDataType(datatype) + .withUnit(unit) + .withMin(min, valueDataType) + .withMax(max, valueDataType) + .build() return VssNodeSpecModel(vssPath, vssNodeProperties) } diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodePropertiesBuilder.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodePropertiesBuilder.kt new file mode 100644 index 00000000..a29e9037 --- /dev/null +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodePropertiesBuilder.kt @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2023 - 2024 Contributors to the Eclipse Foundation + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +package org.eclipse.kuksa.vssprocessor.spec + +import org.eclipse.kuksa.vssprocessor.parser.KEY_DATA_COMMENT +import org.eclipse.kuksa.vssprocessor.parser.KEY_DATA_DATATYPE +import org.eclipse.kuksa.vssprocessor.parser.KEY_DATA_DESCRIPTION +import org.eclipse.kuksa.vssprocessor.parser.KEY_DATA_MAX +import org.eclipse.kuksa.vssprocessor.parser.KEY_DATA_MIN +import org.eclipse.kuksa.vssprocessor.parser.KEY_DATA_TYPE +import org.eclipse.kuksa.vssprocessor.parser.KEY_DATA_UNIT +import org.eclipse.kuksa.vssprocessor.parser.KEY_DATA_UUID +import kotlin.reflect.KClass + +internal class VssNodePropertiesBuilder( + uuid: String, + type: String, +) { + private val nodePropertyMap: MutableMap = mutableMapOf() + + init { + val uuidNodeProperty = VssNodeProperty(KEY_DATA_UUID, uuid, String::class) + nodePropertyMap[KEY_DATA_UUID] = uuidNodeProperty + + val typeNodeProperty = VssNodeProperty(KEY_DATA_TYPE, type, String::class) + nodePropertyMap[KEY_DATA_TYPE] = typeNodeProperty + } + + fun withDescription(description: String?): VssNodePropertiesBuilder { + if (description == null) return this + + val nodeProperty = VssNodeProperty(KEY_DATA_DESCRIPTION, description, String::class) + nodePropertyMap[KEY_DATA_DESCRIPTION] = nodeProperty + + return this + } + + fun withComment(comment: String?): VssNodePropertiesBuilder { + if (comment == null) return this + + val nodeProperty = VssNodeProperty(KEY_DATA_COMMENT, comment, String::class) + nodePropertyMap[KEY_DATA_COMMENT] = nodeProperty + + return this + } + + fun withDataType(dataType: String?): VssNodePropertiesBuilder { + if (dataType == null) return this + + val vssDataType = VssDataType.find(dataType) + val valueDataType = vssDataType.valueDataType + + val signalProperty = VssSignalProperty(KEY_DATA_DATATYPE, dataType, valueDataType) + nodePropertyMap[KEY_DATA_DATATYPE] = signalProperty + + return this + } + + fun withUnit(unit: String?): VssNodePropertiesBuilder { + if (unit == null) return this + + val signalProperty = VssSignalProperty(KEY_DATA_UNIT, unit, String::class) + nodePropertyMap[KEY_DATA_UNIT] = signalProperty + + return this + } + + fun withMin(min: String?, clazz: KClass<*>): VssNodePropertiesBuilder { + if (min == null) return this + + val signalProperty = VssSignalProperty(KEY_DATA_MIN, min, clazz) + nodePropertyMap[KEY_DATA_MIN] = signalProperty + + return this + } + + fun withMin(min: String?, dataType: String): VssNodePropertiesBuilder { + if (min == null) return this + + val vssDataType = VssDataType.find(dataType) + val valueDataType = vssDataType.valueDataType + + return withMin(min, valueDataType) + } + + fun withMax(max: String?, clazz: KClass<*>): VssNodePropertiesBuilder { + if (max == null) return this + + val maxSignalProperty = VssSignalProperty(KEY_DATA_MAX, max, clazz) + nodePropertyMap[KEY_DATA_MAX] = maxSignalProperty + + return this + } + + fun withMax(max: String?, dataType: String): VssNodePropertiesBuilder { + if (max == null) return this + + val vssDataType = VssDataType.find(dataType) + val valueDataType = vssDataType.valueDataType + + return withMax(max, valueDataType) + } + + fun build(): Set { + return nodePropertyMap.values.toSet() + } +} diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeProperty.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeProperty.kt index 78eaf277..ffbc0f1b 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeProperty.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeProperty.kt @@ -21,8 +21,7 @@ package org.eclipse.kuksa.vssprocessor.spec import kotlin.reflect.KClass -open class VssNodeProperty( - val vssPath: String, +internal open class VssNodeProperty( val nodePropertyName: String, val nodePropertyValue: String, val dataType: KClass<*>, @@ -43,11 +42,10 @@ open class VssNodeProperty( } } -class VssSignalProperty( - vssPath: String, +internal class VssSignalProperty( nodePropertyName: String, nodePropertyValue: String, dataType: KClass<*>, -) : VssNodeProperty(vssPath, nodePropertyName, nodePropertyValue, dataType) { +) : VssNodeProperty(nodePropertyName, nodePropertyValue, dataType) { override val isCommon: Boolean = false } diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt index 6704f991..0ba8ec4e 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt @@ -42,6 +42,11 @@ import org.eclipse.kuksa.vsscore.model.name import org.eclipse.kuksa.vsscore.model.parentClassName import org.eclipse.kuksa.vsscore.model.parentKey import org.eclipse.kuksa.vsscore.model.variableName +import org.eclipse.kuksa.vssprocessor.parser.KEY_DATA_COMMENT +import org.eclipse.kuksa.vssprocessor.parser.KEY_DATA_DATATYPE +import org.eclipse.kuksa.vssprocessor.parser.KEY_DATA_DESCRIPTION +import org.eclipse.kuksa.vssprocessor.parser.KEY_DATA_TYPE +import org.eclipse.kuksa.vssprocessor.parser.KEY_DATA_UUID import org.eclipse.kuksa.vssprocessor.spec.VssNodeProperty.* import kotlin.reflect.KClass import kotlin.reflect.KProperty1 @@ -54,11 +59,11 @@ internal class VssNodeSpecModel( private val propertyNameToNodePropertyMap = vssNodeProperties.associateBy { it.nodePropertyName } - override var uuid: String = propertyNameToNodePropertyMap["uuid"]?.nodePropertyValue ?: "" - override var type: String = propertyNameToNodePropertyMap["type"]?.nodePropertyValue ?: "" - override var description: String = propertyNameToNodePropertyMap["description"]?.nodePropertyValue ?: "" - override var comment: String = propertyNameToNodePropertyMap["comment"]?.nodePropertyValue ?: "" - var datatype: String = propertyNameToNodePropertyMap["datatype"]?.nodePropertyValue ?: "" + override var uuid: String = propertyNameToNodePropertyMap[KEY_DATA_UUID]?.nodePropertyValue ?: "" + override var type: String = propertyNameToNodePropertyMap[KEY_DATA_TYPE]?.nodePropertyValue ?: "" + override var description: String = propertyNameToNodePropertyMap[KEY_DATA_DESCRIPTION]?.nodePropertyValue ?: "" + override var comment: String = propertyNameToNodePropertyMap[KEY_DATA_COMMENT]?.nodePropertyValue ?: "" + var datatype: String = propertyNameToNodePropertyMap[KEY_DATA_DATATYPE]?.nodePropertyValue ?: "" var logger: KSPLogger? = null diff --git a/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModelTest.kt b/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModelTest.kt index b80b819f..86edf092 100644 --- a/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModelTest.kt +++ b/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModelTest.kt @@ -22,27 +22,25 @@ import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNotBe import io.kotest.matchers.string.shouldContain -import org.eclipse.kuksa.vssprocessor.parser.KEY_DATA_DATATYPE -import org.eclipse.kuksa.vssprocessor.parser.KEY_DATA_MAX -import org.eclipse.kuksa.vssprocessor.parser.KEY_DATA_MIN - -private const val TYPE_ANY = "any" -private const val TYPE_STRING = "string" -private const val TYPE_STRING_ARRAY = "string[]" -private const val TYPE_BOOLEAN = "boolean" -private const val TYPE_BOOLEAN_ARRAY = "boolean[]" -private const val TYPE_FLOAT = "float" -private const val TYPE_INT64 = "int64" -private const val TYPE_UINT32 = "uint32" -private const val TYPE_INT32 = "int32" -private const val TYPE_UINT64_ARRAY = "uint64[]" -private const val TYPE_INVALID = "invalid" +import java.util.UUID + +private const val DATATYPE_ANY = "any" +private const val DATATYPE_STRING = "string" +private const val DATATYPE_STRING_ARRAY = "string[]" +private const val DATATYPE_BOOLEAN = "boolean" +private const val DATATYPE_BOOLEAN_ARRAY = "boolean[]" +private const val DATATYPE_FLOAT = "float" +private const val DATATYPE_INT64 = "int64" +private const val DATATYPE_UINT32 = "uint32" +private const val DATATYPE_INT32 = "int32" +private const val DATATYPE_UINT64_ARRAY = "uint64[]" +private const val DATATYPE_INVALID = "invalid" class VssNodeSpecModelTest : BehaviorSpec({ given("String spec model") { - val vssNodeProperties = setOf( - createSignalProperty(KEY_DATA_DATATYPE, TYPE_STRING, TYPE_STRING), - ) + val vssNodeProperties = createNodePropertiesBuilder() + .withDataType(DATATYPE_STRING) + .build() val specModel = VssNodeSpecModel(vssPath = "Vehicle.IgnitionType", vssNodeProperties) `when`("creating a class spec") { @@ -57,11 +55,12 @@ class VssNodeSpecModelTest : BehaviorSpec({ } given("int64 spec model with min and max values") { - val vssNodeProperties = setOf( - createSignalProperty(KEY_DATA_DATATYPE, TYPE_INT64, TYPE_INT64), - createSignalProperty(KEY_DATA_MIN, "0", TYPE_INT64), - createSignalProperty(KEY_DATA_MAX, "100", TYPE_INT64), - ) + val vssNodeProperties = createNodePropertiesBuilder() + .withDataType(DATATYPE_INT64) + .withMin("0", DATATYPE_INT64) + .withMax("100", DATATYPE_INT64) + .build() + val specModel = VssNodeSpecModel(vssPath = "Vehicle.IgnitionType", vssNodeProperties) `when`("creating a class spec") { @@ -90,11 +89,12 @@ class VssNodeSpecModelTest : BehaviorSpec({ } given("uint32 spec model (inline class)") { - val vssNodeProperties = setOf( - createSignalProperty(KEY_DATA_DATATYPE, TYPE_UINT32, TYPE_UINT32), - createSignalProperty(KEY_DATA_MIN, "0", TYPE_UINT32), - createSignalProperty(KEY_DATA_MAX, "100", TYPE_UINT32), - ) + val vssNodeProperties = createNodePropertiesBuilder() + .withDataType(DATATYPE_UINT32) + .withMin("0", DATATYPE_UINT32) + .withMax("100", DATATYPE_UINT32) + .build() + val specModel = VssNodeSpecModel(vssPath = "Vehicle.IgnitionType", vssNodeProperties) `when`("creating a class spec") { @@ -129,11 +129,11 @@ class VssNodeSpecModelTest : BehaviorSpec({ } given("int32 spec model with min and max values") { - val vssNodeProperties = setOf( - createSignalProperty(KEY_DATA_DATATYPE, TYPE_INT32, TYPE_INT32), - createSignalProperty(KEY_DATA_MIN, "0", TYPE_INT32), - createSignalProperty(KEY_DATA_MAX, "100", TYPE_INT32), - ) + val vssNodeProperties = createNodePropertiesBuilder() + .withDataType(DATATYPE_INT32) + .withMin("0", DATATYPE_INT32) + .withMax("100", DATATYPE_INT32) + .build() val specModel = VssNodeSpecModel(vssPath = "Vehicle.IgnitionType", vssNodeProperties) `when`("creating a class spec") { @@ -162,9 +162,9 @@ class VssNodeSpecModelTest : BehaviorSpec({ } given("uint64[] spec model") { - val vssNodeProperties = setOf( - createSignalProperty(KEY_DATA_DATATYPE, TYPE_UINT64_ARRAY, TYPE_UINT64_ARRAY), - ) + val vssNodeProperties = createNodePropertiesBuilder() + .withDataType(DATATYPE_UINT64_ARRAY) + .build() val specModel = VssNodeSpecModel(vssPath = "Vehicle.IgnitionType", vssNodeProperties) @@ -186,9 +186,10 @@ class VssNodeSpecModelTest : BehaviorSpec({ } given("String[] spec model") { - val vssNodeProperties = setOf( - createSignalProperty(KEY_DATA_DATATYPE, TYPE_STRING_ARRAY, TYPE_STRING_ARRAY), - ) + val vssNodeProperties = createNodePropertiesBuilder() + .withDataType(DATATYPE_STRING_ARRAY) + .build() + val specModel = VssNodeSpecModel(vssPath = "Vehicle.IgnitionType", vssNodeProperties) `when`("creating a class spec") { @@ -203,9 +204,9 @@ class VssNodeSpecModelTest : BehaviorSpec({ } given("Boolean[] spec model") { - val vssNodeProperties = setOf( - createSignalProperty(KEY_DATA_DATATYPE, TYPE_BOOLEAN_ARRAY, TYPE_BOOLEAN_ARRAY), - ) + val vssNodeProperties = createNodePropertiesBuilder() + .withDataType(DATATYPE_BOOLEAN_ARRAY) + .build() val specModel = VssNodeSpecModel(vssPath = "Vehicle.IgnitionType", vssNodeProperties) @@ -221,9 +222,9 @@ class VssNodeSpecModelTest : BehaviorSpec({ } given("Any spec model") { - val vssNodeProperties = setOf( - createSignalProperty(KEY_DATA_DATATYPE, TYPE_ANY, TYPE_ANY), - ) + val vssNodeProperties = createNodePropertiesBuilder() + .withDataType(DATATYPE_ANY) + .build() val specModel = VssNodeSpecModel(vssPath = "Vehicle.IgnitionType", vssNodeProperties) @@ -254,40 +255,36 @@ class VssNodeSpecModelTest : BehaviorSpec({ val vehicleSpeedSpecModel = VssNodeSpecModel( vssPath = "Vehicle.Speed", - vssNodeProperties = setOf(createSignalProperty(KEY_DATA_DATATYPE, TYPE_FLOAT, TYPE_FLOAT)), + vssNodeProperties = createNodePropertiesBuilder() + .withDataType(DATATYPE_FLOAT) + .build(), ) val relatedVssNodes = listOf( VssNodeSpecModel(vssPath = "Vehicle.SmartphoneProjection", setOf()), VssNodeSpecModel( vssPath = "Vehicle.IsBrokenDown", - vssNodeProperties = setOf( - createSignalProperty( - KEY_DATA_DATATYPE, - TYPE_BOOLEAN, - TYPE_BOOLEAN, - ), - ), + vssNodeProperties = createNodePropertiesBuilder() + .withDataType(DATATYPE_BOOLEAN) + .build(), ), vehicleSpeedSpecModel, VssNodeSpecModel( vssPath = "Vehicle.SupportedMode", - vssNodeProperties = setOf( - createSignalProperty(KEY_DATA_DATATYPE, TYPE_STRING_ARRAY, TYPE_STRING_ARRAY), - ), + vssNodeProperties = createNodePropertiesBuilder() + .withDataType(DATATYPE_STRING_ARRAY) + .build(), ), VssNodeSpecModel( vssPath = "Vehicle.AreSeatsHeated", - vssNodeProperties = setOf( - createSignalProperty( - KEY_DATA_DATATYPE, - TYPE_BOOLEAN_ARRAY, - TYPE_BOOLEAN_ARRAY, - ), - ), + vssNodeProperties = createNodePropertiesBuilder() + .withDataType(DATATYPE_BOOLEAN_ARRAY) + .build(), ), VssNodeSpecModel( vssPath = "Vehicle.Invalid", - vssNodeProperties = setOf(createSignalProperty(KEY_DATA_DATATYPE, TYPE_INVALID, TYPE_INVALID)), + vssNodeProperties = createNodePropertiesBuilder() + .withDataType(DATATYPE_INVALID) + .build(), ), ) @@ -342,16 +339,8 @@ class VssNodeSpecModelTest : BehaviorSpec({ } }) -private fun createSignalProperty( - propertyName: String, - propertyValue: String, - propertyType: String, -): VssNodeProperty { - val vssDataType = VssDataType.find(propertyType) - return VssSignalProperty( - vssPath = "Vehicle.ADAS.ABS.IsEnabled", - nodePropertyName = propertyName, - nodePropertyValue = propertyValue, - dataType = vssDataType.valueDataType, - ) +private fun createNodePropertiesBuilder(): VssNodePropertiesBuilder { + val randomUuid = UUID.randomUUID() + val uuidString = randomUuid.toString() + return VssNodePropertiesBuilder(uuidString, "signal") }