You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by ah...@apache.org on 2026/05/14 05:55:11 UTC

(causeway) branch 3999-dropdown.val.sem created (now 0b72f4adde0)

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

andi-huber pushed a change to branch 3999-dropdown.val.sem
in repository https://gitbox.apache.org/repos/asf/causeway.git


      at 0b72f4adde0 CAUSEWAY-3999: refactor ObjectDisplayDto to allow render arbitrary HTML

This branch includes the following new commits:

     new 0b72f4adde0 CAUSEWAY-3999: refactor ObjectDisplayDto to allow render arbitrary HTML

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(causeway) 01/01: CAUSEWAY-3999: refactor ObjectDisplayDto to allow render arbitrary HTML

Posted by ah...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

andi-huber pushed a commit to branch 3999-dropdown.val.sem
in repository https://gitbox.apache.org/repos/asf/causeway.git

commit 0b72f4adde093b15c9e8d7d60c9d33dcb298d955
Author: andi-huber <ah...@apache.org>
AuthorDate: Thu May 14 07:55:02 2026 +0200

    CAUSEWAY-3999: refactor ObjectDisplayDto to allow render arbitrary HTML
    
    as provided server-side
---
 .../objectmanager/memento/ObjectDisplayDto.java     | 11 ++++++-----
 .../objectmanager/memento/ObjectMemento.java        | 21 +++++++++++----------
 .../objectmanager/memento/ObjectMementoEmpty.java   | 15 ++++++++++++---
 .../memento/ObjectMementoSingular.java              |  6 ++----
 .../ui/components/widgets/select2/Select2.java      |  6 ++----
 5 files changed, 33 insertions(+), 26 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectDisplayDto.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectDisplayDto.java
index 569fd231eef..9e3dab78182 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectDisplayDto.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectDisplayDto.java
@@ -19,30 +19,31 @@
 package org.apache.causeway.core.metamodel.objectmanager.memento;
 
 import java.io.Serializable;
