This is an automated email from the ASF dual-hosted git repository. joergrade pushed a commit to branch CAUSEWAY-3264 in repository https://gitbox.apache.org/repos/asf/causeway.git
commit b2f92ac1eff8419b87545c5d74c8859ee1d7397b Author: Jörg Rade <[email protected]> AuthorDate: Mon Apr 24 16:45:06 2023 +0200 CAUSEWAY-3264 vega 1/n, asciidoctor --- examples/demo/.run/DemoAppWicketJdo.run.xml | 2 - examples/demo/wicket/jpa/pom.xml | 16 ++ .../webapp/wicket/jpa/DemoAppWicketJpa.java | 4 + incubator/clients/kroviz/build.gradle.kts | 7 +- incubator/clients/kroviz/gradle.properties | 2 +- .../apache/causeway/client/kroviz/to/TypeMapper.kt | 5 +- .../client/kroviz/ui/builder/FieldSetBuilder.kt | 4 +- .../client/kroviz/ui/core/FormPanelFactory.kt | 19 +- .../causeway/client/kroviz/ui/core/RoMenuBar.kt | 10 +- .../causeway/client/kroviz/ui/dialog/VegaSample.kt | 233 +++++++++++++++++++++ .../utils/js/{ShowDown.kt => AsciiDoctor.kt} | 12 +- .../kroviz/utils/js/{ShowDown.kt => Vega.kt} | 18 +- .../causeway/client/kroviz/snapshots/sample.json | 150 ++----------- 13 files changed, 312 insertions(+), 170 deletions(-) diff --git a/examples/demo/.run/DemoAppWicketJdo.run.xml b/examples/demo/.run/DemoAppWicketJdo.run.xml index 512a010222..631b102e2a 100644 --- a/examples/demo/.run/DemoAppWicketJdo.run.xml +++ b/examples/demo/.run/DemoAppWicketJdo.run.xml @@ -1,7 +1,5 @@ <component name="ProjectRunConfigurationManager"> <configuration default="false" name="DemoAppWicketJdo" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot"> - <option name="ACTIVE_PROFILES" /> - <module name="demo-wicket-jdo" /> <option name="SPRING_BOOT_MAIN_CLASS" value="demoapp.webapp.wicket.jdo.DemoAppWicketJdo" /> <method v="2"> <option name="Make" enabled="true" /> diff --git a/examples/demo/wicket/jpa/pom.xml b/examples/demo/wicket/jpa/pom.xml index 7e38ccefc3..f1d2a3e3e5 100644 --- a/examples/demo/wicket/jpa/pom.xml +++ b/examples/demo/wicket/jpa/pom.xml @@ -49,6 +49,22 @@ <groupId>org.apache.causeway.persistence</groupId> <artifactId>causeway-persistence-jpa-eclipselink</artifactId> </dependency> + <dependency> + <groupId>org.apache.causeway.security</groupId> + <artifactId>causeway-security-bypass</artifactId> + </dependency> + <dependency> + <groupId>org.apache.causeway.viewer</groupId> + <artifactId>causeway-viewer-wicket-applib</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-autoconfigure</artifactId> + </dependency> </dependencies> diff --git a/examples/demo/wicket/jpa/src/main/java/demoapp/webapp/wicket/jpa/DemoAppWicketJpa.java b/examples/demo/wicket/jpa/src/main/java/demoapp/webapp/wicket/jpa/DemoAppWicketJpa.java index f6e5f89113..781ed767b8 100644 --- a/examples/demo/wicket/jpa/src/main/java/demoapp/webapp/wicket/jpa/DemoAppWicketJpa.java +++ b/examples/demo/wicket/jpa/src/main/java/demoapp/webapp/wicket/jpa/DemoAppWicketJpa.java @@ -18,6 +18,7 @@ */ package demoapp.webapp.wicket.jpa; +import org.apache.causeway.security.bypass.CausewayModuleSecurityBypass; import org.apache.causeway.viewer.wicket.applib.CausewayModuleViewerWicketApplibMixins; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -70,6 +71,9 @@ import demoapp.webapp.wicket.common.ui.DemoAppWicketCommon; // Custom Demo UI (Wicket Viewer) DemoAppWicketCommon.class, + // bypassing sycurity for kroviz development + CausewayModuleSecurityBypass.class, + // Persistence/Converters (JPA) CausewayModuleValAsciidocPersistenceJpa.class, CausewayModuleValMarkdownPersistenceJpa.class, diff --git a/incubator/clients/kroviz/build.gradle.kts b/incubator/clients/kroviz/build.gradle.kts index f5fdc8887c..74e83adc47 100644 --- a/incubator/clients/kroviz/build.gradle.kts +++ b/incubator/clients/kroviz/build.gradle.kts @@ -107,10 +107,11 @@ kotlin { implementation(npm("xml-beautify", "1.1.2", false)) implementation(npm("xterm", "4.15.0", false)) implementation(npm("pdfjs", "2.4.7", false)) - implementation(npm("vega", "5.22.1", false)) -// implementation(npm("vega-lite", "5.6.0", true)) + implementation(npm("vega", "5.24.0")) +// implementation(npm("vega-lite", "5.6.0", false)) +// implementation(npm("vega-embed", "6.21.3", false)) implementation(npm("element-resize-event", "3.0.6", false)) - implementation(npm("showdown", "2.1.0", false)) + implementation(npm("asciidoctor", "2.2.6", false)) } sourceSets["test"].dependencies { implementation(kotlin("test-js")) diff --git a/incubator/clients/kroviz/gradle.properties b/incubator/clients/kroviz/gradle.properties index 90baeeb9e3..59db1900d5 100644 --- a/incubator/clients/kroviz/gradle.properties +++ b/incubator/clients/kroviz/gradle.properties @@ -18,7 +18,7 @@ # javaVersion=1.8 #Plugins -systemProp.kotlinVersion=1.7.0 +systemProp.kotlinVersion=1.8.0 serializationVersion=1.3.3 #Dependencies systemProp.kvisionVersion=5.15.3 diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/to/TypeMapper.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/to/TypeMapper.kt index 21f93b7633..29523671ac 100644 --- a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/to/TypeMapper.kt +++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/to/TypeMapper.kt @@ -37,7 +37,7 @@ enum class ValueType(val type: String) { SHELL("Shell"), SVG_MAPPED("Map"), SVG_INLINE("Inline"), - VEGA("Vega"), + CANVAS("Canvas"), } class TypeMapper { @@ -68,6 +68,7 @@ class TypeMapper { XmlHelper.isXml(contentStr) -> ValueType.HTML.type contentStr.startsWith(":Notice:") -> ValueType.HTML.type contentStr.startsWith("link:") -> ValueType.HTML.type + contentStr.contains("vega.github.io/schema") -> ValueType.CANVAS.type else -> ValueType.TEXT.type } } @@ -89,7 +90,7 @@ class TypeMapper { ValueType.SLIDER.type -> return ValueType.SLIDER ValueType.SVG_MAPPED.type -> return ValueType.SVG_MAPPED ValueType.SVG_INLINE.type -> return ValueType.SVG_INLINE - ValueType.VEGA.type -> return ValueType.VEGA + ValueType.CANVAS.type -> return ValueType.CANVAS else -> { return ValueType.TEXT } diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/builder/FieldSetBuilder.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/builder/FieldSetBuilder.kt index d1d5f34ecc..46fb3292f6 100644 --- a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/builder/FieldSetBuilder.kt +++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/builder/FieldSetBuilder.kt @@ -25,7 +25,7 @@ import org.apache.causeway.client.kroviz.to.ValueType import org.apache.causeway.client.kroviz.to.bs.FieldSetBs import org.apache.causeway.client.kroviz.ui.core.FormItem import org.apache.causeway.client.kroviz.ui.core.FormPanelFactory -import org.apache.causeway.client.kroviz.utils.js.ShowDown +import org.apache.causeway.client.kroviz.utils.js.AsciiDoctor class FieldSetBuilder { @@ -47,7 +47,7 @@ class FieldSetBuilder { label = p.named if (memberType == ValueType.HTML && content is String) { when { - content.startsWith(":Notice:") -> content = ShowDown.convertMarkDown2Html(content) + content.startsWith(":Notice:") -> content = AsciiDoctor.convert(content) content.startsWith("link:") -> content = content.replace("link:", "") else -> {} } diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/core/FormPanelFactory.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/core/FormPanelFactory.kt index d5ab217f30..8ac0c2ba6e 100644 --- a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/core/FormPanelFactory.kt +++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/core/FormPanelFactory.kt @@ -32,10 +32,7 @@ import io.kvision.form.text.Text import io.kvision.form.text.TextArea import io.kvision.form.time.DateTime import io.kvision.form.time.dateTime -import io.kvision.html.Button -import io.kvision.html.Div -import io.kvision.html.Iframe -import io.kvision.html.Image +import io.kvision.html.* import io.kvision.panel.VPanel import io.kvision.panel.vPanel import io.kvision.utils.auto @@ -74,8 +71,8 @@ class FormPanelFactory(items: List<FormItem>) : VPanel() { ValueType.SVG_INLINE -> add(createInline(fi)) ValueType.SVG_MAPPED -> add(createSvgMap(fi)) ValueType.BUTTON -> add(createButton(fi)) - ValueType.VEGA -> { - TODO("implement VEGA") + ValueType.CANVAS -> add(createCanvas(fi)) + else -> { } } } @@ -245,6 +242,16 @@ class FormPanelFactory(items: List<FormItem>) : VPanel() { return item } + private fun createCanvas(fi: FormItem): VPanel { + val item = VPanel { + val vega = fi.content as String + val canvas = Canvas() + + add(canvas) + } + return item + } + companion object { private const val FORM_PANEL = "form-panel" } diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/core/RoMenuBar.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/core/RoMenuBar.kt index 569d385c6c..3d66beb18a 100644 --- a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/core/RoMenuBar.kt +++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/core/RoMenuBar.kt @@ -35,10 +35,7 @@ import org.apache.causeway.client.kroviz.core.Session import org.apache.causeway.client.kroviz.core.aggregator.ActionDispatcher import org.apache.causeway.client.kroviz.core.event.ResourceProxy import org.apache.causeway.client.kroviz.to.mb.Menubars -import org.apache.causeway.client.kroviz.ui.dialog.About -import org.apache.causeway.client.kroviz.ui.dialog.EventDialog -import org.apache.causeway.client.kroviz.ui.dialog.LoginPrompt -import org.apache.causeway.client.kroviz.ui.dialog.SvgInline +import org.apache.causeway.client.kroviz.ui.dialog.* import org.apache.causeway.client.kroviz.ui.menu.DropDownMenuBuilder import org.apache.causeway.client.kroviz.ui.panel.GeoMap import org.apache.causeway.client.kroviz.ui.panel.ImageSample @@ -204,6 +201,11 @@ class RoMenuBar : SimplePanel() { buildMenuEntry(imageTitle, "Image", { ViewManager.add(imageTitle, ImageSample) }) ) + val vegaTitle = "Vega Sample" + subMenu.add( + buildMenuEntry(vegaTitle, "Image", { VegaSample().open() }) + ) + mainMenu.add(subMenu) return mainMenu diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/dialog/VegaSample.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/dialog/VegaSample.kt new file mode 100644 index 0000000000..01475f5656 --- /dev/null +++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/ui/dialog/VegaSample.kt @@ -0,0 +1,233 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.causeway.client.kroviz.ui.dialog + +import io.kvision.utils.obj +import org.apache.causeway.client.kroviz.core.event.ReplayController +import org.apache.causeway.client.kroviz.to.ValueType +import org.apache.causeway.client.kroviz.ui.core.FormItem +import org.apache.causeway.client.kroviz.ui.core.RoDialog +import org.apache.causeway.client.kroviz.ui.core.ViewManager + +class VegaSample(val nextController: Controller? = null) : Controller() { + + //Default values + val spec = obj { + this["\$schema"] = "https://vega.github.io/schema/vega/v5.json" + this.description = "A basic bar chart example, with value labels shown upon mouse hover." + this.width = 400 + this.height = 200 + this.padding = 5 + this.data = arrayOf( + obj { + this.name = "table" + this.values = arrayOf( + obj { + this.category = "A" + this.amount = 28 + }, + obj { + this.category = "B" + this.amount = 55 + }, + obj { + this.category = "C" + this.amount = 43 + }, + obj { + this.category = "D" + this.amount = 91 + }, + obj { + this.category = "E" + this.amount = 81 + }, + obj { + this.category = "F" + this.amount = 53 + }, + obj { + this.category = "G" + this.amount = 19 + }, + obj { + this.category = "H" + this.amount = 87 + } + ) + } + ) + this.signals = arrayOf( + obj { + this.name = "tooltip" + this.value = obj { + } + this.on = arrayOf( + obj { + this.events = "rect:mouseover" + this.update = "datum" + }, + obj { + this.events = "rect:mouseout" + this.update = "{}" + } + ) + } + ) + this.scales = arrayOf( + obj { + this.name = "xscale" + this.type = "band" + this.domain = obj { + this.data = "table" + this.field = "category" + } + this.range = "width" + this.padding = 0.05 + this.round = true + }, + obj { + this.name = "yscale" + this.domain = obj { + this.data = "table" + this.field = "amount" + } + this.nice = true + this.range = "height" + } + ) + this.axes = arrayOf( + obj { + this.orient = "bottom" + this.scale = "xscale" + }, + obj { + this.orient = "left" + this.scale = "yscale" + } + ) + this.marks = arrayOf( + obj { + this.type = "rect" + this.from = obj { + this.data = "table" + } + this.encode = obj { + this.enter = obj { + this.x = obj { + this.scale = "xscale" + this.field = "category" + } + this.width = obj { + this.scale = "xscale" + this.band = 1 + } + this.y = obj { + this.scale = "yscale" + this.field = "amount" + } + this.y2 = obj { + this.scale = "yscale" + this.value = 0 + } + } + this.update = obj { + this.fill = obj { + this.value = "steelblue" + } + } + this.hover = obj { + this.fill = obj { + this.value = "red" + } + } + } + }, + obj { + this.type = "text" + this.encode = obj { + this.enter = obj { + this.align = obj { + this.value = "center" + } + this.baseline = obj { + this.value = "bottom" + } + this.fill = obj { + this.value = "#333" + } + } + this.update = obj { + this.x = obj { + this.scale = "xscale" + this.signal = "tooltip.category" + this.band = 0.5 + } + this.y = obj { + this.scale = "yscale" + this.signal = "tooltip.amount" + this.offset = -2 + } + this.text = obj { + this.signal = "tooltip.amount" + } + this.fillOpacity = arrayOf( + obj { + this.test = "datum === tooltip" + this.value = 0 + }, + obj { + this.value = 1 + } + ) + } + } + } + ) + } + + + fun embed(spec: String): dynamic { + return js( + code = """ + var embed = require('vega'); + var result = embed('#vis', spec); + console.log(result.view); + return result; + """ + ) + } + + override fun open() { + val formItems = mutableListOf<FormItem>() + formItems.add(FormItem("Diagram", ValueType.CANVAS, embed(spec))) + dialog = RoDialog(caption = "Vega Sample", items = formItems, controller = this, heightPerc = 27) + val at = ViewManager.position!! + dialog.open(at) + } + + override fun execute(action: String?) { + if (nextController is ReplayController) { + nextController.open() + } else { + ViewManager.closeDialog(dialog) + } + } + +} diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/utils/js/ShowDown.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/utils/js/AsciiDoctor.kt similarity index 76% copy from incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/utils/js/ShowDown.kt copy to incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/utils/js/AsciiDoctor.kt index aa5264c668..ea7accd87c 100644 --- a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/utils/js/ShowDown.kt +++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/utils/js/AsciiDoctor.kt @@ -18,14 +18,12 @@ */ package org.apache.causeway.client.kroviz.utils.js -object ShowDown { - fun convertMarkDown2Html(text: String): dynamic { - //TODO content.replace(":Notice:", "") +object AsciiDoctor { + fun convert(content: String): dynamic { return js( - """ - var showdown = require('showdown'), - converter = new showdown.Converter(), - html = converter.makeHtml(text); + code = """ + var asciidoctor = require('asciidoctor')(); + var html = asciidoctor.convert(content); return html; """ ) diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/utils/js/ShowDown.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/utils/js/Vega.kt similarity index 70% rename from incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/utils/js/ShowDown.kt rename to incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/utils/js/Vega.kt index aa5264c668..0e899436b2 100644 --- a/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/utils/js/ShowDown.kt +++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/causeway/client/kroviz/utils/js/Vega.kt @@ -18,16 +18,12 @@ */ package org.apache.causeway.client.kroviz.utils.js -object ShowDown { - fun convertMarkDown2Html(text: String): dynamic { - //TODO content.replace(":Notice:", "") - return js( - """ - var showdown = require('showdown'), - converter = new showdown.Converter(), - html = converter.makeHtml(text); - return html; - """ - ) +@JsModule("vega") +@JsNonModule +external object Vega { + fun parse(spec: dynamic): dynamic + class View(spec: dynamic, options: dynamic) { + fun runAsync() } + } diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/causeway/client/kroviz/snapshots/sample.json b/incubator/clients/kroviz/src/test/kotlin/org/apache/causeway/client/kroviz/snapshots/sample.json index 35e3e62ed9..6a1f2175b7 100644 --- a/incubator/clients/kroviz/src/test/kotlin/org/apache/causeway/client/kroviz/snapshots/sample.json +++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/causeway/client/kroviz/snapshots/sample.json @@ -1,135 +1,21 @@ { - "links": [ - { - "rel": "self", - "href": "http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=", - "method": "GET", - "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object\"", - "title": "String data type" - }, - { - "rel": "describedby", - "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStrings", - "method": "GET", - "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/domain-type\"" - }, - { - "rel": "urn:org.apache.causeway.restfulobjects:rels/object-layout", - "href": "http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/object-layout", - "method": "GET", - "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-layout-bs3\"" - }, - { - "rel": "urn:org.apache.causeway.restfulobjects:rels/object-icon", - "href": "http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/object-icon", - "method": "GET", - "type": "image/*" - }, - { - "rel": "urn:org.restfulobjects:rels/update", - "href": "http://localhost:8080/restful/objects/demo.JavaLangStrings:PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=", - "method": "PUT", - "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object\"", - "arguments": {} - } - ], - "extensions": { - "oid": "demo.JavaLangStrings:PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=", - "isService": false, - "isPersistent": true + "$schema": "https://vega.github.io/schema/vega-lite/v5.json", + "data": { + "values": [ + {"a": "C", "b": 2}, + {"a": "C", "b": 7}, + {"a": "C", "b": 4}, + {"a": "D", "b": 1}, + {"a": "D", "b": 2}, + {"a": "D", "b": 6}, + {"a": "E", "b": 8}, + {"a": "E", "b": 4}, + {"a": "E", "b": 7} + ] }, - "title": "String data type", - "domainType": "demo.JavaLangStrings", - "instanceId": "PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=", - "members": { - "description": { - "id": "description", - "memberType": "property", - "links": [ - { - "rel": "urn:org.restfulobjects:rels/details;property=\"description\"", - "href": "http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/properties/description", - "method": "GET", - "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-property\"" - } - ], - "value": "<div class=\"paragraph\">\n<p>The framework has built-in support for the <code>String</code> data type.</p>\n</div>\n<div class=\"paragraph\">\n<p>From here you can:</p>\n</div>\n<div class=\"ulist\">\n<ul>\n<li>\n<p>navigate to an entity that uses the <code>String</code> datatype</p>\n</li>\n<li>\n<p>open a view model that uses the <code>String</code> datatype</p>\n</li>\n</ul>\n</div>\n<div class=\"paragraph\">\n<p>Some properties on these domain objects are mandatory, [...] - "format": "string", - "extensions": { - "x-causeway-format": "string" - }, - "disabledReason": "Contributed property" - }, - "logicalTypeName": { - "id": "logicalTypeName", - "memberType": "property", - "links": [ - { - "rel": "urn:org.restfulobjects:rels/details;property=\"logicalTypeName\"", - "href": "http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/properties/logicalTypeName", - "method": "GET", - "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-property\"" - } - ], - "value": "demo.JavaLangStrings", - "extensions": { - "x-causeway-format": "string" - }, - "disabledReason": "Contributed property" - }, - "sources": { - "id": "sources", - "memberType": "property", - "links": [ - { - "rel": "urn:org.restfulobjects:rels/details;property=\"sources\"", - "href": "http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/properties/sources", - "method": "GET", - "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-property\"" - } - ], - "value": "<div class=\"paragraph\">\n<p><a href=\"https://github.com/apache/causeway/tree/master/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/strings\">Sources</a> for this demo</p>\n</div>", - "format": "string", - "extensions": { - "x-causeway-format": "string" - }, - "disabledReason": "Contributed property" - }, - "entities": { - "id": "entities", - "memberType": "collection", - "links": [ - { - "rel": "urn:org.restfulobjects:rels/details;collection=\"entities\"", - "href": "http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/collections/entities", - "method": "GET", - "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-collection\"" - } - ] - }, - "openViewModel": { - "id": "openViewModel", - "memberType": "action", - "links": [ - { - "rel": "urn:org.restfulobjects:rels/details;action=\"openViewModel\"", - "href": "http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/openViewModel", - "method": "GET", - "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-action\"" - } - ] - }, - "clearHints": { - "id": "clearHints", - "memberType": "action", - "links": [ - { - "rel": "urn:org.restfulobjects:rels/details;action=\"clearHints\"", - "href": "http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/actions/clearHints", - "method": "GET", - "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-action\"" - } - ] - } + "mark": "point", + "encoding": { + "x": {"field": "a", "type": "nominal"}, + "y": {"field": "b", "type": "quantitative"} } -} +} \ No newline at end of file
