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

pgil pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git


The following commit(s) were added to refs/heads/trunk by this push:
     new b4e46ff  Implemented : New child element set-callback on link to 
control dynamism (OFBIZ-11812)
b4e46ff is described below

commit b4e46ff0703b640c93f2e69a5e78b473a8be34c3
Author: Gil Portenseigne <p...@apache.org>
AuthorDate: Thu Jun 24 16:13:00 2021 +0200

    Implemented : New child element set-callback on link to control dynamism 
(OFBIZ-11812)
    
    Refreshment information are controlled by the calling object,
    instead of the called form.
    
    This avoid dependency between called form and parent screens.
    
    The set-callback tag generate a jwt encoded UpdateArea widget, that
    is transmitted through submits and links until a submit with no
    update-area information is met.  This specific submit ends the
    process launched by the link, and trigger the refresh action
    contained into the JWT token.
---
 framework/widget/dtd/widget-common.xsd             | 21 ++++++
 .../ofbiz/widget/model/CommonWidgetModels.java     | 57 +++++++++++---
 .../org/apache/ofbiz/widget/model/ModelForm.java   | 86 ++++++++++++++++++++++
 .../apache/ofbiz/widget/model/ModelMenuItem.java   | 10 +++
 .../ofbiz/widget/model/ModelScreenWidget.java      |  4 +
 .../widget/renderer/html/HtmlMenuRenderer.java     |  9 ++-
 .../widget/renderer/macro/MacroCommonRenderer.java | 22 ++++--
 .../widget/renderer/macro/MacroFormRenderer.java   |  9 ++-
 .../widget/renderer/macro/MacroMenuRenderer.java   | 14 ++--
 .../widget/renderer/macro/MacroScreenRenderer.java | 11 ++-
 10 files changed, 205 insertions(+), 38 deletions(-)

diff --git a/framework/widget/dtd/widget-common.xsd 
b/framework/widget/dtd/widget-common.xsd
index 7b18e40..4445fe6 100644
--- a/framework/widget/dtd/widget-common.xsd
+++ b/framework/widget/dtd/widget-common.xsd
@@ -526,6 +526,7 @@ under the License.
             <xs:element minOccurs="0" ref="auto-parameters-entity"/>
             <xs:element minOccurs="0" maxOccurs="unbounded" ref="parameter" />
             <xs:element minOccurs="0" name="image" type="image" />
+            <xs:element minOccurs="0" ref="set-callback"/>
         </xs:sequence>
         <xs:attribute type="xs:string" name="text" />
         <xs:attribute type="xs:string" name="id">
@@ -613,4 +614,24 @@ under the License.
             </xs:simpleType>
         </xs:attribute>
     </xs:complexType>
+    <xs:element name="set-callback">
+        <xs:annotation>
+            <xs:documentation>When actions behind a link are terminated, 
follow the given information
+                to update a screen</xs:documentation>
+        </xs:annotation>
+        <xs:complexType>
+            <xs:sequence>
+                <xs:element minOccurs="0" ref="auto-parameters-service"/>
+                <xs:element minOccurs="0" ref="auto-parameters-entity"/>
+                <xs:element minOccurs="0" maxOccurs="unbounded" 
ref="parameter"/>
+            </xs:sequence>
+            <xs:attribute name="area-id" type="xs:string">
+                <xs:annotation>
+                    <xs:documentation>Identification of the area to update. If 
empty, by default the screen engine
+                        auto resolve it on the first parent referent screen 
present in the widget hierarchy</xs:documentation>
+                </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="area-target" type="xs:string" use="required" />
+        </xs:complexType>
+    </xs:element>
 </xs:schema>
diff --git 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/CommonWidgetModels.java
 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/CommonWidgetModels.java
index 042f50d..87661e5 100644
--- 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/CommonWidgetModels.java
+++ 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/CommonWidgetModels.java
@@ -32,6 +32,7 @@ import java.util.TimeZone;
 import org.apache.ofbiz.base.util.Debug;
 import org.apache.ofbiz.base.util.UtilCodec;
 import org.apache.ofbiz.base.util.UtilDateTime;
