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 2023/12/20 11:14:34 UTC

(causeway) branch 3663-params.invalidated.by.other.tab created (now f5caf015d4)

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

ahuber pushed a change to branch 3663-params.invalidated.by.other.tab
in repository https://gitbox.apache.org/repos/asf/causeway.git


      at f5caf015d4 CAUSEWAY-3663: snapshot pending param values in the event of page serialization

This branch includes the following new commits:

     new f5caf015d4 CAUSEWAY-3663: snapshot pending param values in the event of page serialization

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-3663: snapshot pending param values in the event of page serialization

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

ahuber pushed a commit to branch 3663-params.invalidated.by.other.tab
in repository https://gitbox.apache.org/repos/asf/causeway.git

commit f5caf015d444fb0081fce2e190340b46ccd1eb0c
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Dec 20 12:14:28 2023 +0100

    CAUSEWAY-3663: snapshot pending param values in the event of page
    serialization
    
    - which may be triggered from a different browser tab, eg. loading the
    app's homepage
---
 .../managed/PropertyNegotiationModel.java          | 13 ++-
 .../interaction/act/ActionInteractionWkt.java      | 23 +++++-
 .../interaction/act/PendingParamsSnapshot.java     | 95 ++++++++++++++++++++++
 3 files changed, 120 insertions(+), 11 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/PropertyNegotiationModel.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/PropertyNegotiationModel.java
index 0336b80695..a0897ff967 100644
--- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/PropertyNegotiationModel.java
+++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/interactions/managed/PropertyNegotiationModel.java
@@ -28,7 +28,7 @@ import org.apache.causeway.commons.internal.binding._Bindables;
 import org.apache.causeway.commons.internal.binding._Observables;
 import org.apache.causeway.commons.internal.binding._Observables.BooleanObservable;
 import org.apache.causeway.commons.internal.binding._Observables.LazyObservable;
-import org.apache.causeway.commons.internal.debug._Debug;
+import org.apache.causeway.commons.internal.debug._XrayEvent;
 import org.apache.causeway.commons.internal.debug.xray.XrayUi;
 import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.causeway.core.metamodel.interactions.managed._BindingUtil.TargetFormat;
