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

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/master by this push:
     new 07f6debe46 ISIS-2297: select2: properly handle empty (none) selections
07f6debe46 is described below

commit 07f6debe464da9ba36d6a5ea732917512a6fd8a9
Author: Andi Huber <[email protected]>
AuthorDate: Wed Nov 9 07:49:32 2022 +0100

    ISIS-2297: select2: properly handle empty (none) selections
---
 .../objectmanager/memento/ObjectMemento.java       | 27 +++++++++++++++-------
 .../memento/ObjectMementoForEmpty.java             |  2 ++
 .../memento/ObjectMementoForScalar.java            |  3 +++
 .../widgets/select2/Select2OnSelect.java           | 22 +++++++++++++++---
 .../select2/providers/ChoiceProviderAbstract.java  | 10 ++------
 5 files changed, 45 insertions(+), 19 deletions(-)

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 da192f8df2..ff0fba5f3b 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
@@ -35,11 +35,16 @@ import 
org.apache.causeway.commons.internal.collections._Lists;
 import org.apache.causeway.commons.internal.resources._Serializables;
 import org.apache.causeway.core.metamodel.object.ManagedObject;
 
+import lombok.val;
+
 /**
  * @since 2.0
  */
 public interface ObjectMemento extends BookmarkHolder, HasLogicalType, 
