You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2021/12/05 08:46:20 UTC

[isis] branch master updated: ISIS-2903: wkt: move responsibility for login-page redirect handling from ActionLink to FormExecutorDefault

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 d417b89  ISIS-2903: wkt: move responsibility for login-page redirect handling from ActionLink to FormExecutorDefault
d417b89 is described below

commit d417b898395460bb13b7541938169593ee7b4ebd
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sun Dec 5 09:46:10 2021 +0100

    ISIS-2903: wkt: move responsibility for login-page redirect handling
    from ActionLink to FormExecutorDefault
    
    - also Xray: debug log interaction boundaries (entry and exit)
---
 .../apache/isis/commons/internal/debug/_Debug.java |  2 ++
 .../internal/debug/xray/_CallStackMerger.java      |  3 +-
 .../commons/internal/exceptions/_Exceptions.java   | 10 +++++--
 .../isis/core/runtimeservices/session/_Xray.java   |  5 ++++
 .../viewer/wicket/model/models/FormExecutor.java   |  8 ++---
 .../widgets/linkandlabel/ActionLink.java           | 34 ++--------------------
 .../wicket/ui/panels/FormExecutorDefault.java      | 31 ++++++++++++++++++--
 7 files changed, 52 insertions(+), 41 deletions(-)

diff --git a/commons/src/main/java/org/apache/isis/commons/internal/debug/_Debug.java b/commons/src/main/java/org/apache/isis/commons/internal/debug/_Debug.java
index ddf2607..43e5616 100644
--- a/commons/src/main/java/org/apache/isis/commons/internal/debug/_Debug.java
+++ b/commons/src/main/java/org/apache/isis/commons/internal/debug/_Debug.java
@@ -124,6 +124,8 @@ public class _Debug {
                 && !se.getClassName().contains("_Xray") // suppress _Xray local helpers
                 && !se.getClassName().startsWith(ChainOfResponsibility.class.getName())
                 && !se.getClassName().startsWith("java.util.stream") // suppress Stream processing details
+                && !se.getClassName().startsWith("org.junit") // suppress Junit processing details
+                && !se.getClassName().startsWith("org.eclipse.jdt.internal") // suppress IDE processing details
                 ;
     }
 
diff --git a/commons/src/main/java/org/apache/isis/commons/internal/debug/xray/_CallStackMerger.java b/commons/src/main/java/org/apache/isis/commons/internal/debug/xray/_CallStackMerger.java
index b0fb9e4..7a0fbc3 100644
--- a/commons/src/main/java/org/apache/isis/commons/internal/debug/xray/_CallStackMerger.java
+++ b/commons/src/main/java/org/apache/isis/commons/internal/debug/xray/_CallStackMerger.java
@@ -150,7 +150,8 @@ final class _CallStackMerger {
         val root = merge(executionLanes);
         callStackDiagram = new CallStackDiagram(root.print(id->{
             return _Exceptions.abbreviate(
-                    executionNodeMap.getOrDefault(id, "root"));
+                    executionNodeMap.getOrDefault(id, "root"),
+                    "org.apache.isis");
         }).toString());
     }
 
diff --git a/commons/src/main/java/org/apache/isis/commons/internal/exceptions/_Exceptions.java b/commons/src/main/java/org/apache/isis/commons/internal/exceptions/_Exceptions.java
index 11f13d6..219fce3 100644
--- a/commons/src/main/java/org/apache/isis/commons/internal/exceptions/_Exceptions.java
+++ b/commons/src/main/java/org/apache/isis/commons/internal/exceptions/_Exceptions.java
@@ -394,12 +394,16 @@ public final class _Exceptions {
             "org.apache.wicket", "{wkt}",
             "org.springframework", "{spring}",
             "org.apache.tomcat", "{tomcat}",
-            "org.apache.catalina", "{catalina}"
+            "org.apache.catalina", "{catalina}",
+            "org.apache.coyote", "{coyote}"
             );
 
