You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by nm...@apache.org on 2022/07/15 13:59:58 UTC
[ofbiz-framework] branch trunk updated: Implemented: Define return user message from controller (OFBIZ-12652)
This is an automated email from the ASF dual-hosted git repository.
nmalin 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 e12c98ac5b Implemented: Define return user message from controller (OFBIZ-12652)
e12c98ac5b is described below
commit e12c98ac5b1fcd58a8143707b5a80a333964b7ab
Author: Nicolas Malin <ni...@nereide.fr>
AuthorDate: Fri Jul 15 15:59:09 2022 +0200
Implemented: Define return user message from controller (OFBIZ-12652)
Currently, when you wish return a message to a user after an event request, you need to set it ine the called event.
for a service in java :
ServiceUtil.returnSuccess("Your service is a success")
for a service in groovy :
return success("Your service is a success")
for a Java class :
request.setAttribute("_EVENT_MESSAGE_", "Your service is a success");
If during an integration, you want to use standard service like createProduct, createPartyRelationship, and need a specific message for users, you need to define your own service.
For escape this case and increase the service usability, I propose to implement a new system to override the event return by a definition depending on the buisness context.
For that two improvement :
1. Add new child element to request-map->response on the controller
With given the exact value:
<response name="success" type="request" value="json">
<return-user-message value="Your service is a success"/>
</response>
With a flexible expander:
<response name="success" type="request" value="json">
<return-user-message value="Your service to change is a success"/>
</response>
With a property:
<response name="success" type="request" value="json">
<return-user-message ressource="CommonUiLabels" value="CommonSuccessfullyCreated"/>
</response>
From a context field:
<response name="success" type="request" value="json">
<return-user-message from-field="mySpecificReturnMessage"/>
</response>
2. From the context directly sent from the form
<form name="CallEvent" target="MyEvent" .. >
<field name="_CUSTOM_EVENT_MESSAGE_"> <hidden value="Your service to change is a success"/>
<field name="_CUSTOM_ERROR_MESSAGE_"> <hidden value="Your service failed"/>
Thanks to Florian Motteau for the implementation help
---
framework/webapp/dtd/site-conf.xsd | 35 +++++++++++++
.../ofbiz/webapp/control/ConfigXMLReader.java | 60 ++++++++++++++++++++++
.../ofbiz/webapp/control/RequestHandler.java | 52 +++++++++++++++++++
3 files changed, 147 insertions(+)
diff --git a/framework/webapp/dtd/site-conf.xsd b/framework/webapp/dtd/site-conf.xsd
index b02d6e46ce..f6912fa9ce 100644
--- a/framework/webapp/dtd/site-conf.xsd
+++ b/framework/webapp/dtd/site-conf.xsd
@@ -382,6 +382,40 @@ under the License.
</xs:attribute>
</xs:complexType>
</xs:element>
+ <xs:element name="return-user-message">
+ <xs:annotation>
+ <xs:documentation>
+ Before return a response to the end user, we can override the event message from different origin.
+ Hard coded, from the labelling system or from a given field
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexType>
+ <xs:attribute name="ressource" type="xs:string">
+ <xs:annotation>
+ <xs:documentation>
+ Properties ressource to use for resolve the message, if you set a value here, indicate the key on value attribute
+ otherwise this attribute will be ignored.
+ 'like: CommonUiLabels'
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="value" type="xs:string">
+ <xs:annotation>
+ <xs:documentation>
+ Value to use to display the response user message.
+ You can set a plain text, a flexible string or use a key from the property file give in ressource attribute.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="from-field" type="xs:string">
+ <xs:annotation>
+ <xs:documentation>
+ Set from what field in context we can found the response user message. This field can contain a flexible string
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+ </xs:element>
<xs:element name="event">
<xs:annotation>
<xs:documentation>
@@ -469,6 +503,7 @@ under the License.
</xs:documentation>
</xs:annotation>
</xs:element>
+ <xs:element minOccurs="0" ref="return-user-message"/>
</xs:sequence>
<xs:attributeGroup ref="attlist.response"/>
</xs:complexType>
diff --git a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ConfigXMLReader.java b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ConfigXMLReader.java
index 4d76e2283c..ab3b267e23 100644
--- a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ConfigXMLReader.java
+++ b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ConfigXMLReader.java
@@ -876,6 +876,7 @@ public final class ConfigXMLReader {
private boolean saveHomeView = false;
private Map<String, String> redirectParameterMap = new HashMap<>();
private Map<String, String> redirectParameterValueMap = new HashMap<>();
+ private RequestResponseUserMessage responseMessage = null;
/**
* Gets status code.
@@ -901,6 +902,14 @@ public final class ConfigXMLReader {
return redirectParameterValueMap;
}
+ /**
+ * return the response user message element linked to this
+ * @return
+ */
+ public RequestResponseUserMessage getResponseMessage() {
+ return responseMessage;
+ }
+
/**
* Gets type.
* @return the type
@@ -938,6 +947,57 @@ public final class ConfigXMLReader {
this.redirectParameterMap.put(redirectParameterElement.getAttribute("name"), from);
}
}
+ Element messageElement = UtilXml.firstChildElement(responseElement, "return-user-message");
+ if (messageElement != null) {
+ this.responseMessage = new RequestResponseUserMessage(this, messageElement);
+ }
+ }
+ }
+
+ public static class RequestResponseUserMessage {
+ private RequestResponse requestResponse;
+ private String ressource;
+ private String value;
+ private String fromField;
+
+ public RequestResponseUserMessage() {
+ }
+
+ public RequestResponseUserMessage(RequestResponse requestResponse, Element responseElement) {
+ this.requestResponse = requestResponse;
+ ressource = UtilValidate.isNotEmpty(responseElement.getAttribute("ressource"))
+ ? responseElement.getAttribute("ressource")
+ : null;
+ value = UtilValidate.isNotEmpty(responseElement.getAttribute("value"))
+ ? responseElement.getAttribute("value")
+ : null;
+ fromField = UtilValidate.isNotEmpty(responseElement.getAttribute("from-field"))
+ ? responseElement.getAttribute("from-field")
+ : null;
+ }
+
+ /**
+ * Return the ressource to use
+ * @return
+ */
+ public String getRessource() {
+ return ressource;
+ }
+
+ /**
+ * Return the value
+ * @return
+ */
+ public String getValue(Map<String, Object> context) {
+ return value;
+ }
+
+ /**
+ * Return the fromField
+ * @return
+ */
+ public String getFromField() {
+ return fromField;
}
}
diff --git a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java
index 877a5de387..18ec08d8d5 100644
--- a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java
+++ b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java
@@ -56,6 +56,7 @@ import org.apache.ofbiz.base.util.UtilMisc;
import org.apache.ofbiz.base.util.UtilObject;
import org.apache.ofbiz.base.util.UtilProperties;
import org.apache.ofbiz.base.util.UtilValidate;
+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.GenericValue;
@@ -825,6 +826,9 @@ public final class RequestHandler {
+ eventReturn + "].");
}
+ // before follow, analyze if a have a specific event message to return on the request.
+ setUserMessageResponseToRequest(request, nextRequestResponse);
+
if (Debug.verboseOn()) {
Debug.logVerbose("[Event Response Selected] type=" + nextRequestResponse.getType() + ", value=" + nextRequestResponse.getValue()
+ ". " + showSessionId(request), MODULE);
@@ -1017,6 +1021,54 @@ public final class RequestHandler {
}
}
+ /**
+ * Before return to end user the response, analyse if in this place we need override the event message
+ * 1. Check if the request response have a dedicated response user message
+ * 2. Check if a custom message is present on the context like _CUSTOM_ERROR_MESSAGE_ and _CUSTOM_EVENT_MESSAGE_
+ * @param request
+ * @param requestResponse
+ */
+ private void setUserMessageResponseToRequest(HttpServletRequest request, ConfigXMLReader.RequestResponse requestResponse) {
+ final String fieldMessageName = requestResponse.getName() == "error"
+ ? "_ERROR_MESSAGE_"
+ : "_EVENT_MESSAGE_";
+ final String customMessageField = "_CUSTOM" + fieldMessageName;
+ Map<String, Object> context = UtilHttp.getCombinedMap(request);
+ String userMessage = null;
+
+ if (requestResponse.getResponseMessage() != null) {
+ ConfigXMLReader.RequestResponseUserMessage responseMessage = requestResponse.getResponseMessage();
+
+ // Check if the response user message come from labelling ressource
+ String value = responseMessage.getValue(context);
+ if (UtilValidate.isNotEmpty(value)) {
+ userMessage = responseMessage.getRessource() != null
+ ? UtilProperties.getMessage(
+ responseMessage.getRessource(), value,
+ context, UtilHttp.getLocale(request))
+ : value;
+ } else if (responseMessage.getFromField() != null
+ && context.containsKey(responseMessage.getFromField())) {
+
+ // now analyze each field to found a flexible string to expand
+ userMessage = FlexibleStringExpander.getInstance(
+ (String) context.get(responseMessage.getFromField()))
+ .expandString(context);
+ }
+
+ if (UtilValidate.isNotEmpty(userMessage)) {
+ request.setAttribute(fieldMessageName, userMessage);
+ return;
+ }
+
+ if (context.containsKey(customMessageField)) {
+
+ //This field from the request so for security reason do not expand it to exclude any code injection
+ request.setAttribute(fieldMessageName, context.get(customMessageField));
+ }
+ }
+ }
+
/**
* Find the event handler and invoke an event.
*/