-import org.jspecify.annotations.Nullable;
 
 import org.apache.causeway.commons.internal.base._Strings;
 import org.apache.causeway.commons.io.JsonUtils;
 
 /**
  * Provides a summary of the domain object for rendering,
- * having (translated) title and icon.
+ * having (translated) pre-rendered HTML (typically icon and title).
  *
  * @implSpec works hand in hand with select2 (third-party) java-script
  *  and org.apache.causeway.viewer.wicket.ui.components.widgets.select2.Select2 template configuration.
+ *
+ * @apiNote SECURITY ADVICE: when using this DTO make sure its content is populated from a trusted source
  */
 public record ObjectDisplayDto(
     Class<?> correspondingClass,
     String bookmark,
     String title,
-    @Nullable String iconHtml) implements Serializable {
+    String html) implements Serializable {
 
-    public static ObjectDisplayDto fromJson(String json) {
+    public static ObjectDisplayDto fromJson(final String json) {
         return JsonUtils.tryRead(ObjectDisplayDto.class, json)
             .valueAsNonNullElseFail();
     }
 
-    public static ObjectDisplayDto fromJsonBase64(String base64EncodedJson) {
+    public static ObjectDisplayDto fromJsonBase64(final String base64EncodedJson) {
         return fromJson(_Strings.base64UrlDecode(base64EncodedJson));
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMemento.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMemento.java
index 282a099294b..121c2586a30 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMemento.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMemento.java
@@ -31,8 +31,6 @@
 import org.apache.causeway.applib.id.LogicalType;
 import org.apache.causeway.applib.services.bookmark.Bookmark;
 import org.apache.causeway.applib.services.i18n.TranslationContext;
-import org.apache.causeway.applib.services.render.PlaceholderRenderService;
-import org.apache.causeway.applib.services.render.PlaceholderRenderService.PlaceholderLiteral;
 import org.apache.causeway.commons.internal.assertions._Assert;
 import org.apache.causeway.commons.internal.collections._Lists;
 import org.apache.causeway.commons.internal.exceptions._Exceptions;
@@ -53,7 +51,7 @@ public sealed interface ObjectMemento
     Bookmark bookmark();
 
     /**
-     * The object's title for rendering (before translation).
+     * The object's title for rendering.
      * Corresponds to {@link ManagedObject#getTitle()}.
      *
      * <p>Directly support choice rendering, without the need to (re-)fetch entire object graphs.
@@ -64,9 +62,7 @@ public sealed interface ObjectMemento
     // -- FACTORIES
 
     static ObjectMemento empty(final LogicalType logicalType) {
-        return new ObjectMementoEmpty(
-            logicalType,
-            PlaceholderRenderService.fallback().asText(PlaceholderLiteral.NULL_REPRESENTATION));
+        return new ObjectMementoEmpty(logicalType);
     }
 
     static Optional<ObjectMemento> singular(
@@ -86,11 +82,16 @@ static Optional<ObjectMemento> singular(
                         + "nor has 'encodable' semantics, nor is (Serializable || Externalizable)"
                         .formatted(spec));
 
+        var title = adapter.getTranslationService().translate(TranslationContext.empty(), MmTitleUtils.titleOf(adapter));
+        var prerenderedHtml = "<span>%s %s</span>".formatted(
+                adapter.getObjectRenderService().iconToHtml(adapter.getIcon(IconSize.SMALL), IconSize.SMALL),
+                title);
+
         return Optional.ofNullable(new ObjectMementoSingular(
                 adapter.logicalType(),
                 MmHintUtils.bookmarkElseFail(adapter),
-                adapter.getTranslationService().translate(TranslationContext.empty(), MmTitleUtils.titleOf(adapter)),
-                adapter.getObjectRenderService().iconToHtml(adapter.getIcon(IconSize.SMALL), IconSize.SMALL)));
+                title,
+                prerenderedHtml));
     }
     /**
      * returns null for null
@@ -125,8 +126,8 @@ static ObjectMemento fromDto(final ObjectDisplayDto dto) {
         var bookmark = Bookmark.parse(dto.bookmark()).orElseThrow();
         var logicalType = new LogicalType(bookmark.logicalTypeName(), dto.correspondingClass());
         return bookmark.isEmpty()
-            ? new ObjectMementoEmpty(logicalType, dto.title())
-            : new ObjectMementoSingular(logicalType, bookmark, dto.title(), dto.iconHtml());
+            ? new ObjectMementoEmpty(logicalType)
+            : new ObjectMementoSingular(logicalType, bookmark, dto.title(), dto.html());
     }
 
     static String enstringToBase64(final ObjectMemento memento) {
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoEmpty.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoEmpty.java
index 967f346b545..c398e4cad1b 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoEmpty.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoEmpty.java
@@ -20,10 +20,11 @@
 
 import org.apache.causeway.applib.id.LogicalType;
 import org.apache.causeway.applib.services.bookmark.Bookmark;
+import org.apache.causeway.applib.services.render.PlaceholderRenderService;
+import org.apache.causeway.applib.services.render.PlaceholderRenderService.PlaceholderLiteral;
 
 record ObjectMementoEmpty(
-        LogicalType logicalType,
-        String title)
+        LogicalType logicalType)
 implements ObjectMemento {
 
     @Override
@@ -32,7 +33,15 @@ public Bookmark bookmark() {
     }
 
     public ObjectDisplayDto toDto() {
-        return new ObjectDisplayDto(logicalType.correspondingClass(), bookmark().stringify(), title, null);
+        return new ObjectDisplayDto(logicalType.correspondingClass(), bookmark().stringify(), title(), html());
     }
 
+    @Override
+    public String title() {
+        return PlaceholderRenderService.fallback().asText(PlaceholderLiteral.NULL_REPRESENTATION);
+    }
+
+    private String html() {
+        return PlaceholderRenderService.fallback().asHtml(PlaceholderLiteral.NULL_REPRESENTATION);
+    }
 }
diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoSingular.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoSingular.java
index 7f3980bbf47..1c998426732 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoSingular.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoSingular.java
@@ -18,8 +18,6 @@
  */
 package org.apache.causeway.core.metamodel.objectmanager.memento;
 
-import org.jspecify.annotations.Nullable;
-
 import org.apache.causeway.applib.id.LogicalType;
 import org.apache.causeway.applib.services.bookmark.Bookmark;
 
@@ -27,11 +25,11 @@ record ObjectMementoSingular(
         LogicalType logicalType,
         Bookmark bookmark,
         String title,
-        @Nullable String iconHtml)
+        String prerenderedHtml)
 implements ObjectMemento {
 
     public ObjectDisplayDto toDto() {
-        return new ObjectDisplayDto(logicalType.correspondingClass(), bookmark.stringify(), title, iconHtml);
+        return new ObjectDisplayDto(logicalType.correspondingClass(), bookmark.stringify(), title, prerenderedHtml);
     }
 
     @Override public int hashCode() { return bookmark.hashCode(); }
diff --git a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/select2/Select2.java b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/select2/Select2.java
index 0eae32f863a..f79a6772cce 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/select2/Select2.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/select2/Select2.java
@@ -64,10 +64,8 @@ static Select2 create(
                 var dto = decodeBase64ToJson(opt.id);
                 if(!dto) return "undefined";
                 if(!dto.title) return "undefined";
-                if(dto.iconHtml) {
-                    return $('<span>' + dto.iconHtml + ' ' + dto.title + '</span>');
-                }
-                return dto.title;
+                if(!dto.html) return "undefined";
+                return $(dto.html);
             }""";
 
         settings.setTemplateResult(template);