Skip to content

Commit

Permalink
Implemented: REST, adding segmented URI support for webtools/entitymaint
Browse files Browse the repository at this point in the history
(OFBIZ-11007)

After implemeted Rest mechanism on rev. 1868963 by Mathieu Lirzin,
I reviewed the rest url implemented by Artemiy Rozovyk for entitymaint in webtools.

With discussion with Mathieu and Leila, I selected this pattern :

    entity/[cover]/{entityName}/{pkValues: .*}

and implemented like this :

    entity/list -> list all entities
    entity/find/Party -> search
    entity/find/Party/Company -> displaying form for Party with id Company
    entity/create/Party -> creation form for a Party
    entity/edit/Party/Company/Company -> edit form for Party with id Company
    entity/change/Party/Company -> call crud following given http method
    entity/relations/Party -> View relation for Party

The old uris were currently kept and the oldest GenericWebEvent.updateGeneric() were updated to support rest method information.

Thanks Mathieu, Artemiy and Leila for their help to complete this improvement.
  • Loading branch information
nmalin committed Jan 9, 2020
1 parent c3d53e6 commit 6e1c7b5
Show file tree
Hide file tree
Showing 13 changed files with 134 additions and 67 deletions.
4 changes: 4 additions & 0 deletions framework/webtools/config/WebtoolsErrorUiLabels.xml
Expand Up @@ -100,6 +100,10 @@
<value xml:lang="zh">无法删除(写错误)</value>
<value xml:lang="zh-TW">無法刪除(寫錯誤)</value>
</property>
<property key="genericWebEvent.delete_succeeded">
<value xml:lang="en">Delete succeeded</value>
<value xml:lang="fr">La suppression a été effectuée: </value>
</property>
<property key="genericWebEvent.entity_name_not_specified">
<value xml:lang="en">The entityName was not specified, but is required</value>
<value xml:lang="es">El nombre de la entidad no fue especificado, pero es requerido</value>
Expand Down
17 changes: 11 additions & 6 deletions framework/webtools/groovyScripts/entity/FindGeneric.groovy
Expand Up @@ -41,8 +41,9 @@ if (modelEntity) {
ModelReader entityModelReader = delegator.getModelReader()
//create the search form with auto-fields-entity
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="FindGeneric?entityName=${entityName}">
<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="noConditionFind"><hidden value="Y"/></field>
<field name="searchOptions_collapsed" ><hidden value="true"/></field>
<field name="searchButton"><submit/></field>"""
Expand Down Expand Up @@ -81,9 +82,16 @@ 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" target="FindGeneric" list-name="listIt"
<form name="ListGeneric" type="list" method="post" target="entity/find/${entityName}" list-name="listIt"
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">
Expand All @@ -100,10 +108,7 @@ if (modelEntity) {
"<field name=\"${modelField.name}\" sort-field=\"true\"/>"
}
dynamicAutoEntityFieldListForm += """
<field name="viewGeneric" title=" "><hyperlink target="ViewGeneric" description="view">
<auto-parameters-entity entity-name="${entityName}"/>
<parameter param-name="entityName" value="${entityName}"/>
</hyperlink></field>
<field name="viewGeneric" title=" "><hyperlink target="entity/find/${entityName}${res}" description="view"/></field>
<sort-order><sort-field name="viewGeneric"/></sort-order>
</form></forms>"""

Expand Down
31 changes: 18 additions & 13 deletions framework/webtools/groovyScripts/entity/ViewGeneric.groovy
Expand Up @@ -28,7 +28,6 @@ import org.apache.ofbiz.entity.model.ModelRelation
import org.apache.ofbiz.entity.model.ModelKeyMap
import org.apache.ofbiz.base.util.UtilFormatOut
import org.apache.ofbiz.base.util.UtilMisc
import org.apache.ofbiz.base.util.UtilValidate
import java.sql.Timestamp
import java.sql.Date
import java.sql.Time
Expand Down Expand Up @@ -58,25 +57,31 @@ context.put("hasAllDelete", hasAllDelete)
context.put("hasViewPermission", hasViewPermission)
context.put("hasCreatePermission", hasCreatePermission)
context.put("hasUpdatePermission", hasUpdatePermission)
context.put("hasDeletePermission" , hasDeletePermission)
context.hasDeletePermission = hasDeletePermission

boolean useValue = true
String curFindString = "entityName=" + entityName
String currentFindString = entityName
GenericPK findByPK = delegator.makePK(entityName)
Iterator pkIterator = entity.getPksIterator()
while (pkIterator.hasNext()) {
ModelField field = pkIterator.next()
ModelFieldType type = delegator.getEntityFieldType(entity, field.getType())
String fval = parameters.get(field.getName())
if (fval) {
curFindString = curFindString + "&" + field.getName() + "=" + fval
findByPK.setString(field.getName(), fval)
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)
}
}
}
parameters << pkNamesValuesMap
context.pkNamesValuesMap = pkNamesValuesMap
context.put("findByPk", findByPK.toString())

curFindString = UtilFormatOut.encodeQuery(curFindString)
context.put("curFindString", curFindString)
context.currentFindString = UtilFormatOut.encodeQuery(currentFindString)

GenericValue value = null
//only try to find it if this is a valid primary key...
Expand Down Expand Up @@ -136,7 +141,7 @@ if (value == null && (findByPK.getAllFields().size() > 0)) {
}
context.put("pkNotFound", pkNotFound)

String lastUpdateMode = parameters.get("UPDATE_MODE")
String lastUpdateMode = parameters.get("restMethod")
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
Expand Down
Expand Up @@ -61,7 +61,9 @@ public class GenericWebEvent {
public static String updateGeneric(HttpServletRequest request, HttpServletResponse response) {
String entityName = request.getParameter("entityName");
Locale locale = UtilHttp.getLocale(request);

if (UtilValidate.isEmpty(entityName)) {
entityName = (String) request.getAttribute("entityName");
}
if (UtilValidate.isEmpty(entityName)) {
String errMsg = UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.entity_name_not_specified", locale) + ".";
request.setAttribute("_ERROR_MESSAGE_", errMsg);
Expand Down Expand Up @@ -95,6 +97,16 @@ public static String updateGeneric(HttpServletRequest request, HttpServletRespon
}

String updateMode = request.getParameter("UPDATE_MODE");
if (updateMode == null && request.getParameter("restMethod") == null) {
updateMode = "CREATE";
}
if (updateMode == null) {
switch (request.getParameter("restMethod")) {
case "PUT": updateMode = "UPDATE"; break;
case "DELETE": updateMode = "DELETE"; break;
default: updateMode = "CREATE"; break;
}
}

if (UtilValidate.isEmpty(updateMode)) {
String errMsg = UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.update_mode_not_specified", locale) + ".";
Expand Down Expand Up @@ -156,6 +168,8 @@ public static String updateGeneric(HttpServletRequest request, HttpServletRespon
// Delete actual main entity last, just in case database is set up to do a cascading delete, caches won't get cleared
try {
delegator.removeByPrimaryKey(findByEntity.getPrimaryKey());
String confirmMsg = UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.delete_succeeded", locale) ;
request.setAttribute("_EVENT_MESSAGE_", confirmMsg);
} catch (GenericEntityException e) {
String errMsg = UtilProperties.getMessage(GenericWebEvent.err_resource, "genericWebEvent.delete_failed", locale) + ": " + e.toString();
Debug.logWarning(e, errMsg, module);
Expand Down
2 changes: 1 addition & 1 deletion framework/webtools/template/artifactinfo/ArtifactInfo.ftl
Expand Up @@ -127,7 +127,7 @@ under the License.
</#if>

<#if "entity" == artifactInfo.getType()>
<div><a href="<@ofbizUrl>FindGeneric?entityName=${artifactInfo.modelEntity.getEntityName()}&amp;find=true&amp;VIEW_SIZE=50&amp;VIEW_INDEX=0</@ofbizUrl>">All Entity Data</a></div>
<div><a href="<@ofbizUrl>entity/find/${artifactInfo.modelEntity.getEntityName()}?noConditionFind=Y</@ofbizUrl>">All Entity Data</a></div>
<h2>Entity Fields</h2>
<table>
<#list artifactInfo.modelEntity.getFieldsUnmodifiable() as modelField>
Expand Down
22 changes: 7 additions & 15 deletions framework/webtools/template/entity/EntityMaint.ftl
Expand Up @@ -79,21 +79,13 @@ under the License.
<td<#if anchor?has_content> ${anchor}</#if>>${entity.entityName}<#if entity.viewEntity == 'Y'>&nbsp;(${uiLabelMap.WebtoolsEntityView})</#if></td>
<#assign anchor="">
<td class="button-col">
<#if entity.viewEntity == 'Y'>
<#if entity.entityPermissionView == 'Y'>
<a href='<@ofbizUrl>ViewRelations?entityName=${entity.entityName}</@ofbizUrl>'>${uiLabelMap.WebtoolsReln}</a>
<a href='<@ofbizUrl>FindGeneric?entityName=${entity.entityName}</@ofbizUrl>'>${uiLabelMap.WebtoolsFind}</a>
<a href='<@ofbizUrl>FindGeneric?entityName=${entity.entityName}&amp;noConditionFind=Y</@ofbizUrl>'>${uiLabelMap.WebtoolsAll}</a>
</#if>
<#else>
<#if entity.entityPermissionCreate == 'Y'>
<a href='<@ofbizUrl>ViewGeneric?entityName=${entity.entityName}</@ofbizUrl>' title='${uiLabelMap.CommonCreate}'>${uiLabelMap.WebtoolsCreate}</a>
</#if>
<#if entity.entityPermissionView == 'Y'>
<a href='<@ofbizUrl>ViewRelations?entityName=${entity.entityName}</@ofbizUrl>' title='${uiLabelMap.WebtoolsViewRelations}'>${uiLabelMap.WebtoolsReln}</a>
<a href='<@ofbizUrl>FindGeneric?entityName=${entity.entityName}</@ofbizUrl>' title='${uiLabelMap.WebtoolsFindRecord}'>${uiLabelMap.WebtoolsFind}</a>
<a href='<@ofbizUrl>FindGeneric?entityName=${entity.entityName}&amp;noConditionFind=Y</@ofbizUrl>' title='${uiLabelMap.WebtoolsFindAllRecords}'>${uiLabelMap.WebtoolsAll}</a>
</#if>
<#if entity.viewEntity != 'Y' && entity.entityPermissionCreate == 'Y'>
<a href='<@ofbizUrl>entity/create/${entity.entityName}</@ofbizUrl>' title='${uiLabelMap.CommonCreate}'>${uiLabelMap.WebtoolsCreate}</a>
</#if>
<#if entity.entityPermissionView == 'Y'>
<a href='<@ofbizUrl>entity/relations/${entity.entityName}</@ofbizUrl>'>${uiLabelMap.WebtoolsReln}</a>
<a href='<@ofbizUrl>entity/find/${entity.entityName}</@ofbizUrl>'>${uiLabelMap.WebtoolsFind}</a>
<a href='<@ofbizUrl>entity/find/${entity.entityName}?noConditionFind=Y</@ofbizUrl>'>${uiLabelMap.WebtoolsAll}</a>
</#if>
</td>
<#if right_col>
Expand Down
2 changes: 1 addition & 1 deletion framework/webtools/template/entity/EntityRefMain.ftl
Expand Up @@ -63,7 +63,7 @@ under the License.
</div>
<div>${entity.title}&nbsp;
<#if !forstatic>
<a target='main' href="<@ofbizUrl>FindGeneric?entityName=${entity.entityName}&amp;noConditionFind=Y</@ofbizUrl>">[${uiLabelMap.WebtoolsViewData}]</a>
<a target='main' href="<@ofbizUrl>entity/find/${entity.entityName}?noConditionFind=Y</@ofbizUrl>">[${uiLabelMap.WebtoolsViewData}]</a>
</#if>
<#if !forstatic>
<a target='main' href="<@ofbizUrl>ArtifactInfo?name=${entity.entityName}&amp;type=entity</@ofbizUrl>">[${uiLabelMap.WebtoolsArtifactInfo}]</a>
Expand Down
22 changes: 14 additions & 8 deletions framework/webtools/template/entity/ViewGeneric.ftl
Expand Up @@ -50,15 +50,22 @@ function ShowTab(lname) {
<h2>${uiLabelMap.WebtoolsWithPk}: ${findByPk}</h2>
<br />
<div class="button-bar">
<a href='<@ofbizUrl>FindGeneric?entityName=${entityName}&amp;noConditionFind=Y</@ofbizUrl>' class="buttontext">${uiLabelMap.WebtoolsBackToFindScreen}</a>
<a href='<@ofbizUrl>entity/find/${entityName}</@ofbizUrl>' class="buttontext">${uiLabelMap.WebtoolsBackToFindScreen}</a>
<#if enableEdit = "false">
<#if hasCreatePermission>
<a href='<@ofbizUrl>ViewGeneric?entityName=${entityName}&amp;enableEdit=true</@ofbizUrl>' class="buttontext create">${uiLabelMap.CommonCreate}</a>
<a href="<@ofbizUrl>ViewGeneric?${curFindString}&amp;enableEdit=true</@ofbizUrl>" class="buttontext">${uiLabelMap.CommonEdit}</a>
<form action="<@ofbizUrl>entity/edit/${currentFindString}</@ofbizUrl>" method="get">
<input type="submit" value="${uiLabelMap.CommonEdit}" />
</form>
</#if>
<#if value?has_content>
<#if hasDeletePermission>
<a href='<@ofbizUrl>UpdateGeneric?UPDATE_MODE=DELETE&amp;${curFindString}</@ofbizUrl>' class="buttontext delete">${uiLabelMap.WebtoolsDeleteThisValue}</a>
<form action='<@ofbizUrl>entity/change/${currentFindString}</@ofbizUrl>' method="delete" name="updateForm">
<input type="hidden" value="DELETE" name="restMethod"/>
<#list pkNamesValuesMap.keySet() as pkName>
<input type="hidden" value="${pkNamesValuesMap.get(pkName)}" name="${pkName}"/>
</#list>
<input type="submit" value="${uiLabelMap.WebtoolsDeleteThisValue}" />
</form>
</#if>
</#if>
</#if>
Expand Down Expand Up @@ -104,14 +111,13 @@ function ShowTab(lname) {
<#if pkNotFound>
<p>${uiLabelMap.WebtoolsEntityName} ${entityName} ${uiLabelMap.WebtoolsWithPk} ${findByPk} ${uiLabelMap.WebtoolsSpecifiedEntity2}.</p>
</#if>
<form action='<@ofbizUrl>UpdateGeneric?entityName=${entityName}</@ofbizUrl>' method="post" name="updateForm">
<form action='<@ofbizUrl>entity/change/<#if value?has_content>${currentFindString}<#else>${entityName}</#if></@ofbizUrl>' method="post" name="updateForm">
<#assign showFields = true>
<#assign alt_row = false>
<table class="basic-table" cellspacing="0">
<#if value?has_content>
<#if hasUpdatePermission>
<#if newFieldPkList?has_content>
<input type="hidden" name="UPDATE_MODE" value="UPDATE"/>
<#list newFieldPkList as field>
<tr<#if alt_row> class="alternate-row"</#if>>
<td class="label">${field.name}</td>
Expand All @@ -131,7 +137,6 @@ function ShowTab(lname) {
<#if hasCreatePermission>
<#if newFieldPkList?has_content>
<p>${uiLabelMap.WebtoolsYouMayCreateAnEntity}</p>
<input type="hidden" name="UPDATE_MODE" value="CREATE"/>
<#list newFieldPkList as field>
<tr<#if alt_row> class="alternate-row"</#if>>
<td class="label">${field.name}</td>
Expand Down Expand Up @@ -204,6 +209,7 @@ function ShowTab(lname) {
<#assign alt_row = !alt_row>
</#list>
<#if value?has_content>
<input type="hidden" name="restMethod" value="PUT"/>
<#assign button = "${uiLabelMap.CommonUpdate}">
<#else>
<#assign button = "${uiLabelMap.CommonCreate}">
Expand All @@ -212,7 +218,7 @@ function ShowTab(lname) {
<td>&nbsp;</td>
<td>
<input type="submit" name="Update" value="${button}" />
<a href="<@ofbizUrl>ViewGeneric?${curFindString}</@ofbizUrl>" class="smallSubmit">${uiLabelMap.CommonCancel}</a>
<a href="<@ofbizUrl>entity/find/${entityName}</@ofbizUrl>" class="smallSubmit">${uiLabelMap.CommonCancel}</a>
</td>
</tr>
</#if>
Expand Down
4 changes: 2 additions & 2 deletions framework/webtools/template/entity/ViewRelations.ftl
Expand Up @@ -29,7 +29,7 @@ under the License.
<h2>${uiLabelMap.WebtoolsForEntity}: ${entityName}</h2>
<br />
<div class="button-bar">
<a href="<@ofbizUrl>FindGeneric?entityName=${entityName}</@ofbizUrl>" class="smallSubmit">${uiLabelMap.WebtoolsBackToFindScreen}</a>
<a href="<@ofbizUrl>entity/find/${entityName}</@ofbizUrl>" class="smallSubmit">${uiLabelMap.WebtoolsBackToFindScreen}</a>
</div>
<br />
<table class="basic-table hover-bar" cellspacing="0">
Expand All @@ -44,7 +44,7 @@ under the License.
<#list relations as relation>
<tr<#if alt_row> class="alternate-row"</#if>>
<td>${relation.title}</td>
<td class="button-col"><a href='<@ofbizUrl>FindGeneric?entityName=${relation.relEntityName}</@ofbizUrl>'>${relation.relEntityName}</a></td>
<td class="button-col"><a href='<@ofbizUrl>entity/find/${relation.relEntityName}</@ofbizUrl>'>${relation.relEntityName}</a></td>
<td>${relation.type}</td>
<td>${relation.fkName}</td>
<td>
Expand Down

0 comments on commit 6e1c7b5

Please sign in to comment.