You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by jo...@apache.org on 2021/05/10 07:11:40 UTC

[isis] 03/12: convert xml to json for plantuml json diagram

This is an automated email from the ASF dual-hosted git repository.

joergrade pushed a commit to branch ISIS-2505_Catch_Up_With_Demo_Examples
in repository https://gitbox.apache.org/repos/asf/isis.git

commit f6adc4e60aeb464dc59b6c0d66d343b2510e7569
Author: Jörg Rade <jo...@kuehne-nagel.com>
AuthorDate: Mon Apr 26 17:29:53 2021 +0200

    convert xml to json for plantuml json diagram
---
 incubator/clients/kroviz/build.gradle.kts          |  1 +
 .../kotlin/org/apache/isis/client/kroviz/App.kt    |  1 -
 .../client/kroviz/core/aggregator/SvgDispatcher.kt |  2 +-
 .../isis/client/kroviz/core/event/EventStore.kt    |  7 +++
 .../apache/isis/client/kroviz/ui/DiagramDialog.kt  | 60 ++++++++++++----------
 .../apache/isis/client/kroviz/ui/EventLogDetail.kt | 15 ++++--
 .../isis/client/kroviz/ui/kv/FormPanelFactory.kt   |  1 -
 .../client/kroviz/utils/ScalableVectorGraphic.kt   | 15 ++++++
 .../apache/isis/client/kroviz/utils/XmlHelper.kt   | 11 +++-
 .../SvgDispatcher.kt => utils/XmlToJson.kt}        | 23 +++------
 .../isis/client/kroviz/snapshots/TestRequest.kt    |  1 -
 .../isis/client/kroviz/util/XmlHelperTest.kt}      | 30 ++++++-----
 12 files changed, 99 insertions(+), 68 deletions(-)