-    public static String abbreviate(final String className) {
+    public static String abbreviate(final String className, final String...compress) {
         val str = className;
-        return packageReplacements.entrySet().stream()
+        return Stream.concat(
+                    _NullSafe.stream(compress).map(prefix->Map.entry(prefix, "")),
+                    packageReplacements.entrySet().stream()
+                )
                 .filter(entry->str.startsWith(entry.getKey()))
                 .map(entry->{
                     val replacement = entry.getValue();
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/_Xray.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/_Xray.java
index 2972f5c..58cea06 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/_Xray.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/_Xray.java
@@ -21,6 +21,7 @@ package org.apache.isis.core.runtimeservices.session;
 import java.util.Stack;
 
 import org.apache.isis.applib.services.iactnlayer.InteractionLayer;
+import org.apache.isis.commons.internal.debug._Debug;
 import org.apache.isis.commons.internal.debug.xray.XrayDataModel;
 import org.apache.isis.commons.internal.debug.xray.XrayModel.ThreadMemento;
 import org.apache.isis.commons.internal.debug.xray.XrayUi;
@@ -42,6 +43,8 @@ final class _Xray {
         val interactionId = afterEnter.peek().getInteraction().getInteractionId();
         val executionContext = afterEnter.peek().getInteractionContext();
 
+        _Debug.log(10, "open interaction %s", interactionId);
+
         val threadId = ThreadMemento.fromCurrentThread();
 
         XrayUi.updateModel(model->{
@@ -96,6 +99,8 @@ final class _Xray {
         val interactionId = beforeClose.peek().getInteraction().getInteractionId();
         val sequenceId = XrayUtil.sequenceId(interactionId);
 
+        _Debug.log(10, "close interaction %s", interactionId);
+
         XrayUi.updateModel(model->{
 
             val uiInteractionId = XrayUtil.nestedInteractionId(authStackSize);
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/FormExecutor.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/FormExecutor.java
index e6fbfb4..ffb1e4e 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/FormExecutor.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/FormExecutor.java
@@ -34,14 +34,14 @@ public interface FormExecutor extends Serializable {
     enum FormExecutionOutcome {
 
         /**
-         * if invalid arguments or exception
+         * if invalid arguments or recoverable exception
          */
         FAILURE_SO_STAY_ON_PAGE,
 
         /**
          * redirect to result page or re-render all UI components
          */
-        SUCCESS_SO_REDIRECT_TO_RESULT_PAGE,
+        SUCCESS_AND_REDIRECED_TO_RESULT_PAGE,
 
         /**
          * do not trigger a full page re-render, when executing eg. a nested dialog
@@ -50,10 +50,10 @@ public interface FormExecutor extends Serializable {
 
         public boolean isFailure() { return this == FAILURE_SO_STAY_ON_PAGE; }
         public boolean isSuccess() { return !isFailure(); }
-        public boolean isSuccessWithRedirect() { return this == SUCCESS_SO_REDIRECT_TO_RESULT_PAGE; }
+        public boolean isSuccessWithRedirect() { return this == SUCCESS_AND_REDIRECED_TO_RESULT_PAGE; }
         public boolean isSuccessWithinNestedContext() { return this == SUCCESS_IN_NESTED_CONTEXT_SO_STAY_ON_PAGE; }
 
-        public boolean isRedirect() { return this == SUCCESS_SO_REDIRECT_TO_RESULT_PAGE; }
+        public boolean isRedirect() { return this == SUCCESS_AND_REDIRECED_TO_RESULT_PAGE; }
 
     }
 
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLink.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLink.java
index 1f0ad4e..29fb7c3 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLink.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLink.java
@@ -18,8 +18,6 @@
  */
 package org.apache.isis.viewer.wicket.ui.components.widgets.linkandlabel;
 
-import java.util.Optional;
-
 import org.apache.wicket.Application;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
@@ -35,21 +33,18 @@ import org.apache.isis.commons.internal.debug.xray.XrayUi;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.runtime.context.IsisAppCommonContext;
-import org.apache.isis.core.security.authentication.logout.LogoutMenu.LoginRedirect;
 import org.apache.isis.viewer.common.model.components.ComponentType;
 import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
 import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettingsAccessor;
 import org.apache.isis.viewer.wicket.model.models.ActionModel;
 import org.apache.isis.viewer.wicket.model.models.ActionPromptProvider;
 import org.apache.isis.viewer.wicket.model.models.ActionPromptWithExtraContent;
-import org.apache.isis.viewer.wicket.model.models.PageType;
 import org.apache.isis.viewer.wicket.model.util.CommonContextUtils;
 import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistry;
 import org.apache.isis.viewer.wicket.ui.app.registry.ComponentFactoryRegistryAccessor;
 import org.apache.isis.viewer.wicket.ui.components.actions.ActionParametersPanel;
 import org.apache.isis.viewer.wicket.ui.components.layout.bs3.BS3GridPanel;
 import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelAbstract;
-import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry;
 import org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage;
 import org.apache.isis.viewer.wicket.ui.panels.FormExecutorDefault;
 import org.apache.isis.viewer.wicket.ui.panels.PanelUtil;
@@ -221,36 +216,13 @@ extends IndicatingAjaxLink<ManagedObject> {
         val actionModel = this.getActionModel();
         val page = this.getPage();
 
+        // on non-recoverable exception throws
         val outcome = FormExecutorDefault
                 .forAction(actionModel)
                 .executeAndProcessResults(page, null, null, actionModel);
 
-        if(outcome.isSuccess()) {
-
-            // intercept redirect request to sign-in page
-            Optional.ofNullable(actionModel.getObject())
-            .ifPresent(actionResultAdapter->{
-                val actionResultObjectType = actionResultAdapter.getSpecification().getLogicalTypeName();
-                if(LoginRedirect.LOGICAL_TYPE_NAME.equals(actionResultObjectType)) {
-                    val commonContext = actionModel.getCommonContext();
-                    val pageClassRegistry = commonContext.lookupServiceElseFail(PageClassRegistry.class);
-                    val signInPage = pageClassRegistry.getPageClass(PageType.SIGN_IN);
-                    RequestCycle.get().setResponsePage(signInPage);
-                }
-            });
-
-            _Debug.onCondition(XrayUi.isXrayEnabled(), ()->{
-                _Debug.log(10, "nothing to do, outcome: %s", outcome);
-            });
-
-            // else nothing to do
-
-            //
-            // the formExecutor will have either redirected, or scheduled a response,
-            // or repainted components as required
-            //
-
-        } else {
+        // on recoverable exception stay on page (eg. validation failure)
+        if(outcome.isFailure()) {
 
             _Debug.onCondition(XrayUi.isXrayEnabled(), ()->{
                 _Debug.log(10, "render the target entity again, outcome: %s", outcome);
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/FormExecutorDefault.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/FormExecutorDefault.java
index e26f520..8a0b3d5 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/FormExecutorDefault.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/FormExecutorDefault.java
@@ -23,6 +23,7 @@ import java.util.Optional;
 import org.apache.wicket.Page;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.request.cycle.RequestCycle;
 import org.springframework.lang.Nullable;
 
 import org.apache.isis.applib.services.exceprecog.Category;
@@ -36,13 +37,16 @@ import org.apache.isis.commons.internal.debug._Debug;
 import org.apache.isis.commons.internal.debug.xray.XrayUi;
 import org.apache.isis.core.metamodel.spec.ManagedObjects.EntityUtil;
 import org.apache.isis.core.runtime.context.IsisAppCommonContext;
+import org.apache.isis.core.security.authentication.logout.LogoutMenu.LoginRedirect;
 import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
 import org.apache.isis.viewer.wicket.model.models.ActionModel;
 import org.apache.isis.viewer.wicket.model.models.FormExecutor;
 import org.apache.isis.viewer.wicket.model.models.FormExecutorContext;
+import org.apache.isis.viewer.wicket.model.models.PageType;
 import org.apache.isis.viewer.wicket.model.models.ScalarPropertyModel;
 import org.apache.isis.viewer.wicket.ui.actionresponse.ActionResultResponse;
 import org.apache.isis.viewer.wicket.ui.actionresponse.ActionResultResponseType;
+import org.apache.isis.viewer.wicket.ui.pages.PageClassRegistry;
 import org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage;
 
 import lombok.NonNull;
@@ -148,7 +152,7 @@ implements FormExecutor {
             }
 
             _Debug.onCondition(XrayUi.isXrayEnabled(), ()->{
-                _Debug.log(10, "process result ...");
+                _Debug.log(10, "interpret result ...");
             });
 
             val resultResponse = actionOrPropertyModel.fold(
@@ -157,12 +161,35 @@ implements FormExecutor {
                     prop->ActionResultResponse
                             .toPage(EntityPage.ofAdapter(prop.getCommonContext(), resultAdapter)));
 
+            _Debug.onCondition(XrayUi.isXrayEnabled(), ()->{
+                _Debug.log(10, "handle result ...");
+            });
+
             // redirect unconditionally
             resultResponse
                 .getHandlingStrategy()
                 .handleResults(getCommonContext(), resultResponse);
 
-            return FormExecutionOutcome.SUCCESS_SO_REDIRECT_TO_RESULT_PAGE; // success (valid args), allow redirect
+
+            // intercept redirect request to sign-in page, TODO should be refactored into a new HandlingStrategy
+            if(actionOrPropertyModel.isLeft()) {
+                Optional.ofNullable(resultAdapter)
+                .ifPresent(actionResultAdapter->{
+                    val actionResultObjectType = actionResultAdapter.getSpecification().getLogicalTypeName();
+                    if(LoginRedirect.LOGICAL_TYPE_NAME.equals(actionResultObjectType)) {
+                        val signInPage = getCommonContext()
+                                .lookupServiceElseFail(PageClassRegistry.class)
+                                .getPageClass(PageType.SIGN_IN);
+                        RequestCycle.get().setResponsePage(signInPage);
+                    }
+                });
+            }
+
+            _Debug.onCondition(XrayUi.isXrayEnabled(), ()->{
+                _Debug.log(10, "... return");
+            });
+
+            return FormExecutionOutcome.SUCCESS_AND_REDIRECED_TO_RESULT_PAGE; // success (valid args), allow redirect
 
         } catch (Throwable ex) {