+import org.apache.ofbiz.base.util.UtilGenerics;
 import org.apache.ofbiz.base.util.UtilValidate;
 import org.apache.ofbiz.base.util.UtilXml;
 import org.apache.ofbiz.base.util.collections.FlexibleMapAccessor;
@@ -53,6 +54,7 @@ import org.w3c.dom.Element;
 public final class CommonWidgetModels {
 
     private static final String MODULE = CommonWidgetModels.class.getName();
+    public static final String JWT_CALLBACK = "JWT_CALLBACK";
 
     private CommonWidgetModels() {
     }
@@ -345,6 +347,7 @@ public final class CommonWidgetModels {
         // FIXME: These don't belong in this class (might have been used for 
image)
         private final String height;
         private final String width;
+        private final ModelForm.UpdateArea callback;
 
         public Link(Element linkElement) {
             this.textExdr = 
FlexibleStringExpander.getInstance(linkElement.getAttribute("text"));
@@ -408,12 +411,18 @@ public final class CommonWidgetModels {
             this.confirmationMsgExdr = 
FlexibleStringExpander.getInstance(linkElement.getAttribute("confirmation-message"));
             this.width = linkElement.getAttribute("width");
             this.height = linkElement.getAttribute("height");
+
+            Element updateAreaElement = UtilXml.firstChildElement(linkElement, 
"set-callback");
+            this.callback = updateAreaElement != null
+                    ? new ModelForm.UpdateArea(updateAreaElement)
+                    : null;
         }
 
         // Portal constructor
         public Link(GenericValue portalPage, List<Parameter> parameterList, 
String target, Locale locale) {
             this.autoEntityParameters = null;
             this.autoServiceParameters = null;
+            this.callback = null;
             this.encode = false;
             this.fullPath = false;
             this.idExdr = FlexibleStringExpander.getInstance("");
@@ -443,6 +452,10 @@ public final class CommonWidgetModels {
             return autoServiceParameters;
         }
 
+        public ModelForm.UpdateArea getCallback() {
+            return callback;
+        }
+
         public String getConfirmationMsg(Map<String, Object> context) {
             return this.confirmationMsgExdr.expandString(context);
         }
@@ -495,7 +508,16 @@ public final class CommonWidgetModels {
             return parameterList;
         }
 
-        public Map<String, String> getParameterMap(Map<String, Object> 
context, String defaultEntityName, String defaultServiceName) {
+        public Map<String, String> getParameterMap(Map<String, Object> context,
+                                                   String defaultEntityName,
+                                                   String defaultServiceName) {
+            return getParameterMap(context, defaultEntityName, 
defaultServiceName, true);
+        }
+
+        public Map<String, String> getParameterMap(Map<String, Object> context,
+                                                   String defaultEntityName,
+                                                   String defaultServiceName,
+                                                   boolean 
propagateMyCallback) {
             Map<String, String> fullParameterMap = new HashMap<>();
             for (Parameter parameter : this.parameterList) {
                 fullParameterMap.put(parameter.getName(), 
parameter.getValue(context));
@@ -506,21 +528,32 @@ public final class CommonWidgetModels {
             if (autoEntityParameters != null) {
                 
fullParameterMap.putAll(autoEntityParameters.getParametersMap(context, 
defaultEntityName));
             }
+            propagateCallbackInParameterMap(context, propagateMyCallback, 
fullParameterMap);
             return fullParameterMap;
         }
 
-        public Map<String, String> getParameterMap(Map<String, Object> 
context) {
-            Map<String, String> fullParameterMap = new HashMap<>();
-            for (Parameter parameter : this.parameterList) {
-                fullParameterMap.put(parameter.getName(), 
parameter.getValue(context));
-            }
-            if (autoServiceParameters != null) {
-                
fullParameterMap.putAll(autoServiceParameters.getParametersMap(context, null));
-            }
-            if (autoEntityParameters != null) {
-                
fullParameterMap.putAll(autoEntityParameters.getParametersMap(context, null));
+        // If a call back is present on link or present on context, adding it 
to the parameters list
+        private void propagateCallbackInParameterMap(Map<String, Object> 
context, boolean propagateMyCallback, Map<String, String> fullParameterMap) {
+            if (getCallback() != null && propagateMyCallback) {
+                fullParameterMap.put(JWT_CALLBACK, 
getCallback().toJwtToken(context));
+            } else if (context.containsKey(JWT_CALLBACK)) {
+                fullParameterMap.put(JWT_CALLBACK, (String) 
context.get(JWT_CALLBACK));
+            } else {
+                if (context.containsKey("parameters")) {
+                    Map<String, Object> parameters = 
UtilGenerics.cast(context.get("parameters"));
+                    if (parameters.containsKey(JWT_CALLBACK)) {
+                        fullParameterMap.put(JWT_CALLBACK, (String) 
parameters.get(JWT_CALLBACK));
+                    }
+                }
             }
-            return fullParameterMap;
+        }
+
+        public Map<String, String> getParameterMap(Map<String, Object> 
context) {
+            return getParameterMap(context, null, null, true);
+        }
+
+        public Map<String, String> getParameterMap(Map<String, Object> 
context, boolean propagateMyCallback) {
+            return getParameterMap(context, null, null, propagateMyCallback);
         }
 
         public String getPrefix(Map<String, Object> context) {
diff --git 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelForm.java 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelForm.java
index 1869d2b..75b20cc 100644
--- 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelForm.java
+++ 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelForm.java
@@ -31,6 +31,10 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import java.util.stream.Collectors;
+import org.apache.ofbiz.base.conversion.ConversionException;
+import org.apache.ofbiz.base.conversion.JSONConverters;
+import org.apache.ofbiz.base.lang.JSON;
 import org.apache.ofbiz.base.util.Debug;
 import org.apache.ofbiz.base.util.GroovyUtil;
 import org.apache.ofbiz.base.util.StringUtil;
@@ -42,6 +46,7 @@ import org.apache.ofbiz.base.util.UtilValidate;
 import org.apache.ofbiz.base.util.UtilXml;
 import org.apache.ofbiz.base.util.collections.FlexibleMapAccessor;
 import org.apache.ofbiz.base.util.string.FlexibleStringExpander;
+import org.apache.ofbiz.entity.Delegator;
 import org.apache.ofbiz.entity.GenericEntityException;
 import org.apache.ofbiz.entity.model.ModelEntity;
 import org.apache.ofbiz.entity.model.ModelField;
@@ -50,6 +55,7 @@ import org.apache.ofbiz.service.DispatchContext;
 import org.apache.ofbiz.service.GenericServiceException;
 import org.apache.ofbiz.service.ModelParam;
 import org.apache.ofbiz.service.ModelService;
+import org.apache.ofbiz.webapp.control.JWTManager;
 import org.apache.ofbiz.widget.WidgetWorker;
 import org.apache.ofbiz.widget.renderer.FormStringRenderer;
 import org.apache.ofbiz.widget.renderer.VisualTheme;
@@ -2342,6 +2348,23 @@ public abstract class ModelForm extends ModelWidget {
             this.autoEntityParameters = null;
         }
 
+        /** String constructor.
+         * @param areaId The id of the widget element to be updated
+         * @param areaTarget The target URL called to update the area
+         * @param parameterList The list of parameters
+         */
+        public UpdateArea(String eventType, String areaId, String areaTarget,
+                          List<CommonWidgetModels.Parameter> parameterList) {
+            this.eventType = eventType;
+            this.areaId = areaId;
+            this.areaTarget = areaTarget;
+            this.defaultServiceName = null;
+            this.defaultEntityName = null;
+            this.parameterList = parameterList;
+            this.autoServiceParameters = null;
+            this.autoEntityParameters = null;
+        }
+
         @Override
         public boolean equals(Object obj) {
             return obj instanceof UpdateArea && obj.hashCode() == 
this.hashCode();
@@ -2444,5 +2467,68 @@ public abstract class ModelForm extends ModelWidget {
         public List<CommonWidgetModels.Parameter> getParameterList() {
             return parameterList;
         }
+
+        /**
+         * Extract updateArea information as a Jwt token
+         * @return the Jwt token
+         */
+        public String toJwtToken(Map<String, Object> context) {
+            Delegator delegator = (Delegator) context.get("delegator");
+
+            Map<String, String> claims = UtilMisc.toMap(
+                    "areaId", 
WidgetWorker.getScreenStack(context).resolveScreenAreaId(getAreaId()),
+                    "areaTarget", getAreaTarget());
+
+            JSONConverters.MapToJSON converter = new 
JSONConverters.MapToJSON();
+            Map<String, Object> parameters = 
UtilGenerics.cast(getParameterMap(context));
+            try {
+                claims.put("parameters", 
converter.convert(parameters).toString());
+            } catch (ConversionException e) {
+                Debug.logWarning("Failed to convert parameters to JSON with " 
+ parameters, MODULE);
+            }
+            return JWTManager.createJwt(delegator, claims, -1);
+        }
+
+        /**
+         * Retrieva Jwt from context, validate it and generate UpdateArea 
Object
+         * @return UpdateArea object
+         */
+        public static ModelForm.UpdateArea fromJwtToken(Map<String, Object> 
context) {
+            Delegator delegator = (Delegator) context.get("delegator");
+
+            String jwtToken = (String) 
context.get(CommonWidgetModels.JWT_CALLBACK);
+            if (jwtToken == null && context.containsKey("parameters")) {
+                Map<String, Object> parameters = 
UtilGenerics.cast(context.get("parameters"));
+                jwtToken = (String) 
parameters.get(CommonWidgetModels.JWT_CALLBACK);
+            }
+            if (jwtToken == null) return null;
+
+            Map<String, Object> claims = JWTManager.validateToken(jwtToken, 
JWTManager.getJWTKey(delegator));
+            if (claims.containsKey(ModelService.ERROR_MESSAGE)) {
+                // Something unexpected happened here
+                Debug.logWarning("There was a problem with the JWT token, 
signature not valid.", MODULE);
+                return null;
+            }
+
+            String areaId = (String) claims.remove("areaId");
+            String areaTarget = (String) claims.remove("areaTarget");
+
+            Map<String, Object> parameters = null;
+            if (claims.containsKey("parameters")) {
+                JSONConverters.JSONToMap converter = new 
JSONConverters.JSONToMap();
+                try {
+                    parameters = converter.convert(JSON.from((String) 
claims.get("parameters")));
+                } catch (ConversionException e) {
+                    Debug.logWarning("Failed to convert JSON to with " + 
claims.get("parameters"), MODULE);
+                }
+            }
+            return new UpdateArea("", areaId, areaTarget,
+                    parameters != null
+                            ? parameters.entrySet()
+                            .stream()
+                            .map(entry -> new 
CommonWidgetModels.Parameter(entry.getKey(), (String) entry.getValue(), true))
+                            .collect(Collectors.toList())
+                            : new ArrayList<>());
+        }
     }
 }
diff --git 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelMenuItem.java
 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelMenuItem.java
index c0f8d04..5898bcb 100644
--- 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelMenuItem.java
+++ 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelMenuItem.java
@@ -791,6 +791,16 @@ public class ModelMenuItem extends ModelWidget {
         }
 
         /**
+         * Gets parameter map.
+         * @param context the context
+         * @param propagateCallback indicate if we need to propagate callback 
element
+         * @return the parameter map
+         */
+        public Map<String, String> getParameterMap(Map<String, Object> 
context, boolean propagateCallback) {
+            return link.getParameterMap(context, propagateCallback);
+        }
+
+        /**
          * Gets prefix.
          * @param context the context
          * @return the prefix
diff --git 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelScreenWidget.java
 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelScreenWidget.java
index 83b9028..17ce2fe 100644
--- 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelScreenWidget.java
+++ 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/model/ModelScreenWidget.java
@@ -1754,6 +1754,10 @@ public abstract class ModelScreenWidget extends 
ModelWidget {
             return link.getParameterMap(context);
         }
 
+        public Map<String, String> getParameterMap(Map<String, Object> 
context, boolean propagateCallback) {
+            return link.getParameterMap(context, propagateCallback);
+        }
+
         public FlexibleStringExpander getTextExdr() {
             return link.getTextExdr();
         }
diff --git 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/html/HtmlMenuRenderer.java
 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/html/HtmlMenuRenderer.java
index c8f5a6d..9b7046d 100644
--- 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/html/HtmlMenuRenderer.java
+++ 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/html/HtmlMenuRenderer.java
@@ -428,7 +428,8 @@ public class HtmlMenuRenderer extends HtmlWidgetRenderer 
implements MenuStringRe
                     + UtilMisc.<String>addToBigDecimalInMap(context, 
"menuUniqueItemIndex", BigDecimal.ONE);
 
             String linkType = 
WidgetWorker.determineAutoLinkType(link.getLinkType(), target, 
link.getUrlMode(), request);
-            if ("hidden-form".equals(linkType)) {
+            boolean isHiddenForm = "hidden-form".equals(linkType);
+            if (isHiddenForm) {
                 writer.append("<form method=\"post\"");
                 writer.append(" action=\"");
                 // note that this passes null for the parameterList on purpose 
so they won't be put into the URL
@@ -449,7 +450,7 @@ public class HtmlMenuRenderer extends HtmlWidgetRenderer 
implements MenuStringRe
                 writer.append("\">");
 
                 UtilCodec.SimpleEncoder simpleEncoder = 
(UtilCodec.SimpleEncoder) context.get("simpleEncoder");
-                for (Map.Entry<String, String> parameter: 
link.getParameterMap(context).entrySet()) {
+                for (Map.Entry<String, String> parameter: 
link.getParameterMap(context, false).entrySet()) {
                     writer.append("<input name=\"");
                     writer.append(parameter.getKey());
                     writer.append("\" value=\"");
@@ -484,7 +485,7 @@ public class HtmlMenuRenderer extends HtmlWidgetRenderer 
implements MenuStringRe
                 writer.append(name);
                 writer.append("\"");
             }
-            if (!"hidden-form".equals(linkType)) {
+            if (!isHiddenForm) {
                 if (UtilValidate.isNotEmpty(targetWindow)) {
                     writer.append(" target=\"");
                     writer.append(targetWindow);
@@ -493,7 +494,7 @@ public class HtmlMenuRenderer extends HtmlWidgetRenderer 
implements MenuStringRe
             }
 
             writer.append(" href=\"");
-            if ("hidden-form".equals(linkType)) {
+            if (isHiddenForm) {
                 writer.append("javascript:document.");
                 writer.append(uniqueItemName);
                 writer.append(".submit()");
diff --git 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroCommonRenderer.java
 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroCommonRenderer.java
index 997317f..b2bb62c 100644
--- 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroCommonRenderer.java
+++ 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroCommonRenderer.java
@@ -122,7 +122,7 @@ public class MacroCommonRenderer {
      * @return
      */
     public static String getLinkUrl(CommonWidgetModels.Link link, Map<String, 
Object> context) {
-        String linkUrl;
+        String linkUrl = "";
 
         HttpServletRequest request = (HttpServletRequest) 
context.get("request");
         HttpServletResponse response = (HttpServletResponse) 
context.get("response");
@@ -134,12 +134,22 @@ public class MacroCommonRenderer {
             linkUrl = 
createAjaxParamsFromUpdateAreas(UtilMisc.toList(resolveUpdateArea),
                     UtilGenerics.cast(link.getParameterMap(context)), null, 
null, context);
             break;
+        case "hidden-form":
+            if (link.getCallback() != null) {
+                // we assume that the post request
+                // wait an immediate response, so we execute the callback 
directly
+                linkUrl = 
createAjaxParamsFromUpdateAreas(UtilMisc.toList(link.getCallback()), null, 
null, null, context);
+            }
+            break;
         default:
-            final URI linkUri = 
WidgetWorker.buildHyperlinkUri(link.getTarget(context), link.getUrlMode(),
-                    "layered-modal".equals(link.getLinkType()) ? null : 
link.getParameterMap(context), link.getPrefix(context),
-                    link.getFullPath(), link.getSecure(), link.getEncode(),
-                    request, response);
-            linkUrl = linkUri.toString();
+            String target = link.getTarget(context);
+            if (UtilValidate.isNotEmpty(target)) {
+                final URI linkUri = WidgetWorker.buildHyperlinkUri(target, 
link.getUrlMode(),
+                        "layered-modal".equals(link.getLinkType()) ? null : 
link.getParameterMap(context), link.getPrefix(context),
+                        link.getFullPath(), link.getSecure(), link.getEncode(),
+                        request, response);
+                linkUrl = linkUri.toString();
+            }
         }
         return linkUrl;
     }
diff --git 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroFormRenderer.java
 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroFormRenderer.java
index c807021..9f33bee 100644
--- 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroFormRenderer.java
+++ 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroFormRenderer.java
@@ -1012,14 +1012,19 @@ public final class MacroFormRenderer implements 
FormStringRenderer {
         // This is here for backwards compatibility. Use on-event-update-area
         // elements instead.
         String backgroundSubmitRefreshTarget = 
submitField.getBackgroundSubmitRefreshTarget(context);
+        ModelForm.UpdateArea jwtCallback = 
ModelForm.UpdateArea.fromJwtToken(context);
         if (UtilValidate.isNotEmpty(backgroundSubmitRefreshTarget)) {
             if (updateAreas == null) {
                 updateAreas = new LinkedList<>();
             }
             updateAreas.add(new ModelForm.UpdateArea("submit", formId, 
backgroundSubmitRefreshTarget));
         }
-        boolean ajaxEnabled = (UtilValidate.isNotEmpty(updateAreas) || 
UtilValidate.isNotEmpty(backgroundSubmitRefreshTarget))
-                && this.javaScriptEnabled;
+
+        // In context a callback is present and no other update area to call 
after the submit, so trigger it.
+        if (UtilValidate.isEmpty(updateAreas) && jwtCallback != null) {
+            updateAreas = UtilMisc.toList(jwtCallback);
+        }
+        boolean ajaxEnabled = UtilValidate.isNotEmpty(updateAreas) && 
this.javaScriptEnabled;
         String ajaxUrl = "";
         if (ajaxEnabled) {
             ajaxUrl = 
MacroCommonRenderer.createAjaxParamsFromUpdateAreas(updateAreas, null, 
modelForm, "", context);
diff --git 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroMenuRenderer.java
 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroMenuRenderer.java
index 9613dae..418c9aa 100644
--- 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroMenuRenderer.java
+++ 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroMenuRenderer.java
@@ -234,18 +234,19 @@ public class MacroMenuRenderer implements 
MenuStringRenderer {
             linkType = WidgetWorker.determineAutoLinkType(link.getLinkType(), 
target, link.getUrlMode(), request);
         }
         parameters.put("linkType", linkType);
-        String linkUrl = "";
         String actionUrl = "";
-
         StringBuilder targetParameters = new StringBuilder();
-        if ("hidden-form".equals(linkType) || 
"layered-modal".equals(linkType)) {
+
+        boolean isModal = "layered-modal".equals(linkType);
+        if ("hidden-form".equals(linkType) || isModal) {
             final URI actionUri = WidgetWorker.buildHyperlinkUri(target, 
link.getUrlMode(), null,
                     link.getPrefix(context), link.getFullPath(), 
link.getSecure(), link.getEncode(),
                     request, response);
             actionUrl = actionUri.toString();
 
             targetParameters.append("[");
-            for (Map.Entry<String, String> parameter : 
link.getParameterMap(context).entrySet()) {
+            // Callback propagation only if displaying a modal
+            for (Map.Entry<String, String> parameter : 
link.getParameterMap(context, isModal).entrySet()) {
                 if (targetParameters.length() > 1) {
                     targetParameters.append(",");
                 }
@@ -262,10 +263,7 @@ public class MacroMenuRenderer implements 
MenuStringRenderer {
         if (targetParameters.length() == 0) {
             targetParameters.append("\"\"");
         }
-        if (UtilValidate.isNotEmpty(target) && 
!"hidden-form".equals(linkType)) {
-            linkUrl = MacroCommonRenderer.getLinkUrl(link.getLink(), context);
-        }
-        parameters.put("linkUrl", linkUrl);
+        parameters.put("linkUrl", 
MacroCommonRenderer.getLinkUrl(link.getLink(), context));
         parameters.put("actionUrl", actionUrl);
         parameters.put("parameterList", targetParameters);
         String imgStr = "";
diff --git 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroScreenRenderer.java
 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroScreenRenderer.java
index 5fdb210..f0f91b1 100644
--- 
a/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroScreenRenderer.java
+++ 
b/framework/widget/src/main/java/org/apache/ofbiz/widget/renderer/macro/MacroScreenRenderer.java
@@ -275,7 +275,6 @@ public class MacroScreenRenderer implements 
ScreenStringRenderer {
                 + UtilMisc.<String>addToBigDecimalInMap(context, 
"screenUniqueItemIndex", BigDecimal.ONE);
 
         String linkType = 
WidgetWorker.determineAutoLinkType(link.getLinkType(), target, 
link.getUrlMode(), request);
-        String linkUrl = "";
         String actionUrl = "";
         StringBuilder parameters = new StringBuilder();
         String width = link.getWidth();
@@ -286,13 +285,15 @@ public class MacroScreenRenderer implements 
ScreenStringRenderer {
         if (UtilValidate.isEmpty(height)) {
             height = 
String.valueOf(modelTheme.getLinkDefaultLayeredModalHeight());
         }
-        if ("hidden-form".equals(linkType) || 
"layered-modal".equals(linkType)) {
+        boolean isModal = "layered-modal".equals(linkType);
+        if ("hidden-form".equals(linkType) || isModal) {
             final URI actionUri = WidgetWorker.buildHyperlinkUri(target, 
link.getUrlMode(), null,
                     link.getPrefix(context), link.getFullPath(), 
link.getSecure(), link.getEncode(),
                     request, response);
             actionUrl = actionUri.toString();
             parameters.append("[");
-            for (Map.Entry<String, String> parameter: 
link.getParameterMap(context).entrySet()) {
+            // Callback propagation only if displaying a modal
+            for (Map.Entry<String, String> parameter: 
link.getParameterMap(context, isModal).entrySet()) {
                 if (parameters.length() > 1) {
                     parameters.append(",");
                 }
@@ -309,9 +310,7 @@ public class MacroScreenRenderer implements 
ScreenStringRenderer {
         String style = link.getStyle(context);
         String name = link.getName(context);
         String text = link.getText(context);
-        if (UtilValidate.isNotEmpty(target)) {
-            linkUrl = MacroCommonRenderer.getLinkUrl(link.getLink(), context);
-        }
+        String linkUrl = MacroCommonRenderer.getLinkUrl(link.getLink(), 
context);
         String imgStr = "";
         ModelScreenWidget.ScreenImage img = link.getImage();
         if (img != null) {

Reply via email to