From 217f347c4bca2cf092e2d958d458c37874a14a37 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 12 Apr 2020 13:51:18 +0300 Subject: [PATCH] Fix Json schema generator --- .../kotlin/hep/dataforge/vis/spatial/World.kt | 10 -- .../hep/dataforge/vis/spatial/geometry.kt | 8 ++ .../dataforge/vis/spatial}/generateSchema.kt | 99 +++++++++++++------ 3 files changed, 75 insertions(+), 42 deletions(-) delete mode 100644 dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/World.kt rename {dataforge-vis-spatial-gdml/src/jvmMain/kotlin/hep/dataforge/vis/spatial/gdml => dataforge-vis-spatial/src/jvmMain/kotlin/hep/dataforge/vis/spatial}/generateSchema.kt (62%) diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/World.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/World.kt deleted file mode 100644 index bc946987..00000000 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/World.kt +++ /dev/null @@ -1,10 +0,0 @@ -package hep.dataforge.vis.spatial - -import kotlin.math.PI - -object World { - val ZERO = Point3D(0.0, 0.0, 0.0) - val ONE = Point3D(1.0, 1.0, 1.0) -} - -const val PI2: Float = 2 * PI.toFloat() \ No newline at end of file diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/geometry.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/geometry.kt index 85d5466a..f88528bb 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/geometry.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/geometry.kt @@ -3,6 +3,14 @@ package hep.dataforge.vis.spatial import hep.dataforge.meta.Meta import hep.dataforge.meta.get import hep.dataforge.meta.number +import kotlin.math.PI + +object World { + val ZERO = Point3D(0.0, 0.0, 0.0) + val ONE = Point3D(1.0, 1.0, 1.0) +} + +const val PI2: Float = 2 * PI.toFloat() expect class Point2D(x: Number, y: Number) { var x: Double diff --git a/dataforge-vis-spatial-gdml/src/jvmMain/kotlin/hep/dataforge/vis/spatial/gdml/generateSchema.kt b/dataforge-vis-spatial/src/jvmMain/kotlin/hep/dataforge/vis/spatial/generateSchema.kt similarity index 62% rename from dataforge-vis-spatial-gdml/src/jvmMain/kotlin/hep/dataforge/vis/spatial/gdml/generateSchema.kt rename to dataforge-vis-spatial/src/jvmMain/kotlin/hep/dataforge/vis/spatial/generateSchema.kt index b9d4fc48..54a2c08d 100644 --- a/dataforge-vis-spatial-gdml/src/jvmMain/kotlin/hep/dataforge/vis/spatial/gdml/generateSchema.kt +++ b/dataforge-vis-spatial/src/jvmMain/kotlin/hep/dataforge/vis/spatial/generateSchema.kt @@ -1,24 +1,24 @@ -package hep.dataforge.vis.spatial.gdml +package hep.dataforge.vis.spatial import hep.dataforge.meta.JSON_PRETTY -import hep.dataforge.meta.Meta -import hep.dataforge.vis.spatial.* import kotlinx.serialization.* import kotlinx.serialization.json.* import kotlinx.serialization.modules.SerialModule import kotlinx.serialization.modules.SerialModuleCollector import kotlin.reflect.KClass -internal val SerialDescriptor.jsonType - get() = when (this.kind) { - StructureKind.LIST -> "array" - PrimitiveKind.BYTE, PrimitiveKind.SHORT, PrimitiveKind.INT, PrimitiveKind.LONG, - PrimitiveKind.FLOAT, PrimitiveKind.DOUBLE -> "number" - PrimitiveKind.STRING, PrimitiveKind.CHAR, UnionKind.ENUM_KIND -> "string" - PrimitiveKind.BOOLEAN -> "boolean" - else -> "object" - } +private fun SerialDescriptor.getJsonType() = when (this.kind) { + StructureKind.LIST -> "array" + PrimitiveKind.BYTE, PrimitiveKind.SHORT, PrimitiveKind.INT, PrimitiveKind.LONG, + PrimitiveKind.FLOAT, PrimitiveKind.DOUBLE -> "number" + PrimitiveKind.STRING, PrimitiveKind.CHAR, UnionKind.ENUM_KIND -> "string" + PrimitiveKind.BOOLEAN -> "boolean" + else -> "object" +} +private fun SerialDescriptor.isVisualObject() = serialName.startsWith("3d")||serialName.startsWith("group") + +private const val definitionNode = "\$defs" private fun SerialModule.enumerate(type: KClass<*>): Sequence { val list = ArrayList() @@ -63,11 +63,14 @@ private fun jsonSchema(descriptor: SerialDescriptor, context: SerialModule): Jso if (descriptor.serialName in arrayOf( "hep.dataforge.vis.spatial.Point3D", + "hep.dataforge.vis.spatial.Point3D?", "hep.dataforge.vis.spatial.Point2D", - Meta::class.qualifiedName + "hep.dataforge.vis.spatial.Point2D?", + "hep.dataforge.meta.Meta", + "hep.dataforge.meta.Meta?" ) ) return json { - "\$ref" to "#/definitions/${descriptor.serialName}" + "\$ref" to "#/$definitionNode/${descriptor.serialName.replace("?", "")}" } @@ -80,35 +83,33 @@ private fun jsonSchema(descriptor: SerialDescriptor, context: SerialModule): Jso if (!isEnum && !isPolymorphic) descriptor.elementDescriptors().forEachIndexed { index, child -> val elementName = descriptor.getElementName(index) - properties[elementName] = when (elementName) { - "templates" -> json { - "\$ref" to "#/definitions/hep.dataforge.vis.spatial.VisualGroup3D" + val elementSchema = when (elementName) { + "properties" -> json { + "\$ref" to "#/$definitionNode/hep.dataforge.meta.Meta" } - "properties" -> json { - "\$ref" to "#/definitions/${Meta::class.qualifiedName}" - } - "first", "second" -> json{ - "\$ref" to "#/definitions/children" + "first", "second" -> json { + "\$ref" to "#/$definitionNode/children" } "styleSheet" -> json { "type" to "object" "additionalProperties" to json { - "\$ref" to "#/definitions/${Meta::class.qualifiedName}" + "\$ref" to "#/$definitionNode/hep.dataforge.meta.Meta" } } - in arrayOf("children") -> json { + in arrayOf("children", "prototypes") -> json { "type" to "object" "additionalProperties" to json { - "\$ref" to "#/definitions/children" + "\$ref" to "#/$definitionNode/children" } } else -> jsonSchema(child, context) } + properties[elementName] = elementSchema if (!descriptor.isElementOptional(index)) requiredProperties.add(elementName) } - val jsonType = descriptor.jsonType + val jsonType = descriptor.getJsonType() val objectData: MutableMap = mutableMapOf( "description" to JsonLiteral(descriptor.serialName), "type" to JsonLiteral(jsonType) @@ -119,6 +120,11 @@ private fun jsonSchema(descriptor: SerialDescriptor, context: SerialModule): Jso } when (jsonType) { "object" -> { + if(descriptor.isVisualObject()) { + properties["type"] = json { + "const" to descriptor.serialName + } + } objectData["properties"] = JsonObject(properties) val required = requiredProperties.map { JsonLiteral(it) } if (required.isNotEmpty()) { @@ -143,7 +149,7 @@ fun main() { context.enumerate(VisualObject3D::class).forEach { if (it.serialName == "hep.dataforge.vis.spatial.VisualGroup3D") { +json { - "\$ref" to "#/definitions/${it.serialName}" + "\$ref" to "#/$definitionNode/${it.serialName}" } } else { +jsonSchema(it, context) @@ -151,9 +157,38 @@ fun main() { } } } - "hep.dataforge.vis.spatial.Point3D" to jsonSchema(Point3DSerializer.descriptor, context) - "hep.dataforge.vis.spatial.Point2D" to jsonSchema(Point2DSerializer.descriptor, context) - "hep.dataforge.vis.spatial.VisualGroup3D" to jsonSchema(VisualGroup3D.serializer().descriptor, context) + "hep.dataforge.meta.Meta" to json { + "type" to "object" + } + "hep.dataforge.vis.spatial.Point3D" to json { + "type" to "object" + "properties" to json { + "x" to json { + "type" to "number" + } + "y" to json { + "type" to "number" + } + "z" to json { + "type" to "number" + } + } + } + "hep.dataforge.vis.spatial.Point2D" to json { + "type" to "object" + "properties" to json { + "x" to json { + "type" to "number" + } + "y" to json { + "type" to "number" + } + } + } + "hep.dataforge.vis.spatial.VisualGroup3D" to jsonSchema( + VisualGroup3D.serializer().descriptor, + context + ) } @@ -161,8 +196,8 @@ fun main() { JSON_PRETTY.stringify( JsonObjectSerializer, json { - "definitions" to definitions - "\$ref" to "#/definitions/hep.dataforge.vis.spatial.VisualGroup3D" + "\$defs" to definitions + "\$ref" to "#/$definitionNode/hep.dataforge.vis.spatial.VisualGroup3D" } ) )