@@ -216,12 +216,11 @@ public class PropertyNegotiationModel implements ManagedValue {
     // -- SUBMISSION
 
     public void submit() {
-
-        _Debug.onCondition(XrayUi.isXrayEnabled(), ()->{
-            _Debug.log("[PENDING MODEL] submit pending property value '%s' into owning object", getValue().getValue());
-        });
-
-        managedProperty.modifyProperty(getValue().getValue());
+        var newPropertyValue = getValue().getValue();
+        if(XrayUi.isXrayEnabled()) {
+            _XrayEvent.event("[PENDING MODEL] submit pending property value '%s' into owning object", newPropertyValue);
+        }
+        managedProperty.modifyProperty(newPropertyValue);
         isCurrentValueAbsent.invalidate();
     }
 
diff --git a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/act/ActionInteractionWkt.java b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/act/ActionInteractionWkt.java
index 570a772927..7bf5074997 100644
--- a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/act/ActionInteractionWkt.java
+++ b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/act/ActionInteractionWkt.java
@@ -59,8 +59,9 @@ import lombok.val;
  * defaults provider. This is modeled with {@link #associatedWithCollectionIfAny}.
  *
  * @implSpec the state of pending parameters ParameterNegotiationModel is held transient,
- * that means it does not survive a serialization/de-serialization cycle; instead
- * is recreated with parameter defaults
+ * that means it does not survive a serialization/de-serialization cycle; however,
+ * we capture a snapshot of the pending parameter values in the event serialization
+ * using a serializable {@link PendingParamsSnapshot}.
  *
  * @see ChainingModel
  */
@@ -218,12 +219,23 @@ extends HasBookmarkedOwnerAbstract<ActionInteraction> {
             return parameterNegotiationModel;
         }
 
+        //[CAUSEWAY-3663] restore pending params, in case we do have a snapshot of these
+        if(pendingParamsSnapshot!=null) {
+            this.parameterNegotiationModel =
+                    pendingParamsSnapshot.restoreParameterNegotiationModel(
+                            actionInteraction()
+                                .getManagedAction()
+                                .orElseThrow(()->_Exceptions.noSuchElement(memberId)));
+            return parameterNegotiationModel;
+        }
+
         return startParameterNegotiationModel();
     }
 
     public void resetParametersToDefault() {
         // in effect invalidates the currently memoized parameterNegotiationModel (if any)
         this.parameterNegotiationModel = null;
+        this.pendingParamsSnapshot = null;
     }
 
     public InlinePromptContext getInlinePromptContext() {
@@ -240,12 +252,15 @@ extends HasBookmarkedOwnerAbstract<ActionInteraction> {
      * memoized transiently
      */
     private transient ParameterNegotiationModel parameterNegotiationModel;
+    private PendingParamsSnapshot pendingParamsSnapshot;
     /**
      * Start and transiently memoize a new {@link ParameterNegotiationModel}.
      */
     private ParameterNegotiationModel startParameterNegotiationModel() {
-        return this.parameterNegotiationModel = actionInteraction().startParameterNegotiation()
+        this.parameterNegotiationModel = actionInteraction().startParameterNegotiation()
                 .orElseThrow(()->_Exceptions.noSuchElement(memberId));
+        this.pendingParamsSnapshot = PendingParamsSnapshot.create(parameterNegotiationModel);
+        return parameterNegotiationModel;
     }
     /**
      * [CAUSEWAY-3649] safe guard against access to the model while it is not attached
@@ -253,7 +268,7 @@ extends HasBookmarkedOwnerAbstract<ActionInteraction> {
     private void guardAgainstNotAttached() {
         if(!this.isAttached()) {
             // start over
-            this.parameterNegotiationModel = null;
+            resetParametersToDefault();
             getObject();
         }
         _Assert.assertTrue(this.isAttached(), ()->"model is not attached");
diff --git a/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/act/PendingParamsSnapshot.java b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/act/PendingParamsSnapshot.java
new file mode 100644
index 0000000000..46c134471e
--- /dev/null
+++ b/viewers/wicket/model/src/main/java/org/apache/causeway/viewer/wicket/model/models/interaction/act/PendingParamsSnapshot.java
@@ -0,0 +1,95 @@
+/*
+ *  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.viewer.wicket.model.models.interaction.act;
+
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+
+import org.apache.causeway.applib.services.bookmark.Bookmark;
+import org.apache.causeway.commons.collections.Can;
+import org.apache.causeway.core.metamodel.context.MetaModelContext;
+import org.apache.causeway.core.metamodel.interactions.managed.ManagedAction;
+import org.apache.causeway.core.metamodel.interactions.managed.ParameterNegotiationModel;
+import org.apache.causeway.core.metamodel.object.ManagedObject;
+import org.apache.causeway.core.metamodel.object.ManagedObjects;
+
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+
+/**
+ * In the event of page serialization memoizes all the current pending parameter values
+ * form the {@link ParameterNegotiationModel} this instance was originally created from.
+ * <p>
+ * On de-serialization those snapshot-ed parameter values can be fed back into a new
+ * {@link ParameterNegotiationModel} instance.
+ */
+@AllArgsConstructor(access = AccessLevel.PRIVATE)
+class PendingParamsSnapshot implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    public static PendingParamsSnapshot create(final ParameterNegotiationModel parameterNegotiationModel) {
+        return new PendingParamsSnapshot(null, parameterNegotiationModel);
+    }
+
+    private Can<ManagedObject> parameterValues;
+    private ParameterNegotiationModel parameterNegotiationModel;
+
+    public ParameterNegotiationModel restoreParameterNegotiationModel(final ManagedAction managedAction) {
+        return this.parameterNegotiationModel = ParameterNegotiationModel.of(managedAction, parameterValues);
+    }
+
+    // -- SERIALIZATION PROXY
+
+    private Object writeReplace() {
+        return new SerializationProxy(this);
+    }
+
+    private void readObject(final ObjectInputStream stream) throws InvalidObjectException {
+        throw new InvalidObjectException("Proxy required");
+    }
+
+    private static class SerializationProxy implements Serializable {
+        private static final long serialVersionUID = 1L;
+        private final Can<Bookmark> argBookmarks;
+
+        //TODO[CAUSEWAY-3663] also handle PackedManagedObject
+        private SerializationProxy(final PendingParamsSnapshot pvm) {
+            this.argBookmarks = pvm.parameterNegotiationModel.getParamValues()
+                    .map(managedObj->ManagedObjects.bookmark(managedObj)
+                            .orElseGet(()->Bookmark.empty(managedObj.getLogicalType())));
+        }
+
+        //TODO[CAUSEWAY-3663] also handle PackedManagedObject
+        private Object readResolve() {
+            var objectManager = MetaModelContext.instanceElseFail().getObjectManager();
+            return new PendingParamsSnapshot(
+                    argBookmarks.map(bookmark->
+                        bookmark.isEmpty()
+                        ? ManagedObject.empty(
+                                objectManager.getSpecificationLoader().specForBookmarkElseFail(bookmark))
+                        : objectManager
+                            .loadObject(bookmark)
+                            .orElseThrow()),
+                    null);
+        }
+
+    }
+
+}