Serializable {
 
+    /** arbitrary/random string */
+    static final String NULL_ID = "VGN6r6zKTiLhUsA0WkdQ17LvMU1IYdb0";
+
     /**
      * The object's title for rendering (before translation).
      * Corresponds to {@link ManagedObject#getTitle()}.
@@ -75,23 +80,29 @@ public interface ObjectMemento extends BookmarkHolder, 
HasLogicalType, Serializa
 
     @Nullable
     static String enstringToUrlBase64(final @Nullable ObjectMemento memento) {
-        return memento!=null
+        val base64UrlEncodedMemento = memento!=null
                 ? _Strings.ofBytes(
                     _Bytes.asUrlBase64.apply(
                             _Serializables.write(memento)),
                     StandardCharsets.US_ASCII)
                 : null;
+        return base64UrlEncodedMemento;
     }
 
     @Nullable
     static ObjectMemento destringFromUrlBase64(final @Nullable String 
base64UrlEncodedMemento) {
-        return _Strings.isNotEmpty(base64UrlEncodedMemento)
-                ? _Serializables.read(
-                        ObjectMemento.class,
-                        _Bytes.ofUrlBase64.apply(
-                                
base64UrlEncodedMemento.getBytes(StandardCharsets.US_ASCII)))
-                : null;
-    }
+        try {
+            return _Strings.isNotEmpty(base64UrlEncodedMemento)
+                    && !NULL_ID.equals(base64UrlEncodedMemento)
+                    ? _Serializables.read(
+                            ObjectMemento.class,
+                            _Bytes.ofUrlBase64.apply(
+                                    
base64UrlEncodedMemento.getBytes(StandardCharsets.US_ASCII)))
+                    : null;
+        } catch (Exception e) {
+            return null; // map to null if anything goes wrong
+        }
 
+    }
 
 }
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoForEmpty.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoForEmpty.java
index 5a70c042d3..8ed48882e1 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoForEmpty.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoForEmpty.java
@@ -26,10 +26,12 @@ import 
org.apache.causeway.applib.services.placeholder.PlaceholderRenderService.
 import lombok.Getter;
 import lombok.NonNull;
 import lombok.RequiredArgsConstructor;
+import lombok.ToString;
 
 /**
  * @since 2.0
  */
+@ToString
 @RequiredArgsConstructor
 public class ObjectMementoForEmpty implements ObjectMemento {
 
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoForScalar.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoForScalar.java
index 03b8c796b8..164d55b2f5 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoForScalar.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoForScalar.java
@@ -36,8 +36,10 @@ import 
org.apache.causeway.core.metamodel.specloader.SpecificationLoader;
 
 import lombok.Getter;
 import lombok.NonNull;
+import lombok.ToString;
 import lombok.val;
 
+@ToString
 public final class ObjectMementoForScalar
 implements HasLogicalType, Serializable, ObjectMemento {
 
@@ -66,6 +68,7 @@ implements HasLogicalType, Serializable, ObjectMemento {
     @Getter(onMethod_ = {@Override}) private final String title;
     @Getter final Bookmark bookmark;
 
+    @ToString.Exclude
     byte[] serializedPayload;
 
     private ObjectMementoForScalar(
diff --git 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/select2/Select2OnSelect.java
 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/select2/Select2OnSelect.java
index 8e2d4da9ed..3b2e66f77c 100644
--- 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/select2/Select2OnSelect.java
+++ 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/select2/Select2OnSelect.java
@@ -107,9 +107,13 @@ class Select2OnSelect extends AbstractAjaxBehavior {
     private void updatePendingModels() {
         PageParameterUtils.streamCurrentRequestParameters()
         .forEach(pair->
-            Event.valueOf(pair).ifPresent(event->{
-                val objectMementoFromEvent = 
ObjectMemento.destringFromUrlBase64(pair.getValue());
+            Event.valueOf(pair)
+            .ifPresent(event->{
                 if(getComponent() instanceof Select2MultiChoiceExt) {
+                    val objectMementoFromEvent = 
ObjectMemento.destringFromUrlBase64(pair.getValue());
+                    if(objectMementoFromEvent==null) {
+                        return; // add or remove nothing is a no-op
+                    }
                     val component = (Select2MultiChoiceExt)getComponent();
                     switch(event) {
                     case SELECT:{
@@ -137,6 +141,13 @@ class Select2OnSelect extends AbstractAjaxBehavior {
                     val component = (Select2ChoiceExt)getComponent();
                     switch(event) {
                     case SELECT:
+                        val objectMementoFromEvent = 
ObjectMemento.destringFromUrlBase64(pair.getValue());
+                        if(objectMementoFromEvent==null) {
+                            // select nothing is rather a CLEAR operation
+                            component.clearInput();
+                            clearUpdateReceiver();
+                            return;
+                        }
                         component.setModelObject(objectMementoFromEvent);
                         
updateReceiver().setValue(demementify(objectMementoFromEvent));
                         break;
@@ -150,7 +161,12 @@ class Select2OnSelect extends AbstractAjaxBehavior {
                 } else return;
 
                 if(XrayUi.isXrayEnabled()) {
-                    _XrayEvent.event("Select2 event: %s %s", event, 
objectMementoFromEvent.getBookmark());
+                    val objectMementoFromEvent = 
ObjectMemento.destringFromUrlBase64(pair.getValue());
+                    if(objectMementoFromEvent!=null) {
+                        _XrayEvent.event("Select2 event: %s %s", event, 
objectMementoFromEvent.getBookmark());
+                    } else {
+                        _XrayEvent.event("Select2 event: %s %s", event, 
"(none)");
+                    }
                 }
 
                 // schedule form update (AJAX)
diff --git 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/select2/providers/ChoiceProviderAbstract.java
 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/select2/providers/ChoiceProviderAbstract.java
index ce610b0995..eb89524fa3 100644
--- 
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/select2/providers/ChoiceProviderAbstract.java
+++ 
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/components/widgets/select2/providers/ChoiceProviderAbstract.java
@@ -41,9 +41,6 @@ extends ChoiceProvider<ObjectMemento>
 implements HasCommonContext {
     private static final long serialVersionUID = 1L;
 
-    /** arbitrary string */
-    private static final String NULL_ID = "VGN6r6zKTiLhUsA0WkdQ17LvMU1IYdb0";
-
     /**
      * Whether to not prepend <code>null</code> as choice candidate.
      */
@@ -66,15 +63,12 @@ implements HasCommonContext {
     @Override
     public final String getIdValue(final ObjectMemento choiceMemento) {
         if (choiceMemento == null) {
-            return NULL_ID;
+            return ObjectMemento.NULL_ID;
         }
         return ObjectMemento.enstringToUrlBase64(choiceMemento);
     }
 
     protected final @Nullable ObjectMemento mementoFromId(final @Nullable 
String id) {
-        if(NULL_ID.equals(id)) {
-            return null;
-        }
         return ObjectMemento.destringFromUrlBase64(id);
     }
 
@@ -137,7 +131,7 @@ implements HasCommonContext {
     // -- HELPER
 
     private @Nullable ObjectMemento mementoFromIdWithNullHandling(final String 
id) {
-        if(NULL_ID.equals(id)) {
+        if(ObjectMemento.NULL_ID.equals(id)) {
             return null;
         }
         return mementoFromId(id);

Reply via email to