Skip to content
Permalink
Browse files
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
  • Loading branch information
nmalin committed Jan 29, 2020
1 parent 11cf350 commit 1ee1ec76d6202f66cdff271fd4c313d5d2c132cc
@@ -22,6 +22,7 @@
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.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 static PagedList<GenericValue> getPagedList(EntityListIterator iter, int
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;
}
}
@@ -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,14 +94,15 @@ 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 ->
dynamicAutoEntityFieldListForm +=
"<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>"""

@@ -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
@@ -40,6 +40,7 @@
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 static String updateGeneric(HttpServletRequest request, HttpServletRespon
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";
}
}

@@ -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}">

0 comments on commit 1ee1ec7

Please sign in to comment.