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

commit 1ee1ec76d6202f66cdff271fd4c313d5d2c132cc
Author: Nicolas Malin <[email protected]>
AuthorDate: Tue Jan 28 18:16:13 2020 +0100

    Fixed: Change 'restMethod' by '_method' in request parameters
    (OFBIZ-11007)
    
    Some issue has been introduce on the previous commit 6e1c7b5 [1], corrected 
by this one :
      * the view link on ListGeneric failed
      * the paginate on ListGeneric failed
    
    I also simplify the url writing with delegate the entity path generation 
and translation
    to two function on EntityUtil : entityToPath and getPkValuesMapFromPath
    
    thanks to Pawan Verma to spot the pagination problem
    
    [1] https://gitbox.apache.org/repos/asf?p=ofbiz-framework.git;h=6e1c7b5
---
 .../org/apache/ofbiz/entity/util/EntityUtil.java   | 53 ++++++++++++++++++++++
 .../groovyScripts/entity/FindGeneric.groovy        | 14 ++----
 .../groovyScripts/entity/ViewGeneric.groovy        | 35 +++++---------
 .../org/apache/ofbiz/webtools/GenericWebEvent.java | 23 +++++++---
 framework/webtools/template/entity/ViewGeneric.ftl |  4 +-
 5 files changed, 87 insertions(+), 42 deletions(-)

diff --git 
a/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityUtil.java 
b/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityUtil.java
index 0c0411d..9a69955 100644
--- 
a/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityUtil.java
+++ 
b/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityUtil.java
@@ -22,6 +22,7 @@ package org.apache.ofbiz.entity.util;
 import java.io.Serializable;
 import java.sql.Timestamp;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -48,6 +49,7 @@ import org.apache.ofbiz.entity.GenericValue;
 import org.apache.ofbiz.entity.condition.EntityCondition;
 import org.apache.ofbiz.entity.condition.EntityDateFilterCondition;
 import org.apache.ofbiz.entity.condition.OrderByList;
+import org.apache.ofbiz.entity.model.ModelEntity;
 import org.apache.ofbiz.entity.model.ModelField;
 
 import static java.util.stream.Collectors.toList;
@@ -544,4 +546,55 @@ public final class EntityUtil {
         return new PagedList<>(startIndex, endIndex, size, viewIndex, 
viewSize, dataItems);
     }
 
+    /**
+     * For a entityName return the primary keys path that identify it
+     * like entityName/pkValue1/pkValue2/../pkValueN
+     * @param delegator
+     * @param entityName
+     * @param context
+     * @return
+     */
+    public static String entityToPath(Delegator delegator, String entityName, 
Map<String, Object> context) {
+        return entityToPath(delegator.makeValidValue(entityName, context));
+    }
+    /**
+     * For a entityName return the primary keys path that identify it
+     * like entityName/pkValue1/pkValue2/../pkValueN
+     * @param gv
+     * @return
+     */
+    public static String entityToPath(GenericValue gv) {
+        StringBuilder path = new StringBuilder(gv.getEntityName());
+        for (String pkName : gv.getModelEntity().getPkFieldNames()) {
+            path.append("/").append(gv.getString(pkName));
+        }
+        return path.toString();
+    }
+
+    /**
+     * Form a entityName and primary keys path
+     * convert it to a Map contains all pkValue :
+     *  entityName/pkValue1/pkValue2/../pkValueN
+     *    -> [pkName1: pkValue1,
+     *        pkName2, pkValue2,
+     *        ...,
+     *        pkNameN: pkValueN]
+     * @param modelEntity
+     * @param path
+     * @return
+     */
+    public static Map<String, Object> getPkValuesMapFromPath(ModelEntity 
modelEntity, String path)
+            throws GenericEntityException {
+        if (UtilValidate.isEmpty(path)) return null;
+        LinkedList<String> pkValues = new 
LinkedList<>(Arrays.asList(path.split("/")));
+        List<String> pkFieldNames = modelEntity.getPkFieldNames();
+        if (pkFieldNames.size() != pkValues.size()) {
+            throw new GenericEntityException ("Identification path failed ");
+        }
+        Map<String, Object> pkValuesMap = new HashMap<>();
+        for (String pkName : modelEntity.getPkFieldNames()) {
+            pkValuesMap.put(pkName, pkValues.removeFirst());
+        }
+        return pkValuesMap;
+    }
 }
