This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/causeway.git
The following commit(s) were added to refs/heads/main by this push:
new d27bc33a148 CAUSEWAY-3859: Java record refactoring (part 45)
d27bc33a148 is described below
commit d27bc33a148bdc82957e838229ded8cfb1e218bb
Author: Andi Huber <[email protected]>
AuthorDate: Tue Feb 25 21:10:58 2025 +0100
CAUSEWAY-3859: Java record refactoring (part 45)
---
.../ui/actionresponse/ActionResultResponse.java | 97 ---------
.../ActionResultResponseHandlingStrategy.java | 180 ----------------
...oadHandler.java => DownloadHandlerFactory.java} | 29 +--
.../ui/actionresponse/ExecutionResultHandler.java | 41 ++++
.../viewer/wicket/ui/actionresponse/Mediator.java | 228 +++++++++++++++++++++
.../{_ResponseUtil.java => MediatorFactory.java} | 95 +++++----
.../ui/actionresponse/PageRedirectRequest.java | 18 +-
.../wicket/ui/actionresponse/_RedirectHandler.java | 51 -----
.../wicket/ui/panels/FormExecutorDefault.java | 19 +-
9 files changed, 348 insertions(+), 410 deletions(-)
diff --git
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/ActionResultResponse.java
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/ActionResultResponse.java
deleted file mode 100644
index 9f0917118c2..00000000000
---
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/ActionResultResponse.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.ui.actionresponse;
-
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.request.IRequestHandler;
-
-import org.jspecify.annotations.Nullable;
-
-import org.apache.causeway.applib.value.OpenUrlStrategy;
-import org.apache.causeway.core.metamodel.object.ManagedObject;
-import org.apache.causeway.viewer.wicket.model.models.ActionModel;
-import org.apache.causeway.viewer.wicket.ui.pages.obj.DomainObjectPage;
-
-import org.jspecify.annotations.NonNull;
-
-/**
- * The response to provide as a result of interpreting the response;
- * either to show a {@link #toPage(PageRedirectRequest) page}, or to
- * {@link #withHandler(IRequestHandler) redirect} to a
- * handler (eg a download).
- */
-public record ActionResultResponse(
- ActionResultResponseHandlingStrategy handlingStrategy,
- /**
- * Populated only if {@link #handlingStrategy()}
- * is {@link ActionResultResponseHandlingStrategy#SCHEDULE_HANDLER}
- */
- IRequestHandler handler,
- /**
- * Populated only if {@link #handlingStrategy()}
- * is {@link ActionResultResponseHandlingStrategy#REDIRECT_TO_PAGE}
- */
- PageRedirectRequest<?> pageRedirect,
- /**
- * Populated only if {@link #handlingStrategy()} is
- * either {@link
ActionResultResponseHandlingStrategy#OPEN_URL_IN_NEW_BROWSER_WINDOW}
- * or {@link
ActionResultResponseHandlingStrategy#OPEN_URL_IN_SAME_BROWSER_WINDOW}
- */
- AjaxRequestTarget ajaxTarget,
- /**
- * Populated only if {@link #handlingStrategy()} is
- * either {@link
ActionResultResponseHandlingStrategy#OPEN_URL_IN_NEW_BROWSER_WINDOW}
- * or {@link
ActionResultResponseHandlingStrategy#OPEN_URL_IN_SAME_BROWSER_WINDOW}
- */
- String url) {
-
- public static ActionResultResponse toDomainObjectPage(final @NonNull
ManagedObject entityOrViewmodel) {
- var pageRedirectRequest = PageRedirectRequest.forPageClassAndBookmark(
- DomainObjectPage.class,
entityOrViewmodel.refreshBookmark().orElseThrow());
- return ActionResultResponse.toPage(pageRedirectRequest);
- }
-
- public static ActionResultResponse determineAndInterpretResult(
- final ActionModel actionModel,
- final @Nullable AjaxRequestTarget targetIfAny,
- final @Nullable ManagedObject resultAdapter) {
- return _ResponseUtil.determineAndInterpretResult(actionModel,
targetIfAny, resultAdapter);
- }
-
- static ActionResultResponse withHandler(final IRequestHandler handler) {
- return new ActionResultResponse(
- ActionResultResponseHandlingStrategy.SCHEDULE_HANDLER,
handler, null, null, null);
- }
-
- static ActionResultResponse toPage(final PageRedirectRequest<?> page) {
- return new ActionResultResponse(
- ActionResultResponseHandlingStrategy.REDIRECT_TO_PAGE, null,
page, null, null);
- }
-
- static ActionResultResponse openUrlInBrowser(
- final AjaxRequestTarget ajaxTarget,
- final String url,
- final @NonNull OpenUrlStrategy openUrlStrategy) {
- return new ActionResultResponse(
- openUrlStrategy.isNewWindow()
- ?
ActionResultResponseHandlingStrategy.OPEN_URL_IN_NEW_BROWSER_WINDOW
- :
ActionResultResponseHandlingStrategy.OPEN_URL_IN_SAME_BROWSER_WINDOW,
- null, null, ajaxTarget, url);
- }
-}
diff --git
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/ActionResultResponseHandlingStrategy.java
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/ActionResultResponseHandlingStrategy.java
deleted file mode 100644
index 638f03a5d9b..00000000000
---
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/ActionResultResponseHandlingStrategy.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * 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.ui.actionresponse;
-
-import java.time.Duration;
-
-import org.apache.wicket.Component;
-import org.apache.wicket.ajax.AjaxRequestTarget;
-import org.apache.wicket.behavior.AbstractAjaxBehavior;
-import org.apache.wicket.request.IRequestHandler;
-import org.apache.wicket.request.Url;
-import org.apache.wicket.request.cycle.RequestCycle;
-import org.apache.wicket.request.handler.resource.ResourceStreamRequestHandler;
-import org.apache.wicket.request.resource.ContentDisposition;
-import org.apache.wicket.util.resource.IResourceStream;
-
-import org.apache.causeway.commons.internal.exceptions._Exceptions;
-import org.apache.causeway.core.metamodel.context.MetaModelContext;
-import
org.apache.causeway.viewer.wicket.model.models.RedirectRequestHandlerWithOpenUrlStrategy;
-
-public enum ActionResultResponseHandlingStrategy {
- REDIRECT_TO_PAGE {
- @Override
- public void handleResults(
- final ActionResultResponse resultResponse) {
-
- // force any changes in state etc to happen now prior to the
redirect;
- // in the case of an object being returned, this should cause our
page mementos
- // (eg EntityModel) to hold the correct state. I hope.
-
MetaModelContext.instance().ifPresent(mmc->mmc.getTransactionService().flushTransaction());
-
- // "redirect-after-post"
- resultResponse.pageRedirect().apply();
- }
- },
- SCHEDULE_HANDLER {
- @Override
- public void handleResults(
- final ActionResultResponse resultResponse) {
-
- final RequestCycle requestCycle = RequestCycle.get();
- var ajaxTarget =
requestCycle.find(AjaxRequestTarget.class).orElse(null);
-
- if (ajaxTarget == null) {
- // non-Ajax request => just stream the Lob to the browser
- // or if this is a no-arg action, there also will be no parent
for the component
-
requestCycle.scheduleRequestHandlerAfterCurrent(resultResponse.handler());
- } else {
- // otherwise,
- // Ajax request => respond with a redirect to be able to
stream the Lob to the client
- final IRequestHandler requestHandler =
resultResponse.handler();
- if(requestHandler instanceof ResourceStreamRequestHandler
scheduledHandler) {
- var streamingBehavior = new
StreamAfterAjaxResponseBehavior(scheduledHandler);
- var page = ajaxTarget.getPage();
- page.add(streamingBehavior);
- CharSequence callbackUrl =
streamingBehavior.getCallbackUrl();
- scheduleJs(ajaxTarget,
javascriptFor_sameWindow(callbackUrl), 10);
- } else if(requestHandler instanceof
RedirectRequestHandlerWithOpenUrlStrategy redirectHandler) {
-
- final String url = redirectHandler.getRedirectUrl();
- final String fullUrl = expanded(requestCycle, url);
-
- if(redirectHandler.getOpenUrlStrategy().isNewWindow()) {
- scheduleJs(ajaxTarget,
javascriptFor_newWindow(fullUrl), 100);
- } else {
- scheduleJs(ajaxTarget,
javascriptFor_sameWindow(fullUrl), 100);
- }
- } else {
- throw _Exceptions.unrecoverable(
- "no logic implemented to handle IRequestHandler of
type %s",
- requestHandler.getClass().getName());
- }
-
- }
- }
- },
- OPEN_URL_IN_NEW_BROWSER_WINDOW {
- @Override
- public void handleResults(
- final ActionResultResponse resultResponse) {
-
- final String url = resultResponse.url();
- final RequestCycle requestCycle = RequestCycle.get();
- final String fullUrl = expanded(requestCycle, url);
-
- scheduleJs(resultResponse.ajaxTarget(),
javascriptFor_newWindow(fullUrl), 100);
- }
- },
- OPEN_URL_IN_SAME_BROWSER_WINDOW {
- @Override
- public void handleResults(
- final ActionResultResponse resultResponse) {
-
- final String url = resultResponse.url();
- final RequestCycle requestCycle = RequestCycle.get();
- final String fullUrl = expanded(requestCycle, url);
-
- scheduleJs(resultResponse.ajaxTarget(),
javascriptFor_sameWindow(fullUrl), 100);
- }
- };
-
- public abstract void handleResults(
- ActionResultResponse resultResponse);
-
- /**
- * @see #expanded(String)
- */
- public static String expanded(final RequestCycle requestCycle, final
String url) {
- String urlStr = expanded(url);
- return requestCycle.getUrlRenderer().renderFullUrl(Url.parse(urlStr));
- }
-
- /**
- * very simple template support, the idea being that
"antiCache=${currentTimeMillis}"
- * will be replaced automatically.
- */
- public static String expanded(String urlStr) {
- if(urlStr.contains("antiCache=${currentTimeMillis}")) {
- urlStr = urlStr.replace("antiCache=${currentTimeMillis}",
"antiCache="+System.currentTimeMillis());
- }
- return urlStr;
- }
-
- private static String javascriptFor_newWindow(final CharSequence url) {
- return
"function(){Wicket.Event.publish(Causeway.Topic.OPEN_IN_NEW_TAB, '" + url +
"');}";
- }
-
- private static String javascriptFor_sameWindow(final CharSequence url) {
- return "\"window.location.href='" + url + "'\"";
- }
-
- private static void scheduleJs(final AjaxRequestTarget target, final
String js, final int millis) {
- // the timeout is needed to let Wicket release the channel
- target.appendJavaScript(String.format("setTimeout(%s, %d);", js,
millis));
- }
-
- /**
- * A special Ajax behavior that is used to stream the contents of a Lob
after
- * an Ajax request.
- */
- private static class StreamAfterAjaxResponseBehavior extends
AbstractAjaxBehavior {
- private static final long serialVersionUID = 1L;
-
- private final String fileName;
- private final IResourceStream resourceStream;
- private final Duration cacheDuration;
-
- public StreamAfterAjaxResponseBehavior(final
ResourceStreamRequestHandler scheduledHandler) {
- this.fileName = scheduledHandler.getFileName();
- this.resourceStream = scheduledHandler.getResourceStream();
- this.cacheDuration = scheduledHandler.getCacheDuration();
- }
-
- @Override
- public void onRequest() {
- ResourceStreamRequestHandler handler = new
ResourceStreamRequestHandler(resourceStream, fileName);
- handler.setCacheDuration(cacheDuration);
- handler.setContentDisposition(ContentDisposition.ATTACHMENT);
- Component page = getComponent();
- page.getRequestCycle().scheduleRequestHandlerAfterCurrent(handler);
- page.remove(this);
- }
- }
-}
diff --git
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/_DownloadHandler.java
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/DownloadHandlerFactory.java
similarity index 83%
rename from
viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/_DownloadHandler.java
rename to
viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/DownloadHandlerFactory.java
index dc45a292226..ba4aa7d6e7d 100644
---
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/_DownloadHandler.java
+++
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/DownloadHandlerFactory.java
@@ -39,17 +39,15 @@
import lombok.experimental.UtilityClass;
@UtilityClass
-final class _DownloadHandler {
+final class DownloadHandlerFactory {
public IRequestHandler downloadHandler(
final ObjectAction action,
final Object value) {
- if(value instanceof Clob) {
- var clob = (Clob)value;
+ if(value instanceof Clob clob) {
return handlerFor(action, resourceStreamFor(clob), clob);
}
- if(value instanceof Blob) {
- var blob = (Blob)value;
+ if(value instanceof Blob blob) {
return handlerFor(action, resourceStreamFor(blob), blob);
}
return null;
@@ -59,28 +57,21 @@ public IRequestHandler downloadHandler(
private IResourceStream resourceStreamFor(final Blob blob) {
final IResourceStream resourceStream = new AbstractResourceStream() {
-
private static final long serialVersionUID = 1L;
-
- @Override
- public InputStream getInputStream() throws
ResourceStreamNotFoundException {
- return new ByteArrayInputStream(blob.getBytes());
+ @Override public InputStream getInputStream() throws
ResourceStreamNotFoundException {
+ return new ByteArrayInputStream(blob.bytes());
}
-
- @Override
- public String getContentType() {
- return blob.getMimeType().toString();
+ @Override public String getContentType() {
+ return blob.mimeType().toString();
}
-
- @Override
- public void close() throws IOException {
+ @Override public void close() throws IOException {
}
};
return resourceStream;
}
private IResourceStream resourceStreamFor(final Clob clob) {
- return new StringResourceStream(clob.getChars(),
clob.getMimeType().toString());
+ return new StringResourceStream(clob.chars(),
clob.mimeType().toString());
}
private IRequestHandler handlerFor(
@@ -88,7 +79,7 @@ private IRequestHandler handlerFor(
final IResourceStream resourceStream,
final NamedWithMimeType namedWithMimeType) {
var handler =
- new ResourceStreamRequestHandler(resourceStream,
namedWithMimeType.getName());
+ new ResourceStreamRequestHandler(resourceStream,
namedWithMimeType.name());
handler.setContentDisposition(ContentDisposition.ATTACHMENT);
//CAUSEWAY-1619, prevent clients from caching the response content
diff --git
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/ExecutionResultHandler.java
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/ExecutionResultHandler.java
new file mode 100644
index 00000000000..84425641fa4
--- /dev/null
+++
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/ExecutionResultHandler.java
@@ -0,0 +1,41 @@
+/*
+ * 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.ui.actionresponse;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+
+import org.apache.causeway.commons.functional.Either;
+import org.apache.causeway.core.metamodel.object.ManagedObject;
+import org.apache.causeway.viewer.wicket.model.models.ActionModel;
+import org.apache.causeway.viewer.wicket.model.models.PropertyModel;
+
+public record ExecutionResultHandler(Either<ActionModel, PropertyModel>
actionOrPropertyModel) {
+
+ public void handle(final AjaxRequestTarget ajaxTarget, final ManagedObject
result) {
+ // triggers ManagedObject.getBookmarkRefreshed()
+ var mediator = actionOrPropertyModel.fold(
+ act->Mediator.determineAndInterpretResult(act, ajaxTarget,
result),
+ prop->Mediator.toDomainObjectPage(result));
+
+ // redirect using associated strategy
+ // on property edit, triggers SQL update (on JPA)
+ mediator.handle();
+ }
+
+}
diff --git
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/Mediator.java
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/Mediator.java
new file mode 100644
index 00000000000..3b8a9f908af
--- /dev/null
+++
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/Mediator.java
@@ -0,0 +1,228 @@
+/*
+ * 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.ui.actionresponse;
+
+import java.time.Duration;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.behavior.AbstractAjaxBehavior;
+import org.apache.wicket.request.IRequestHandler;
+import org.apache.wicket.request.Url;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.handler.resource.ResourceStreamRequestHandler;
+import org.apache.wicket.request.resource.ContentDisposition;
+import org.apache.wicket.util.resource.IResourceStream;
+import org.jspecify.annotations.NonNull;
+import org.jspecify.annotations.Nullable;
+
+import org.apache.causeway.applib.value.OpenUrlStrategy;
+import org.apache.causeway.commons.internal.exceptions._Exceptions;
+import org.apache.causeway.core.metamodel.context.MetaModelContext;
+import org.apache.causeway.core.metamodel.object.ManagedObject;
+import org.apache.causeway.viewer.wicket.model.models.ActionModel;
+import
org.apache.causeway.viewer.wicket.model.models.RedirectRequestHandlerWithOpenUrlStrategy;
+import org.apache.causeway.viewer.wicket.ui.pages.obj.DomainObjectPage;
+
+/**
+ * {@link #handle()} handles the execution response using given {@link
ExecutionResultHandlingStrategy}.
+ */
+record Mediator(
+ ExecutionResultHandlingStrategy handlingStrategy,
+ /**
+ * Populated only if {@link #handlingStrategy()}
+ * is {@link ExecutionResultHandlingStrategy#SCHEDULE_HANDLER}
+ */
+ IRequestHandler handler,
+ /**
+ * Populated only if {@link #handlingStrategy()}
+ * is {@link ExecutionResultHandlingStrategy#REDIRECT_TO_PAGE}
+ */
+ PageRedirectRequest<?> pageRedirect,
+ /**
+ * Populated only if {@link #handlingStrategy()} is
+ * either {@link
ExecutionResultHandlingStrategy#OPEN_URL_IN_NEW_BROWSER_WINDOW}
+ * or {@link
ExecutionResultHandlingStrategy#OPEN_URL_IN_SAME_BROWSER_WINDOW}
+ */
+ AjaxRequestTarget ajaxTarget,
+ /**
+ * Populated only if {@link #handlingStrategy()} is
+ * either {@link
ExecutionResultHandlingStrategy#OPEN_URL_IN_NEW_BROWSER_WINDOW}
+ * or {@link
ExecutionResultHandlingStrategy#OPEN_URL_IN_SAME_BROWSER_WINDOW}
+ */
+ String url) {
+
+ enum ExecutionResultHandlingStrategy {
+ REDIRECT_TO_PAGE,
+ OPEN_URL_IN_NEW_BROWSER_WINDOW,
+ OPEN_URL_IN_SAME_BROWSER_WINDOW,
+ SCHEDULE_HANDLER
+ }
+
+ static Mediator toDomainObjectPage(final @NonNull ManagedObject
entityOrViewmodel) {
+ var pageRedirectRequest = PageRedirectRequest.forPageClassAndBookmark(
+ DomainObjectPage.class,
entityOrViewmodel.refreshBookmark().orElseThrow());
+ return Mediator.toPage(pageRedirectRequest);
+ }
+
+ static Mediator determineAndInterpretResult(
+ final ActionModel actionModel,
+ final @Nullable AjaxRequestTarget targetIfAny,
+ final @Nullable ManagedObject resultAdapter) {
+ return MediatorFactory.determineAndInterpretResult(actionModel,
targetIfAny, resultAdapter);
+ }
+
+ static Mediator withHandler(final IRequestHandler handler) {
+ return new Mediator(
+ ExecutionResultHandlingStrategy.SCHEDULE_HANDLER, handler,
null, null, null);
+ }
+
+ static Mediator toPage(final PageRedirectRequest<?> page) {
+ return new Mediator(
+ ExecutionResultHandlingStrategy.REDIRECT_TO_PAGE, null, page,
null, null);
+ }
+
+ static Mediator openUrlInBrowser(
+ final AjaxRequestTarget ajaxTarget,
+ final String url,
+ final @NonNull OpenUrlStrategy openUrlStrategy) {
+ return new Mediator(
+ openUrlStrategy.isNewWindow()
+ ?
ExecutionResultHandlingStrategy.OPEN_URL_IN_NEW_BROWSER_WINDOW
+ :
ExecutionResultHandlingStrategy.OPEN_URL_IN_SAME_BROWSER_WINDOW,
+ null, null, ajaxTarget, url);
+ }
+
+ void handle() {
+ switch(handlingStrategy()) {
+ case REDIRECT_TO_PAGE->{
+ // force any changes in state etc to happen now prior to the
redirect;
+ // in the case of an object being returned, this should cause
our page mementos
+ // (eg EntityModel) to hold the correct state. I hope.
+
MetaModelContext.instance().ifPresent(mmc->mmc.getTransactionService().flushTransaction());
+ // "redirect-after-post"
+ this.pageRedirect().apply();
+ }
+ case OPEN_URL_IN_NEW_BROWSER_WINDOW -> {
+ final String fullUrl = expanded(RequestCycle.get(), url());
+ scheduleJs(ajaxTarget(), javascriptFor_newWindow(fullUrl),
100);
+ }
+ case OPEN_URL_IN_SAME_BROWSER_WINDOW -> {
+ final String fullUrl = expanded(RequestCycle.get(), url());
+ scheduleJs(ajaxTarget(), javascriptFor_sameWindow(fullUrl),
100);
+ }
+ case SCHEDULE_HANDLER -> {
+ var requestCycle = RequestCycle.get();
+ var ajaxTarget =
requestCycle.find(AjaxRequestTarget.class).orElse(null);
+
+ if (ajaxTarget == null) {
+ // non-Ajax request => just stream the Lob to the browser
+ // or if this is a no-arg action, there also will be no
parent for the component
+ requestCycle.scheduleRequestHandlerAfterCurrent(handler());
+ } else {
+ // otherwise,
+ // Ajax request => respond with a redirect to be able to
stream the Lob to the client
+ final IRequestHandler requestHandler = handler();
+ if(requestHandler instanceof ResourceStreamRequestHandler
scheduledHandler) {
+ var streamingBehavior = new
StreamAfterAjaxResponseBehavior(scheduledHandler);
+ var page = ajaxTarget.getPage();
+ page.add(streamingBehavior);
+ CharSequence callbackUrl =
streamingBehavior.getCallbackUrl();
+ scheduleJs(ajaxTarget,
javascriptFor_sameWindow(callbackUrl), 10);
+ } else if(requestHandler instanceof
RedirectRequestHandlerWithOpenUrlStrategy redirectHandler) {
+
+ final String url = redirectHandler.getRedirectUrl();
+ final String fullUrl = expanded(requestCycle, url);
+
+ if(redirectHandler.getOpenUrlStrategy().isNewWindow())
{
+ scheduleJs(ajaxTarget,
javascriptFor_newWindow(fullUrl), 100);
+ } else {
+ scheduleJs(ajaxTarget,
javascriptFor_sameWindow(fullUrl), 100);
+ }
+ } else {
+ throw _Exceptions.unrecoverable(
+ "no logic implemented to handle
IRequestHandler of type %s",
+ requestHandler.getClass().getName());
+ }
+ }
+ }
+ }
+ }
+
+ // -- HELPER
+
+ /**
+ * @see #expanded(String)
+ */
+ private static String expanded(final RequestCycle requestCycle, final
String url) {
+ String urlStr = expanded(url);
+ return requestCycle.getUrlRenderer().renderFullUrl(Url.parse(urlStr));
+ }
+
+ /**
+ * very simple template support, the idea being that
"antiCache=${currentTimeMillis}"
+ * will be replaced automatically.
+ */
+ private static String expanded(String urlStr) {
+ if(urlStr.contains("antiCache=${currentTimeMillis}")) {
+ urlStr = urlStr.replace("antiCache=${currentTimeMillis}",
"antiCache="+System.currentTimeMillis());
+ }
+ return urlStr;
+ }
+
+ private static String javascriptFor_newWindow(final CharSequence url) {
+ return
"function(){Wicket.Event.publish(Causeway.Topic.OPEN_IN_NEW_TAB, '" + url +
"');}";
+ }
+
+ private static String javascriptFor_sameWindow(final CharSequence url) {
+ return "\"window.location.href='" + url + "'\"";
+ }
+
+ private static void scheduleJs(final AjaxRequestTarget target, final
String js, final int millis) {
+ // the timeout is needed to let Wicket release the channel
+ target.appendJavaScript(String.format("setTimeout(%s, %d);", js,
millis));
+ }
+
+ /**
+ * A special Ajax behavior that is used to stream the contents of a Lob
after
+ * an Ajax request.
+ */
+ private static class StreamAfterAjaxResponseBehavior extends
AbstractAjaxBehavior {
+ private static final long serialVersionUID = 1L;
+
+ private final String fileName;
+ private final IResourceStream resourceStream;
+ private final Duration cacheDuration;
+
+ public StreamAfterAjaxResponseBehavior(final
ResourceStreamRequestHandler scheduledHandler) {
+ this.fileName = scheduledHandler.getFileName();
+ this.resourceStream = scheduledHandler.getResourceStream();
+ this.cacheDuration = scheduledHandler.getCacheDuration();
+ }
+
+ @Override public void onRequest() {
+ var handler = new ResourceStreamRequestHandler(resourceStream,
fileName);
+ handler.setCacheDuration(cacheDuration);
+ handler.setContentDisposition(ContentDisposition.ATTACHMENT);
+ var page = getComponent();
+ page.getRequestCycle().scheduleRequestHandlerAfterCurrent(handler);
+ page.remove(this);
+ }
+ }
+
+}
diff --git
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/_ResponseUtil.java
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/MediatorFactory.java
similarity index 72%
rename from
viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/_ResponseUtil.java
rename to
viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/MediatorFactory.java
index 6d712192737..f04c241e95a 100644
---
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/_ResponseUtil.java
+++
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/MediatorFactory.java
@@ -24,7 +24,7 @@
import org.apache.wicket.request.IRequestHandler;
import org.apache.wicket.request.cycle.PageRequestHandlerTracker;
import org.apache.wicket.request.cycle.RequestCycle;
-
+import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.apache.causeway.applib.value.LocalResourcePath;
@@ -33,28 +33,30 @@
import org.apache.causeway.commons.internal.base._Casts;
import org.apache.causeway.commons.internal.base._NullSafe;
import org.apache.causeway.commons.internal.exceptions._Exceptions;
+import org.apache.causeway.core.config.viewer.web.WebAppContextPath;
import org.apache.causeway.core.metamodel.context.MetaModelContext;
import org.apache.causeway.core.metamodel.object.ManagedObject;
import org.apache.causeway.core.metamodel.object.PackedManagedObject;
import org.apache.causeway.viewer.wicket.model.models.ActionModel;
import org.apache.causeway.viewer.wicket.model.models.ActionResultModel;
import
org.apache.causeway.viewer.wicket.model.models.FormExecutor.ActionResultResponseType;
-import
org.apache.causeway.viewer.wicket.model.models.coll.CollectionModelStandalone;
import org.apache.causeway.viewer.wicket.model.models.PageType;
+import
org.apache.causeway.viewer.wicket.model.models.RedirectRequestHandlerWithOpenUrlStrategy;
import org.apache.causeway.viewer.wicket.model.models.ValueModel;
import org.apache.causeway.viewer.wicket.model.models.VoidModel;
+import
org.apache.causeway.viewer.wicket.model.models.coll.CollectionModelStandalone;
+import
org.apache.causeway.viewer.wicket.ui.actionresponse.Mediator.ExecutionResultHandlingStrategy;
import org.apache.causeway.viewer.wicket.ui.pages.PageClassRegistry;
import
org.apache.causeway.viewer.wicket.ui.pages.standalonecollection.StandaloneCollectionPage;
import org.apache.causeway.viewer.wicket.ui.pages.value.ValuePage;
import org.apache.causeway.viewer.wicket.ui.pages.voidreturn.VoidReturnPage;
-import org.jspecify.annotations.NonNull;
import lombok.experimental.UtilityClass;
@UtilityClass
-class _ResponseUtil {
+class MediatorFactory {
- ActionResultResponse determineAndInterpretResult(
+ Mediator determineAndInterpretResult(
final @NonNull ActionModel actionModel,
final @Nullable AjaxRequestTarget ajaxTarget,
final @Nullable ManagedObject resultAdapterIfAny) {
@@ -68,12 +70,12 @@ ActionResultResponse determineAndInterpretResult(
// identity op
case NONE -> response;
// force full page reload
- case FORCE_STAY_ON_PAGE -> new ActionResultResponse(
-
ActionResultResponseHandlingStrategy.OPEN_URL_IN_SAME_BROWSER_WINDOW,
+ case FORCE_STAY_ON_PAGE -> new Mediator(
+
ExecutionResultHandlingStrategy.OPEN_URL_IN_SAME_BROWSER_WINDOW,
null, null, ajaxTarget, response.pageRedirect().toUrl());
// page redirect should point to current page
// open result page in new browser tab/win
- case FORCE_NEW_BROWSER_WINDOW -> new ActionResultResponse(
-
ActionResultResponseHandlingStrategy.OPEN_URL_IN_NEW_BROWSER_WINDOW,
+ case FORCE_NEW_BROWSER_WINDOW -> new Mediator(
+
ExecutionResultHandlingStrategy.OPEN_URL_IN_NEW_BROWSER_WINDOW,
null, null, ajaxTarget, response.pageRedirect().toUrl());
// page redirect should point to action result
}
: response;
@@ -81,7 +83,25 @@ ActionResultResponse determineAndInterpretResult(
// -- HELPER
- private ActionResultResponse actionResultResponse(
+ private IRequestHandler redirectHandler(
+ final Object value,
+ final @NonNull OpenUrlStrategy openUrlStrategy,
+ final @NonNull WebAppContextPath webAppContextPath) {
+
+ if(value instanceof java.net.URL) {
+ var url = (java.net.URL) value;
+ return new
RedirectRequestHandlerWithOpenUrlStrategy(url.toString());
+ }
+ if(value instanceof LocalResourcePath) {
+ var localResourcePath = (LocalResourcePath) value;
+ return new RedirectRequestHandlerWithOpenUrlStrategy(
+
localResourcePath.getEffectivePath(webAppContextPath::prependContextPath),
+ localResourcePath.openUrlStrategy());
+ }
+ return null;
+ }
+
+ private Mediator actionResultResponse(
final @NonNull ActionModel actionModel,
final @Nullable AjaxRequestTarget ajaxTarget,
final @NonNull ActionResultModel actionResultModel) {
@@ -96,73 +116,73 @@ private ActionResultResponse actionResultResponse(
.forActionModel((PackedManagedObject)resultAdapter,
actionModel);
var pageRedirectRequest = PageRedirectRequest.forPage(
StandaloneCollectionPage.class, new
StandaloneCollectionPage(collectionModel));
- return ActionResultResponse.toPage(pageRedirectRequest);
+ return Mediator.toPage(pageRedirectRequest);
}
case OBJECT: {
determineScalarAdapter(actionModel.getMetaModelContext(),
resultAdapter); // intercepts collections
- return ActionResultResponse.toDomainObjectPage(resultAdapter);
+ return Mediator.toDomainObjectPage(resultAdapter);
}
case SIGN_IN: {
var signInPage = actionModel.getMetaModelContext()
.lookupServiceElseFail(PageClassRegistry.class)
.getPageClass(PageType.SIGN_IN);
var pageRedirectRequest =
PageRedirectRequest.forPageClass(signInPage);
- return ActionResultResponse.toPage(pageRedirectRequest);
+ return Mediator.toPage(pageRedirectRequest);
}
case VALUE: {
var valueModel = ValueModel.of(actionModel.getAction(),
resultAdapter);
valueModel.setActionHint(actionModel);
var valuePage = new ValuePage(valueModel);
var pageRedirectRequest =
PageRedirectRequest.forPage(ValuePage.class, valuePage);
- return ActionResultResponse.toPage(pageRedirectRequest);
+ return Mediator.toPage(pageRedirectRequest);
}
case VALUE_BLOB: {
final Object value = resultAdapter.getPojo();
IRequestHandler handler =
- _DownloadHandler.downloadHandler(actionModel.getAction(),
value);
- return ActionResultResponse.withHandler(handler);
+
DownloadHandlerFactory.downloadHandler(actionModel.getAction(), value);
+ return Mediator.withHandler(handler);
}
case VALUE_CLOB: {
final Object value = resultAdapter.getPojo();
IRequestHandler handler =
- _DownloadHandler.downloadHandler(actionModel.getAction(),
value);
- return ActionResultResponse.withHandler(handler);
+
DownloadHandlerFactory.downloadHandler(actionModel.getAction(), value);
+ return Mediator.withHandler(handler);
}
case VALUE_LOCALRESPATH_AJAX: {
final LocalResourcePath localResPath =
(LocalResourcePath)resultAdapter.getPojo();
var webAppContextPath =
actionModel.getMetaModelContext().getWebAppContextPath();
- return ActionResultResponse
+ return Mediator
.openUrlInBrowser(ajaxTarget,
localResPath.getEffectivePath(webAppContextPath::prependContextPath),
localResPath.openUrlStrategy());
}
case VALUE_LOCALRESPATH_NOAJAX: {
// open URL server-side redirect
final LocalResourcePath localResPath =
(LocalResourcePath)resultAdapter.getPojo();
var webAppContextPath =
actionModel.getMetaModelContext().getWebAppContextPath();
- IRequestHandler handler =
_RedirectHandler.redirectHandler(localResPath, localResPath.openUrlStrategy(),
webAppContextPath);
- return ActionResultResponse.withHandler(handler);
+ IRequestHandler handler = redirectHandler(localResPath,
localResPath.openUrlStrategy(), webAppContextPath);
+ return Mediator.withHandler(handler);
}
case VALUE_URL_AJAX: {
final URL url = (URL)resultAdapter.getPojo();
- return ActionResultResponse
+ return Mediator
.openUrlInBrowser(ajaxTarget, url.toString(),
OpenUrlStrategy.NEW_WINDOW); // default behavior
}
case VALUE_URL_NOAJAX: {
// open URL server-side redirect
final Object value = resultAdapter.getPojo();
var webAppContextPath =
actionModel.getMetaModelContext().getWebAppContextPath();
- IRequestHandler handler = _RedirectHandler.redirectHandler(value,
OpenUrlStrategy.NEW_WINDOW, webAppContextPath); // default behavior
- return ActionResultResponse.withHandler(handler);
+ IRequestHandler handler = redirectHandler(value,
OpenUrlStrategy.NEW_WINDOW, webAppContextPath); // default behavior
+ return Mediator.withHandler(handler);
}
case VOID_AS_EMPTY: {
var pageRedirectRequest = PageRedirectRequest
.forPage(VoidReturnPage.class, new VoidReturnPage(new
VoidModel(), actionModel.getFriendlyName()));
- return ActionResultResponse.toPage(pageRedirectRequest);
+ return Mediator.toPage(pageRedirectRequest);
}
case RELOAD: {
var currentPage =
PageRequestHandlerTracker.getLastHandler(RequestCycle.get()).getPage();
var pageClass = currentPage.getClass();
var pageRedirectRequest = PageRedirectRequest.forPage(pageClass,
_Casts.uncheckedCast(currentPage));
- return ActionResultResponse.toPage(pageRedirectRequest);
+ return Mediator.toPage(pageRedirectRequest);
}
default:
throw _Exceptions.unmatchedCase(responseType);
@@ -173,18 +193,17 @@ private ManagedObject determineScalarAdapter(
final @NonNull MetaModelContext mmc,
final @NonNull ManagedObject resultAdapter) {
- if (resultAdapter.getSpecification().isSingular()) {
- return resultAdapter;
- } else {
- // will only be a single element
- final Object pojo = _NullSafe
- .streamAutodetect(resultAdapter.getPojo())
- .findFirst()
- .orElseThrow(_Exceptions::noSuchElement);
-
- final var scalarAdapter = mmc.getObjectManager().adapt(pojo);
- return scalarAdapter;
- }
+ if (resultAdapter.getSpecification().isSingular()) return
resultAdapter;
+
+ // will only be a single element
+ final Object pojo = _NullSafe
+ .streamAutodetect(resultAdapter.getPojo())
+ .findFirst()
+ .orElseThrow(_Exceptions::noSuchElement);
+
+ final var scalarAdapter = mmc.getObjectManager().adapt(pojo);
+ return scalarAdapter;
+
}
}
diff --git
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/PageRedirectRequest.java
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/PageRedirectRequest.java
index 5c38f6b51c4..c27c54e078a 100644
---
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/PageRedirectRequest.java
+++
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/PageRedirectRequest.java
@@ -23,26 +23,24 @@
import org.apache.wicket.request.component.IRequestablePage;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.request.mapper.parameter.PageParameters;
-
+import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.apache.causeway.applib.services.bookmark.Bookmark;
import org.apache.causeway.viewer.wicket.model.util.PageParameterUtils;
-import org.jspecify.annotations.NonNull;
-
-public record PageRedirectRequest<T extends IRequestablePage>(
+record PageRedirectRequest<T extends IRequestablePage>(
@NonNull Class<T> pageClass,
@Nullable PageParameters pageParameters,
@Nullable IRequestablePage pageInstance) {
- public static <T extends IRequestablePage> PageRedirectRequest<T>
forPageClass(
+ static <T extends IRequestablePage> PageRedirectRequest<T> forPageClass(
final @NonNull Class<T> pageClass,
final @NonNull PageParameters pageParameters) {
return new PageRedirectRequest<>(pageClass, pageParameters, null);
}
- public static <T extends IRequestablePage> PageRedirectRequest
forPageClassAndBookmark(
+ static <T extends IRequestablePage> PageRedirectRequest<T>
forPageClassAndBookmark(
final @NonNull Class<T> pageClass,
final @NonNull Bookmark bookmark) {
return forPageClass(
@@ -50,25 +48,25 @@ public static <T extends IRequestablePage>
PageRedirectRequest forPageClassAndBo
PageParameterUtils.createPageParametersForBookmark(bookmark));
}
- public static <T extends IRequestablePage> PageRedirectRequest<T>
forPageClass(
+ static <T extends IRequestablePage> PageRedirectRequest<T> forPageClass(
final @NonNull Class<T> pageClass) {
return new PageRedirectRequest<>(pageClass, null, null);
}
- public static <T extends IRequestablePage> PageRedirectRequest<T> forPage(
+ static <T extends IRequestablePage> PageRedirectRequest<T> forPage(
final @NonNull Class<T> pageClass,
final @NonNull T pageInstance) {
return new PageRedirectRequest<>(pageClass, null, pageInstance);
}
- public String toUrl() {
+ String toUrl() {
var handler = new BookmarkablePageRequestHandler(
new PageProvider(pageClass, pageParameters));
return RequestCycle.get().urlFor(handler)
.toString();
}
- public void apply() {
+ void apply() {
var requestCycle = RequestCycle.get();
if(requestCycle==null) return;
if(pageParameters!=null) {
diff --git
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/_RedirectHandler.java
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/_RedirectHandler.java
deleted file mode 100644
index 9bb04f3d1d6..00000000000
---
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/actionresponse/_RedirectHandler.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.ui.actionresponse;
-
-import org.apache.wicket.request.IRequestHandler;
-
-import org.apache.causeway.applib.value.LocalResourcePath;
-import org.apache.causeway.applib.value.OpenUrlStrategy;
-import org.apache.causeway.core.config.viewer.web.WebAppContextPath;
-import
org.apache.causeway.viewer.wicket.model.models.RedirectRequestHandlerWithOpenUrlStrategy;
-
-import org.jspecify.annotations.NonNull;
-import lombok.experimental.UtilityClass;
-
-@UtilityClass
-final class _RedirectHandler {
-
- public IRequestHandler redirectHandler(
- final Object value,
- final @NonNull OpenUrlStrategy openUrlStrategy,
- final @NonNull WebAppContextPath webAppContextPath) {
-
- if(value instanceof java.net.URL) {
- var url = (java.net.URL) value;
- return new
RedirectRequestHandlerWithOpenUrlStrategy(url.toString());
- }
- if(value instanceof LocalResourcePath) {
- var localResourcePath = (LocalResourcePath) value;
- return new RedirectRequestHandlerWithOpenUrlStrategy(
-
localResourcePath.getEffectivePath(webAppContextPath::prependContextPath),
- localResourcePath.openUrlStrategy());
- }
- return null;
- }
-}
diff --git
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/panels/FormExecutorDefault.java
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/panels/FormExecutorDefault.java
index 93a3c7ecbde..202c5287722 100644
---
a/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/panels/FormExecutorDefault.java
+++
b/viewers/wicket/ui/src/main/java/org/apache/causeway/viewer/wicket/ui/panels/FormExecutorDefault.java
@@ -22,7 +22,7 @@
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.form.Form;
-
+import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.apache.causeway.applib.services.exceprecog.Category;
@@ -34,9 +34,8 @@
import org.apache.causeway.viewer.wicket.model.models.FormExecutorContext;
import org.apache.causeway.viewer.wicket.model.models.HasCommonContext;
import org.apache.causeway.viewer.wicket.model.models.PropertyModel;
-import
org.apache.causeway.viewer.wicket.ui.actionresponse.ActionResultResponse;
+import
org.apache.causeway.viewer.wicket.ui.actionresponse.ExecutionResultHandler;
-import org.jspecify.annotations.NonNull;
import lombok.extern.log4j.Log4j2;
@Log4j2
@@ -110,18 +109,8 @@ public FormExecutionOutcome executeAndProcessResults(
return
FormExecutionOutcome.SUCCESS_IN_NESTED_CONTEXT_SO_STAY_ON_PAGE;
}
- //XXX triggers ManagedObject.getBookmarkRefreshed()
- var resultResponse = actionOrPropertyModel.fold(
- act->ActionResultResponse
- .determineAndInterpretResult(act, ajaxTarget,
resultAdapter),
- prop->ActionResultResponse
- .toDomainObjectPage(resultAdapter));
-
- // redirect using associated strategy
- // XXX note: on property edit, triggers SQL update (on JPA)
- resultResponse
- .handlingStrategy()
- .handleResults(resultResponse);
+ new ExecutionResultHandler(actionOrPropertyModel)
+ .handle(ajaxTarget, resultAdapter);
return FormExecutionOutcome.SUCCESS_AND_REDIRECED_TO_RESULT_PAGE;
// success (valid args), allow redirect