diff --git a/incubator/clients/kroviz/build.gradle.kts b/incubator/clients/kroviz/build.gradle.kts
index 2858b5e..a2c2e47 100644
--- a/incubator/clients/kroviz/build.gradle.kts
+++ b/incubator/clients/kroviz/build.gradle.kts
@@ -88,6 +88,7 @@ kotlin {
         implementation("io.kvision:kvision-pace:$kvisionVersion")
         implementation("io.kvision:kvision-moment:$kvisionVersion")
         implementation("io.kvision:kvision-maps:$kvisionVersion")
+        implementation(npm("xmltojson", "1.3.5", false))
     }
     sourceSets["test"].dependencies {
         implementation(kotlin("test-js"))
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/App.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/App.kt
index 8e8dad6..3162eb9 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/App.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/App.kt
@@ -31,7 +31,6 @@ class App : Application() {
 
     init {
         require("css/kroviz.css")
-//        require("lodash")
     }
 
     override fun start() {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/SvgDispatcher.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/SvgDispatcher.kt
index 380952e..13bb28f 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/SvgDispatcher.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/SvgDispatcher.kt
@@ -23,7 +23,7 @@ import org.apache.isis.client.kroviz.ui.kv.MapPanel
 import org.apache.isis.client.kroviz.utils.DomUtil
 import org.apache.isis.client.kroviz.utils.UUID
 
-class SvgDispatcher(private val callBack: Any) : BaseAggregator() {
+class SvgDispatcher(val callBack: Any) : BaseAggregator() {
 
     override fun update(logEntry: LogEntry, subType: String) {
         val response = logEntry.response
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/EventStore.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/EventStore.kt
index bfed6aa..4e72a2b 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/EventStore.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/EventStore.kt
@@ -24,6 +24,8 @@ import org.apache.isis.client.kroviz.to.mb.Menubars
 import org.apache.isis.client.kroviz.ui.kv.UiManager
 import io.kvision.panel.SimplePanel
 import io.kvision.state.observableListOf
+import org.apache.isis.client.kroviz.core.aggregator.SvgDispatcher
+import org.apache.isis.client.kroviz.utils.UUID
 
 /**
  * Keeps a log of remote invocations and the responses.
@@ -126,6 +128,11 @@ object EventStore {
         return log.firstOrNull { it.getAggregator() == aggregator }
     }
 
+    fun findBy(uuid: UUID): LogEntry {
+        return log.first { it.getAggregator() is SvgDispatcher
+                && (it.getAggregator() as SvgDispatcher).callBack == uuid }
+    }
+
     fun findMenuBars(): LogEntry? {
         return log.firstOrNull() {
             it.obj is Menubars
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/DiagramDialog.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/DiagramDialog.kt
index 4ca34fb..359280b 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/DiagramDialog.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/DiagramDialog.kt
@@ -18,6 +18,7 @@
  */
 package org.apache.isis.client.kroviz.ui
 
+import org.apache.isis.client.kroviz.core.event.EventStore
 import org.apache.isis.client.kroviz.to.ValueType
 import org.apache.isis.client.kroviz.ui.kv.FormPanelFactory
 import org.apache.isis.client.kroviz.ui.kv.RoDialog
@@ -25,8 +26,8 @@ import org.apache.isis.client.kroviz.ui.kv.UiManager
 import org.apache.isis.client.kroviz.utils.*
 
 class DiagramDialog(
-    var label: String,
-    private var pumlCode: String
+        var label: String,
+        private var pumlCode: String
 ) : Command() {
 
     private var callBack: Any = UUID()
@@ -35,8 +36,6 @@ class DiagramDialog(
 
     fun open() {
         dialog.open()
-        console.log("[DiagramDialog.open]")
-        console.log(pumlCode)
         UmlUtils.generateJsonDiagram(pumlCode, callBack)
     }
 
@@ -45,40 +44,47 @@ class DiagramDialog(
         formItems.add(fi)
 
         dialog = RoDialog(
-            widthPerc = 80,
-            caption = "Diagram",
-            items = formItems,
-            command = this,
-            defaultAction = "Pin"
+                widthPerc = 80,
+                caption = "Diagram",
+                items = formItems,
+                command = this,
+                defaultAction = "Pin"
         )
     }
 
     override fun execute() {
-        val newFormItems = mutableListOf<FormItem>()
-        val newCallBack = UUID()
-        val newFi = FormItem("svg", ValueType.SVG_INLINE, callBack = newCallBack)
-        newFormItems.add(newFi)
-        val panel = FormPanelFactory(newFormItems)
-        UiManager.add("Diagram", panel)
-        // Timing critical: Panel has to be added first, then extract from old location.
-        val uuid = callBack as UUID
-        val oldElement = DomUtil.getById(uuid.value)!!
-        val oldStr = oldElement.innerHTML
-        val newImage = ScalableVectorGraphic(oldStr)
+        val newImage = getDiagram()
+        val newCallBack = buildNewPanel()
         DomUtil.replaceWith(newCallBack, newImage)
     }
 
+    private fun getDiagram(): ScalableVectorGraphic {
+        val logEntry = EventStore.findBy(callBack as UUID)
+        val svgStr = logEntry.getResponse()
+        console.log("[DiagramDialog.execute]")
+        console.log(svgStr)
+        return ScalableVectorGraphic(svgStr)
+    }
+
+    private fun buildNewPanel() : UUID {
+        val newUuid = UUID()
+        val formItems = mutableListOf<FormItem>()
+        val newFi = FormItem("svg", ValueType.SVG_INLINE, callBack = newUuid)
+        formItems.add(newFi)
+        val panel = FormPanelFactory(formItems)
+        console.log(panel)
+        UiManager.add("Diagram", panel)
+        return newUuid
+    }
+
     @Deprecated("use leaflet/svg")
     fun scale(direction: Direction) {
-        val uuid = callBack as UUID
-        val oldElement = DomUtil.getById(uuid.value)!!
-        val oldStr = oldElement.innerHTML
-        val newImage = ScalableVectorGraphic(oldStr)
+        val svg = getDiagram()
         when (direction) {
-            Direction.UP -> newImage.scaleUp()
-            Direction.DOWN -> newImage.scaleDown()
+            Direction.UP -> svg.scaleUp()
+            Direction.DOWN -> svg.scaleDown()
         }
-        DomUtil.replaceWith(uuid, newImage)
+        DomUtil.replaceWith(callBack as UUID, svg)
     }
 
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/EventLogDetail.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/EventLogDetail.kt
index 533442c..97aee27 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/EventLogDetail.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/EventLogDetail.kt
@@ -35,7 +35,7 @@ class EventLogDetail(val logEntry: LogEntry) : Command() {
         var responseStr = logEntry.response
         if (logEntry.subType == Constants.subTypeJson) {
             responseStr = Utils.format(responseStr)
-        }   else {
+        } else {
             responseStr = XmlHelper.formatXml(responseStr)
         }
         formItems.add(FormItem("Response", ValueType.TEXT_AREA, responseStr, 10))
@@ -56,11 +56,16 @@ class EventLogDetail(val logEntry: LogEntry) : Command() {
 
 
     override fun execute() {
-        if (logEntry.subType != Constants.subTypeXml) {
-            val responseStr = logEntry.response
-            val pumlCode = PumlBuilder().asJsonDiagram(responseStr)
-            DiagramDialog("Json Diagram", pumlCode).open()
+        val str = logEntry.response
+        val json = when {
+            str.startsWith("<") -> {
+                XmlHelper.xml2json(str)
+            }
+            str.startsWith("{") -> str
+            else -> "{}"
         }
+        val pumlCode = PumlBuilder().asJsonDiagram(json)
+        DiagramDialog("Response Diagram", pumlCode).open()
     }
 
     fun executeConsole() {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/FormPanelFactory.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/FormPanelFactory.kt
index fac5df6..d3adff9 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/FormPanelFactory.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/FormPanelFactory.kt
@@ -36,7 +36,6 @@ import io.kvision.form.time.dateTime
 import io.kvision.html.Div
 import io.kvision.html.Iframe
 import io.kvision.html.Image
-import io.kvision.html.image
 import io.kvision.panel.VPanel
 import io.kvision.panel.vPanel
 import io.kvision.utils.auto
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/ScalableVectorGraphic.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/ScalableVectorGraphic.kt
index 811ecf7..9fd4931 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/ScalableVectorGraphic.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/ScalableVectorGraphic.kt
@@ -20,14 +20,19 @@ package org.apache.isis.client.kroviz.utils
 
 import org.apache.isis.client.kroviz.ui.kv.Constants
 import org.w3c.dom.Document
+import org.w3c.dom.Image
 import org.w3c.dom.parsing.DOMParser
 import org.w3c.dom.svg.SVGSVGElement
+import org.w3c.dom.url.URL
+import org.w3c.files.Blob
+import org.w3c.files.BlobPropertyBag
 
 enum class Direction(val id: String) {
     UP("UP"),
     DOWN("DOWN")
 }
 
+// see: https://vecta.io/blog/best-way-to-embed-svg
 class ScalableVectorGraphic(val data: String) {
 
     var document: Document = DOMParser().parseFromString(data, Constants.svgMimeType)
@@ -85,4 +90,14 @@ class ScalableVectorGraphic(val data: String) {
 
     class ViewBox(val x: Int, val y: Int, var width: Int, var height: Int)
 
+    fun asImage(): Image {
+        val byteArray = data.encodeToByteArray().asDynamic()
+        val options = BlobPropertyBag("image/svg+xml;charset=utf-8")
+        val svgBlob = Blob(byteArray, options)
+        val objectURL = URL.createObjectURL(svgBlob)
+        val image = Image()
+        image.src = objectURL
+        return image
+    }
+
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/XmlHelper.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/XmlHelper.kt
index 0dd8fe8..122a35d 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/XmlHelper.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/XmlHelper.kt
@@ -69,7 +69,16 @@ object XmlHelper {
             formatted += padding + node + "\r\n"
             pad += indent
         }
-        return formatted.substring(1, formatted.length - 3);
+        return formatted.substring(0, formatted.length - 2);
+    }
+
+    fun xml2json(xml: String): String {
+        console.log("[XmlHelper.xml2json]")
+        val json = XmlToJson.parseString(xml)
+        console.log(json)
+        val jsonStr = JSON.stringify(json)
+        console.log(jsonStr)
+        return jsonStr
     }
 
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/SvgDispatcher.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/XmlToJson.kt
similarity index 56%
copy from incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/SvgDispatcher.kt
copy to incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/XmlToJson.kt
index 380952e..fe2e926 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/SvgDispatcher.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/XmlToJson.kt
@@ -16,23 +16,12 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.client.kroviz.core.aggregator
+package org.apache.isis.client.kroviz.utils
 
-import org.apache.isis.client.kroviz.core.event.LogEntry
-import org.apache.isis.client.kroviz.ui.kv.MapPanel
-import org.apache.isis.client.kroviz.utils.DomUtil
-import org.apache.isis.client.kroviz.utils.UUID
-
-class SvgDispatcher(private val callBack: Any) : BaseAggregator() {
-
-    override fun update(logEntry: LogEntry, subType: String) {
-        val response = logEntry.response
-        when (callBack) {
-            is UUID -> DomUtil.appendTo(callBack, response)
-            is MapPanel -> callBack.renderSvg(response)
-            else -> {
-            }
-        }
-    }
+import org.w3c.dom.Document
 
+@JsModule("xmltojson")
+@JsNonModule
+external object XmlToJson {
+    fun parseString(xml: String): String
 }
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/TestRequest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/TestRequest.kt
index 5bdf293..513671c 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/TestRequest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/TestRequest.kt
@@ -2,7 +2,6 @@ package org.apache.isis.client.kroviz.snapshots
 
 import kotlinx.browser.window
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.asDeferred
 import kotlinx.coroutines.await
 import org.apache.isis.client.kroviz.IntegrationTest
 import org.apache.isis.client.kroviz.to.Link
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/SvgDispatcher.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/util/XmlHelperTest.kt
similarity index 57%
copy from incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/SvgDispatcher.kt
copy to incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/util/XmlHelperTest.kt
index 380952e..9d3c6a7 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/SvgDispatcher.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/util/XmlHelperTest.kt
@@ -16,23 +16,25 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.client.kroviz.core.aggregator
+package org.apache.isis.client.kroviz.util
 
-import org.apache.isis.client.kroviz.core.event.LogEntry
-import org.apache.isis.client.kroviz.ui.kv.MapPanel
-import org.apache.isis.client.kroviz.utils.DomUtil
-import org.apache.isis.client.kroviz.utils.UUID
+import org.apache.isis.client.kroviz.snapshots.demo2_0_0.TAB_LAYOUT_XML
+import org.apache.isis.client.kroviz.utils.XmlHelper
+import kotlin.test.Test
+import kotlin.test.assertEquals
 
-class SvgDispatcher(private val callBack: Any) : BaseAggregator() {
+class XmlHelperTest {
 
-    override fun update(logEntry: LogEntry, subType: String) {
-        val response = logEntry.response
-        when (callBack) {
-            is UUID -> DomUtil.appendTo(callBack, response)
-            is MapPanel -> callBack.renderSvg(response)
-            else -> {
-            }
-        }
+    @Test
+    fun testXml2Json() {
+        //given
+        val xmlStr = TAB_LAYOUT_XML.str
+        //when
+        val jsonStr = XmlHelper.xml2json(xmlStr)
+        // then
+        assertEquals("{", jsonStr.first())
+        assertEquals("}", jsonStr.last())
     }
 
+
 }