diff --git a/framework/webtools/groovyScripts/entity/FindGeneric.groovy 
b/framework/webtools/groovyScripts/entity/FindGeneric.groovy
index 29d3eb1..cd8d06a 100644
--- a/framework/webtools/groovyScripts/entity/FindGeneric.groovy
+++ b/framework/webtools/groovyScripts/entity/FindGeneric.groovy
@@ -43,7 +43,7 @@ if (modelEntity) {
     String dynamicAutoEntityFieldSearchForm = """<?xml version="1.0" 
encoding="UTF-8"?><forms xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns="http://ofbiz.apache.org/Widget-Form"; 
xsi:schemaLocation="http://ofbiz.apache.org/Widget-Form 
http://ofbiz.apache.org/dtds/widget-form.xsd";>
         <form name="FindGeneric" type="single" 
target="entity/find/${entityName}">
            <auto-fields-entity entity-name="${entityName}" 
default-field-type="find" include-internal="true"/>
-            <field name="restMethod"><hidden value="GET"/></field>
+            <field name="_method"><hidden value="GET"/></field>
             <field name="noConditionFind"><hidden value="Y"/></field>
             <field name="searchOptions_collapsed" ><hidden 
value="true"/></field>
             <field name="searchButton"><submit/></field>"""
@@ -82,16 +82,9 @@ if (modelEntity) {
     dynamicAutoEntitySearchFormRenderer.render(writer, context)
     context.dynamicAutoEntitySearchForm = writer
 
-    // In case of composite pk
-    String pk = modelEntity.pkNameString()
-    String res = ""
-    for (w in pk.split(", ")) {
-        res = "${res}/\${${w}}"
-    }
-
     //prepare the result list from performFind
     String dynamicAutoEntityFieldListForm = """<?xml version="1.0" 
encoding="UTF-8"?><forms xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xmlns="http://ofbiz.apache.org/Widget-Form"; 
xsi:schemaLocation="http://ofbiz.apache.org/Widget-Form 
http://ofbiz.apache.org/dtds/widget-form.xsd";>
-            <form name="ListGeneric" type="list" method="post" 
target="entity/find/${entityName}" list-name="listIt" 
+            <form name="ListGeneric" type="list" 
target="entity/find/${entityName}" list-name="listIt" 
paginate-target="entity/find/${entityName}"
               odd-row-style="alternate-row" default-table-style="basic-table 
light-grid hover-bar" header-row-style="header-row-2">
             <actions>
                 <service service-name="performFind">
@@ -101,6 +94,7 @@ if (modelEntity) {
                 </service>
             </actions>
             <auto-fields-entity entity-name="${entityName}" 
default-field-type="display" include-internal="true"/>
+            <field name="_method"><hidden value="POST"/></field>
             <field name="entityName"><hidden value="${entityName}"/></field>"""
     modelEntity.getFieldsUnmodifiable().each {
         modelField ->
@@ -108,7 +102,7 @@ if (modelEntity) {
                     "<field name=\"${modelField.name}\" sort-field=\"true\"/>"
     }
     dynamicAutoEntityFieldListForm += """
-            <field name="viewGeneric" title=" "><hyperlink 
target="entity/find/${entityName}${res}" description="view"/></field>
+            <field name="viewGeneric" title=" "><hyperlink target="\${groovy: 
'entity/find/' + 
org.apache.ofbiz.entity.util.EntityUtil.entityToPath(delegator, 
'${entityName}', context)}" description="view"/></field>
             <sort-order><sort-field name="viewGeneric"/></sort-order>
             </form></forms>"""
 
diff --git a/framework/webtools/groovyScripts/entity/ViewGeneric.groovy 
b/framework/webtools/groovyScripts/entity/ViewGeneric.groovy
index 36c963d..79ef1fd 100644
--- a/framework/webtools/groovyScripts/entity/ViewGeneric.groovy
+++ b/framework/webtools/groovyScripts/entity/ViewGeneric.groovy
@@ -16,10 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import org.apache.ofbiz.entity.Delegator
 import org.apache.ofbiz.entity.GenericPK
 import org.apache.ofbiz.entity.GenericValue
-import org.apache.ofbiz.security.Security
+import org.apache.ofbiz.entity.util.EntityUtil
 import org.apache.ofbiz.entity.model.ModelReader
 import org.apache.ofbiz.entity.model.ModelEntity
 import org.apache.ofbiz.entity.model.ModelField
@@ -60,29 +59,19 @@ context.put("hasUpdatePermission", hasUpdatePermission)
 context.hasDeletePermission = hasDeletePermission
 
 boolean useValue = true
-String currentFindString = entityName
-GenericPK findByPK = delegator.makePK(entityName)
-Iterator pkIterator = entity.getPksIterator()
-String fieldValues = parameters.get("pkValues")
-HashMap<String,String> pkNamesValuesMap = new HashMap<>()
-if (fieldValues != null) {
-    Iterator pkParamIterator = Arrays.asList(fieldValues.split("/")).iterator()
-    while (pkIterator.hasNext() && pkParamIterator.hasNext()) {
-        ModelField field = pkIterator.next()
-        String fieldValue = pkParamIterator.next()
-        if (fieldValue) {
-            currentFindString += "/" + fieldValue
-            pkNamesValuesMap[field.getName()] = fieldValue
-            findByPK.setString(field.getName(), fieldValue)
-        }
-    }
+
+if (parameters.pkValues) {
+    Map<String, String> pkNamesValuesMap = EntityUtil.getPkValuesMapFromPath(
+            delegator.getModelEntity(entityName), parameters.pkValues)
+    parameters << pkNamesValuesMap
+    context.pkNamesValuesMap = pkNamesValuesMap
 }
-parameters << pkNamesValuesMap
-context.pkNamesValuesMap = pkNamesValuesMap
+GenericValue valueFromParameters = delegator.makeValue(entityName)
+valueFromParameters.setPKFields(parameters)
+GenericPK findByPK = valueFromParameters.getPrimaryKey()
+context.currentFindString = 
UtilFormatOut.encodeQuery(EntityUtil.entityToPath(valueFromParameters))
 context.put("findByPk", findByPK.toString())
 
-context.currentFindString = UtilFormatOut.encodeQuery(currentFindString)
-
 GenericValue value = null
 //only try to find it if this is a valid primary key...
 if (findByPK.isPrimaryKey()) {
@@ -141,7 +130,7 @@ if (value == null && (findByPK.getAllFields().size() > 0)) {
 }
 context.put("pkNotFound", pkNotFound)
 
-String lastUpdateMode = parameters.get("restMethod")
+String lastUpdateMode = parameters.get("_method")
 if ((session.getAttribute("_ERROR_MESSAGE_") != null || 
request.getAttribute("_ERROR_MESSAGE_") != null) &&
     lastUpdateMode != null && !"DELETE".equals(lastUpdateMode)) {
     //if we are updating and there is an error, do not use the entity data for 
the fields, use parameters to get the old value
diff --git 
a/framework/webtools/src/main/java/org/apache/ofbiz/webtools/GenericWebEvent.java
 
b/framework/webtools/src/main/java/org/apache/ofbiz/webtools/GenericWebEvent.java
index 07c5233..59df1db 100644
--- 
a/framework/webtools/src/main/java/org/apache/ofbiz/webtools/GenericWebEvent.java
+++ 
b/framework/webtools/src/main/java/org/apache/ofbiz/webtools/GenericWebEvent.java
@@ -40,6 +40,7 @@ import org.apache.ofbiz.entity.model.ModelField;
 import org.apache.ofbiz.entity.model.ModelFieldType;
 import org.apache.ofbiz.entity.model.ModelReader;
 import org.apache.ofbiz.entity.util.EntityQuery;
+import org.apache.ofbiz.entity.util.EntityUtil;
 import org.apache.ofbiz.security.Security;
 
 /**
@@ -102,15 +103,23 @@ public class GenericWebEvent {
             Debug.logError(e, module);
         }
 
+        //Check if the update came from rest call
         String updateMode = request.getParameter("UPDATE_MODE");
-        if (updateMode == null && request.getParameter("restMethod") == null) {
-            updateMode = "CREATE";
-        }
+        Map<String, Object> pkFields = null;
         if (updateMode == null) {
-            switch (request.getParameter("restMethod")) {
-                case "PUT": updateMode = "UPDATE"; break;
-                case "DELETE": updateMode = "DELETE"; break;
-                default: updateMode = "CREATE"; break;
+            switch (UtilHttp.getRequestMethod(request)) {
+            case "PUT": updateMode = "UPDATE"; break;
+            case "DELETE": updateMode = "DELETE"; break;
+            default: updateMode = "CREATE"; break;
+            }
+            try {
+                pkFields = 
EntityUtil.getPkValuesMapFromPath(delegator.getModelEntity(entityName),
+                        (String) request.getAttribute("pkValues"));
+            } catch (Exception e) {
+
+                request.setAttribute("_ERROR_MESSAGE_", 
UtilProperties.getMessage(err_resource,
+                        "genericWebEvent.entity_path_not_valid", locale));
+                return "error";
             }
         }
 
diff --git a/framework/webtools/template/entity/ViewGeneric.ftl 
b/framework/webtools/template/entity/ViewGeneric.ftl
index 216eb63..7c163db 100644
--- a/framework/webtools/template/entity/ViewGeneric.ftl
+++ b/framework/webtools/template/entity/ViewGeneric.ftl
@@ -60,7 +60,7 @@ function ShowTab(lname) {
         <#if value?has_content>
           <#if hasDeletePermission>
             <form 
action='<@ofbizUrl>entity/change/${currentFindString}</@ofbizUrl>' 
method="delete" name="updateForm">
-              <input type="hidden" value="DELETE" name="restMethod"/>
+              <input type="hidden" value="DELETE" name="_method"/>
               <#list pkNamesValuesMap.keySet() as pkName>
                 <input type="hidden" value="${pkNamesValuesMap.get(pkName)}" 
name="${pkName}"/>
               </#list>
@@ -209,7 +209,7 @@ function ShowTab(lname) {
                     <#assign alt_row = !alt_row>
                   </#list>
                   <#if value?has_content>
-                    <input type="hidden" name="restMethod" value="PUT"/>
+                    <input type="hidden" name="_method" value="PUT"/>
                     <#assign button = "${uiLabelMap.CommonUpdate}">
                   <#else>
                     <#assign button = "${uiLabelMap.CommonCreate}">

Reply via email to