mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Rules/Actions REST API drop after current phase of testing
- various minor fixes from current testing phase - various code improvements, mostly in Rules Helper JSON to object translation methods for rules, actions and conditions - some improvements to test data creation in unit test class helper methods - updates to delete, get, post rule unit tests - put rule unit test - finer grained per property JSON exception handling in rules helper methods - added more assertions to various unit tests - added more comments to web scripts and rules helper methods - added more comments to unit tests - added more error checking across various web scripts git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@11483 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
<webscript>
|
||||
<shortname>Get Rule</shortname>
|
||||
<description>Get the rule identified by the specified rule node reference.</description>
|
||||
<url>/api/rules/{store_type}/{store_id}/{id}</url>
|
||||
<url>/api/node/{store_type}/{store_id}/{id}/rules/{id}</url>
|
||||
<url>/api/path/{store_type}/{store_id}/{id}/rules/{id}</url>
|
||||
<url>/api/rules/{store_type}/{store_id}/{rule_id}</url>
|
||||
<url>/api/node/{store_type}/{store_id}/{id}/rules/{rule_id}</url>
|
||||
<url>/api/path/{store_type}/{store_id}/{id}/rules/{rule_id}</url>
|
||||
<format default="json"/>
|
||||
<authentication>user</authentication>
|
||||
<transaction>required</transaction>
|
||||
|
@@ -1,9 +1,9 @@
|
||||
<webscript>
|
||||
<shortname>Put Rule</shortname>
|
||||
<description>Update the rule identified by the specified rule node reference.</description>
|
||||
<url>/api/rules/{store_type}/{store_id}/{id}</url>
|
||||
<url>/api/node/{store_type}/{store_id}/{id}/rules/{id}</url>
|
||||
<url>/api/path/{store_type}/{store_id}/{id}/rules/{id}</url>
|
||||
<url>/api/rules/{store_type}/{store_id}/{rule_id}</url>
|
||||
<url>/api/node/{store_type}/{store_id}/{id}/rules/{rule_id}</url>
|
||||
<url>/api/path/{store_type}/{store_id}/{id}/rules/{rule_id}</url>
|
||||
<format default="json"/>
|
||||
<authentication>user</authentication>
|
||||
<transaction>required</transaction>
|
||||
|
@@ -1,2 +1,2 @@
|
||||
<#import "rule.lib.ftl" as ruleLib/>
|
||||
<@ruleLib.ruleJSON rule=rule/>
|
||||
<@ruleLib.ruleJSON rule=rule owningNodeRef=owningNodeRef/>
|
@@ -37,6 +37,16 @@ import org.alfresco.web.scripts.WebScriptRequest;
|
||||
/**
|
||||
* Web Script to DELETE the rule identified by the given rule node id.
|
||||
*
|
||||
* NOTE -
|
||||
* that if a value is provided for the 'id' URL template variable {id},
|
||||
* i.e. either of the following URL patterns have been used
|
||||
* <url>/api/node/{store_type}/{store_id}/{id}/rules/{rule_id}</url> or
|
||||
* <url>/api/path/{store_type}/{store_id}/{id}/rules/{rule_id}</url>
|
||||
* then the rule owning node ref supplied therein will be ignored,
|
||||
* as these URL templates are just provided for convenience and the
|
||||
* rule owning node ref is retrieved by using the rule's identifying node
|
||||
* ref (supplied in {rule_id})
|
||||
*
|
||||
* @author glen johnson at alfresco dot com
|
||||
*/
|
||||
public class RuleDelete extends DeclarativeWebScript
|
||||
@@ -100,28 +110,25 @@ public class RuleDelete extends DeclarativeWebScript
|
||||
}
|
||||
|
||||
String ruleNodeId = req.getServiceMatch().getTemplateVars().get(REQ_TEMPL_VAR_RULE_NODE_ID);
|
||||
// Handle if 'ruleNodeId' URL template token not provided
|
||||
// Handle if 'rule_id' URL template token not provided
|
||||
if ((ruleNodeId == null) || (ruleNodeId.length() == 0))
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
|
||||
"The 'rule_id' URL template token has not been provided in URL");
|
||||
}
|
||||
|
||||
// NOTE -
|
||||
// that if a value is provided for the 'id' URL template variable {id},
|
||||
// i.e. either of the following URL patterns have been used
|
||||
// <url>/api/node/{store_type}/{store_id}/{id}/rules/{rule_id}</url> or
|
||||
// <url>/api/path/{store_type}/{store_id}/{id}/rules/{rule_id}</url>
|
||||
// then the rule owning node ref supplied therein will be ignored,
|
||||
// as these URL templates are just provided for convenience and the
|
||||
// rule owning node ref is retrieved by using the rule's identifying node
|
||||
// ref (supplied in {rule_id})
|
||||
|
||||
// create the rule's identifying node reference from the given
|
||||
// URL template tokens
|
||||
NodeRef ruleNodeRef = this.rulesHelper.getNodeRefFromWebScriptUrl(req, storeType, storeId, ruleNodeId);
|
||||
|
||||
// get the rule using it's unique identifying node reference
|
||||
// if ruleNodeRef referred to by {store_type} {store_id} {rule_id} is 'null' then the rule identified by that
|
||||
// given node id or node path no longer exists
|
||||
if (ruleNodeRef == null)
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_NOT_FOUND, "Rule identified by rule node/path - 'store_type': "
|
||||
+ storeType + " 'store_id': " + storeId + " and 'rule_id': " + ruleNodeId + " could not be found");
|
||||
}
|
||||
|
||||
Rule rule = this.ruleService.getRule(ruleNodeRef);
|
||||
NodeRef ruleOwningNodeRef = this.ruleService.getOwningNodeRef(rule);
|
||||
|
||||
|
@@ -38,6 +38,16 @@ import org.alfresco.web.scripts.WebScriptRequest;
|
||||
/**
|
||||
* Web Script to GET the rule identified by the given rule node reference.
|
||||
*
|
||||
* NOTE -
|
||||
* that if a value is provided for the 'id' URL template variable {id},
|
||||
* i.e. either of the following URL patterns have been used
|
||||
* <url>/api/node/{store_type}/{store_id}/{id}/rules/{rule_id}</url> or
|
||||
* <url>/api/path/{store_type}/{store_id}/{id}/rules/{rule_id}</url>
|
||||
* then the rule owning node ref supplied therein will be ignored,
|
||||
* as these URL templates are just provided for convenience and the
|
||||
* rule owning node ref is retrieved by using the rule's identifying node
|
||||
* ref (supplied in {rule_id})
|
||||
*
|
||||
* @author glen johnson at alfresco dot com
|
||||
*/
|
||||
public class RuleGet extends DeclarativeWebScript
|
||||
@@ -45,7 +55,7 @@ public class RuleGet extends DeclarativeWebScript
|
||||
// private constants
|
||||
private static final String REQ_TEMPL_VAR_STORE_TYPE = "store_type";
|
||||
private static final String REQ_TEMPL_VAR_STORE_ID = "store_id";
|
||||
private static final String REQ_TEMPL_VAR_RULE_NODE_ID = "id";
|
||||
private static final String REQ_TEMPL_VAR_RULE_NODE_ID = "rule_id";
|
||||
|
||||
// model property keys
|
||||
private static final String MODEL_PROP_KEY_RULE = "rule";
|
||||
@@ -119,12 +129,12 @@ public class RuleGet extends DeclarativeWebScript
|
||||
// URL template tokens
|
||||
NodeRef ruleNodeRef = this.rulesHelper.getNodeRefFromWebScriptUrl(req, storeType, storeId, ruleNodeId);
|
||||
|
||||
// if ruleNodeRef referred to by {store_type} {store_id} {id} is 'null' then the rule identified by that
|
||||
// if ruleNodeRef referred to by {store_type} {store_id} {rule_id} is 'null' then the rule identified by that
|
||||
// given node id or node path no longer exists
|
||||
if (ruleNodeRef == null)
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_NOT_FOUND, "Rule identified by rule node/path - 'store_type': "
|
||||
+ storeType + " 'store_id': " + storeId + " and 'id': " + ruleNodeId + " could not be found");
|
||||
+ storeType + " 'store_id': " + storeId + " and 'rule_id': " + ruleNodeId + " could not be found");
|
||||
}
|
||||
|
||||
// get rule identified by the given rule node reference
|
||||
@@ -135,7 +145,7 @@ public class RuleGet extends DeclarativeWebScript
|
||||
|
||||
// add objects to model for the template to render
|
||||
model.put(MODEL_PROP_KEY_RULE, rule);
|
||||
model.put(MODEL_PROP_KEY_OWNING_NODE_REF, ruleOwningNodeRef);
|
||||
model.put(MODEL_PROP_KEY_OWNING_NODE_REF, ruleOwningNodeRef.toString());
|
||||
|
||||
return model;
|
||||
}
|
||||
|
@@ -39,6 +39,16 @@ import org.json.JSONObject;
|
||||
/**
|
||||
* Web Script to PUT (update) the rule identified by the given rule node reference.
|
||||
*
|
||||
* NOTE -
|
||||
* that if a value is provided for the 'id' URL template variable {id},
|
||||
* i.e. either of the following URL patterns have been used
|
||||
* <url>/api/node/{store_type}/{store_id}/{id}/rules/{rule_id}</url> or
|
||||
* <url>/api/path/{store_type}/{store_id}/{id}/rules/{rule_id}</url>
|
||||
* then the rule owning node ref supplied therein will be ignored,
|
||||
* as these URL templates are just provided for convenience and the
|
||||
* rule owning node ref is retrieved by using the rule's identifying node
|
||||
* ref (supplied in {rule_id})
|
||||
*
|
||||
* @author glen johnson at alfresco dot com
|
||||
*/
|
||||
public class RulePut extends DeclarativeWebScript
|
||||
@@ -46,10 +56,11 @@ public class RulePut extends DeclarativeWebScript
|
||||
// private constants
|
||||
private static final String REQ_TEMPL_VAR_STORE_TYPE = "store_type";
|
||||
private static final String REQ_TEMPL_VAR_STORE_ID = "store_id";
|
||||
private static final String REQ_TEMPL_VAR_RULE_NODE_ID = "id";
|
||||
private static final String REQ_TEMPL_VAR_RULE_NODE_ID = "rule_id";
|
||||
|
||||
// model property keys
|
||||
private static final String MODEL_PROP_KEY_RULE = "rule";
|
||||
private static final String MODEL_PROP_KEY_OWNING_NODE_REF = "owningNodeRef";
|
||||
|
||||
// properties for services
|
||||
private RuleService ruleService;
|
||||
@@ -120,6 +131,14 @@ public class RulePut extends DeclarativeWebScript
|
||||
// URL template tokens
|
||||
NodeRef ruleNodeRef = this.rulesHelper.getNodeRefFromWebScriptUrl(req, storeType, storeId, ruleNodeId);
|
||||
|
||||
// if ruleNodeRef referred to by {store_type} {store_id} {rule_id} is 'null' then the rule identified by that
|
||||
// given node id or node path no longer exists
|
||||
if (ruleNodeRef == null)
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_NOT_FOUND, "Rule identified by rule node/path - 'store_type': "
|
||||
+ storeType + " 'store_id': " + storeId + " and 'rule_id': " + ruleNodeId + " could not be found");
|
||||
}
|
||||
|
||||
// get the rule JSON object sent in the request content (when PUTting the Rule)
|
||||
Object contentObj = req.parseContent();
|
||||
if (contentObj == null || !(contentObj instanceof JSONObject))
|
||||
@@ -129,19 +148,20 @@ public class RulePut extends DeclarativeWebScript
|
||||
}
|
||||
JSONObject ruleJson = (JSONObject)contentObj;
|
||||
|
||||
// get the rule object (identified by the rule node reference)
|
||||
// updated by the details in the rule JSON object
|
||||
// update the rule object identified by the given rule node reference
|
||||
// with the details in the rule JSON
|
||||
Rule rule = this.rulesHelper.getRuleFromJson(ruleJson, ruleNodeRef);
|
||||
|
||||
// get owning node ref that rule was
|
||||
// previous applied to
|
||||
NodeRef owningNodeRef = this.ruleService.getOwningNodeRef(rule);
|
||||
NodeRef ruleOwningNodeRef = this.ruleService.getOwningNodeRef(rule);
|
||||
|
||||
// re-apply rule to actionable node
|
||||
this.ruleService.saveRule(owningNodeRef, rule);
|
||||
// re-apply rule to owning node
|
||||
this.ruleService.saveRule(ruleOwningNodeRef, rule);
|
||||
|
||||
// add objects to model for the template to render
|
||||
model.put(MODEL_PROP_KEY_RULE, rule);
|
||||
model.put(MODEL_PROP_KEY_OWNING_NODE_REF, ruleOwningNodeRef.toString());
|
||||
|
||||
return model;
|
||||
}
|
||||
|
@@ -25,9 +25,11 @@
|
||||
package org.alfresco.repo.web.scripts.rule;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.action.evaluator.CompareMimeTypeEvaluator;
|
||||
import org.alfresco.repo.action.evaluator.ComparePropertyValueEvaluator;
|
||||
import org.alfresco.repo.action.executer.CompositeActionExecuter;
|
||||
import org.alfresco.repo.action.executer.CopyActionExecuter;
|
||||
@@ -36,7 +38,6 @@ import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.repo.web.scripts.BaseWebScriptTest;
|
||||
import org.alfresco.service.cmr.action.ActionService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.rule.RuleType;
|
||||
@@ -49,6 +50,7 @@ import org.alfresco.web.scripts.Status;
|
||||
import org.alfresco.web.scripts.TestWebScriptServer.DeleteRequest;
|
||||
import org.alfresco.web.scripts.TestWebScriptServer.GetRequest;
|
||||
import org.alfresco.web.scripts.TestWebScriptServer.PostRequest;
|
||||
import org.alfresco.web.scripts.TestWebScriptServer.PutRequest;
|
||||
import org.alfresco.web.scripts.TestWebScriptServer.Response;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
@@ -65,16 +67,17 @@ public class RuleServiceTest extends BaseWebScriptTest
|
||||
private AuthenticationComponent authenticationComponent;
|
||||
private NodeService nodeService;
|
||||
private PersonService personService;
|
||||
private ActionService actionService;
|
||||
|
||||
private NodeRef owningNodeRef1;
|
||||
private NodeRef testDestFolder1;
|
||||
private NodeRef testDestFolder2;
|
||||
|
||||
// private constants
|
||||
private static final String RULES_USER = "Rules.User";
|
||||
private static final String RULES_USER_PASSWORD = "password";
|
||||
private static final String RULES_TEST_OWNING_FOLDER_1 = "rulesTestOwningFolder1";
|
||||
private static final String RULES_TEST_DEST_FOLDER_1 = "rulesTestDestinationFolder1";
|
||||
private static final String RULES_TEST_DEST_FOLDER_2 = "rulesTestDestinationFolder2";
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception
|
||||
@@ -88,7 +91,6 @@ public class RuleServiceTest extends BaseWebScriptTest
|
||||
"AuthenticationComponent");
|
||||
this.nodeService = (NodeService) getServer().getApplicationContext().getBean("NodeService");
|
||||
this.personService = (PersonService) getServer().getApplicationContext().getBean("PersonService");
|
||||
this.actionService = (ActionService) getServer().getApplicationContext().getBean("ActionService");
|
||||
|
||||
//
|
||||
// various setup operations which need to be run as system user
|
||||
@@ -117,6 +119,9 @@ public class RuleServiceTest extends BaseWebScriptTest
|
||||
this.testDestFolder1 = this.nodeService.createNode(userHomeRef, ContentModel.ASSOC_CONTAINS,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, RULES_TEST_DEST_FOLDER_1),
|
||||
ContentModel.TYPE_FOLDER).getChildRef();
|
||||
this.testDestFolder2 = this.nodeService.createNode(userHomeRef, ContentModel.ASSOC_CONTAINS,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, RULES_TEST_DEST_FOLDER_2),
|
||||
ContentModel.TYPE_FOLDER).getChildRef();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -345,8 +350,14 @@ public class RuleServiceTest extends BaseWebScriptTest
|
||||
// Construct rule JSON object
|
||||
JSONObject rule = new JSONObject();
|
||||
|
||||
rule.put("owningNodeRef", owningNodeRef);
|
||||
rule.put("ruleNodeRef", ruleNodeRef);
|
||||
if (owningNodeRef != null)
|
||||
{
|
||||
rule.put("owningNodeRef", owningNodeRef.toString());
|
||||
}
|
||||
if (ruleNodeRef != null)
|
||||
{
|
||||
rule.put("ruleNodeRef", ruleNodeRef.toString());
|
||||
}
|
||||
rule.put("title", title);
|
||||
rule.put("description", description);
|
||||
rule.put("ruleTypes", new JSONArray(ruleTypes));
|
||||
@@ -421,9 +432,9 @@ public class RuleServiceTest extends BaseWebScriptTest
|
||||
// create nested action parameters
|
||||
JSONObject actionCopyParamsJson = new JSONObject();
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_ASSOC_QNAME,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "copy"));
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_DESTINATION_FOLDER, this.testDestFolder1);
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_ASSOC_TYPE_QNAME, ContentModel.ASSOC_CONTAINS);
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "copy").toString());
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_DESTINATION_FOLDER, this.testDestFolder1.toString());
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_ASSOC_TYPE_QNAME, ContentModel.ASSOC_CONTAINS.toString());
|
||||
|
||||
// create nested actions
|
||||
JSONObject actionCopyJson = getActionJsonObject(null, CopyActionExecuter.NAME, "CopyTitle", "CopyDesc", false,
|
||||
@@ -485,9 +496,9 @@ public class RuleServiceTest extends BaseWebScriptTest
|
||||
// create nested action parameters
|
||||
JSONObject actionCopyParamsJson = new JSONObject();
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_ASSOC_QNAME,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "copy"));
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_DESTINATION_FOLDER, this.testDestFolder1);
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_ASSOC_TYPE_QNAME, ContentModel.ASSOC_CONTAINS);
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "copy").toString());
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_DESTINATION_FOLDER, this.testDestFolder1.toString());
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_ASSOC_TYPE_QNAME, ContentModel.ASSOC_CONTAINS.toString());
|
||||
|
||||
// create nested action
|
||||
JSONObject actionCopyJson = getActionJsonObject(null, CopyActionExecuter.NAME, "CopyTitle", "CopyDesc", false,
|
||||
@@ -527,6 +538,7 @@ public class RuleServiceTest extends BaseWebScriptTest
|
||||
sendRequest(new GetRequest(url), Status.STATUS_NOT_FOUND);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testGetRule() throws Exception
|
||||
{
|
||||
//
|
||||
@@ -538,7 +550,7 @@ public class RuleServiceTest extends BaseWebScriptTest
|
||||
JSONObject condCompMimeTypeParams = new JSONObject();
|
||||
condCompMimeTypeParams.put(ComparePropertyValueEvaluator.PARAM_VALUE, "image/png");
|
||||
|
||||
// create conditions
|
||||
// create conditions JSON array
|
||||
JSONObject conditionCompMimeType = getConditionJsonObject(null, condCompMimeTypeParams, "compare-mime-type", false, null);
|
||||
JSONArray conditions = new JSONArray();
|
||||
conditions.put(conditionCompMimeType);
|
||||
@@ -546,9 +558,9 @@ public class RuleServiceTest extends BaseWebScriptTest
|
||||
// create parameters for nested actions
|
||||
JSONObject actionCopyParamsJson = new JSONObject();
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_ASSOC_QNAME,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "copy"));
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_DESTINATION_FOLDER, this.testDestFolder1);
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_ASSOC_TYPE_QNAME, ContentModel.ASSOC_CONTAINS);
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "copy").toString());
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_DESTINATION_FOLDER, this.testDestFolder1.toString());
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_ASSOC_TYPE_QNAME, ContentModel.ASSOC_CONTAINS.toString());
|
||||
|
||||
// create nested actions
|
||||
JSONObject actionCopyJson = getActionJsonObject(null, CopyActionExecuter.NAME, "CopyTitle", "CopyDesc", false,
|
||||
@@ -556,15 +568,15 @@ public class RuleServiceTest extends BaseWebScriptTest
|
||||
JSONArray nestedActions = new JSONArray();
|
||||
nestedActions.put(actionCopyJson);
|
||||
|
||||
// create rule's composite action
|
||||
JSONObject compoActionJson = getActionJsonObject(null, CompositeActionExecuter.NAME, "Rule1Action", "Rule1ActionDesc",
|
||||
// create rule's root action
|
||||
JSONObject ruleActionJson = getActionJsonObject(null, CompositeActionExecuter.NAME, "Rule1Action", "Rule1ActionDesc",
|
||||
false, null, conditions, nestedActions, null, null);
|
||||
|
||||
// create rule to POST
|
||||
// create rule JSON
|
||||
List<String> ruleTypes = new ArrayList<String>();
|
||||
ruleTypes.add(RuleType.UPDATE);
|
||||
JSONObject ruleJson = getRuleJsonObject(this.owningNodeRef1, null, "Rule1", "Rule1Desc", ruleTypes,
|
||||
compoActionJson, false, false, false, null);
|
||||
JSONObject ruleJson = getRuleJsonObject(null, null, "Rule1", "Rule1Desc", ruleTypes,
|
||||
ruleActionJson, false, false, false, null);
|
||||
|
||||
// POST rule JSON to rules collection resource
|
||||
JSONObject resultPostRule = postRules(this.owningNodeRef1, ruleJson);
|
||||
@@ -583,9 +595,106 @@ public class RuleServiceTest extends BaseWebScriptTest
|
||||
Response response = sendRequest(new GetRequest(getRuleRulesBasedUrl), Status.STATUS_OK);
|
||||
JSONObject resultGetRule = new JSONObject(response.getContentAsString());
|
||||
|
||||
String resultRuleNodeRefStr = resultGetRule.getString("ruleNodeRef");
|
||||
//
|
||||
// validate properties returned in GET Rule response
|
||||
//
|
||||
|
||||
assertEquals(ruleNodeRefStr, resultRuleNodeRefStr);
|
||||
//
|
||||
// check rule properties
|
||||
//
|
||||
assertEquals(this.owningNodeRef1.toString(), resultGetRule.getString("owningNodeRef"));
|
||||
assertEquals(ruleNodeRefStr, resultGetRule.getString("ruleNodeRef"));
|
||||
assertEquals("Rule1", resultGetRule.getString("title"));
|
||||
assertEquals("Rule1Desc", resultGetRule.getString("description"));
|
||||
assertEquals(false, resultGetRule.getBoolean("executeAsync"));
|
||||
assertEquals(false, resultGetRule.getBoolean("ruleDisabled"));
|
||||
assertEquals(false, resultGetRule.getBoolean("appliedToChildren"));
|
||||
|
||||
//
|
||||
// check rule types
|
||||
//
|
||||
JSONArray resultRuleTypes = resultGetRule.getJSONArray("ruleTypes");
|
||||
assertEquals(1, resultRuleTypes.length());
|
||||
assertEquals(RuleType.UPDATE, resultRuleTypes.getString(0));
|
||||
|
||||
// retrieve ID for copy action
|
||||
JSONObject resultRuleAction = resultGetRule.getJSONObject("action");
|
||||
JSONObject resultNestedActions = resultRuleAction.getJSONObject("actions");
|
||||
Iterator<String> actionKeysIter = resultNestedActions.keys();
|
||||
String resultCopyActionID = null;
|
||||
while (actionKeysIter.hasNext())
|
||||
{
|
||||
String key = actionKeysIter.next();
|
||||
|
||||
JSONObject resultAction = resultNestedActions.getJSONObject(key);
|
||||
String actionDefName = resultAction.getString("actionDefinitionName");
|
||||
|
||||
if (actionDefName.equals(CopyActionExecuter.NAME))
|
||||
{
|
||||
resultCopyActionID = resultAction.getString("id");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assertNotNull(resultCopyActionID);
|
||||
|
||||
// retrieve copy action
|
||||
JSONObject resCopyAction = resultNestedActions.getJSONObject(resultCopyActionID);
|
||||
|
||||
//
|
||||
// check copy action properties
|
||||
//
|
||||
assertEquals(CopyActionExecuter.NAME, resCopyAction.getString("actionDefinitionName"));
|
||||
assertEquals("CopyTitle", resCopyAction.getString("title"));
|
||||
assertEquals("CopyDesc" , resCopyAction.getString("description"));
|
||||
assertEquals(false, resCopyAction.getBoolean("executeAsync"));
|
||||
|
||||
//
|
||||
// check copy action parameters
|
||||
//
|
||||
JSONObject resCopyActionParams = resCopyAction.getJSONObject("parameterValues");
|
||||
assertEquals(QName.createQName(
|
||||
NamespaceService.CONTENT_MODEL_1_0_URI, "copy").toString(),
|
||||
resCopyActionParams.getString(MoveActionExecuter.PARAM_ASSOC_QNAME));
|
||||
assertEquals(this.testDestFolder1.toString(), resCopyActionParams.getString(MoveActionExecuter.PARAM_DESTINATION_FOLDER));
|
||||
assertEquals(ContentModel.ASSOC_CONTAINS.toString(), resCopyActionParams.getString(MoveActionExecuter.PARAM_ASSOC_TYPE_QNAME));
|
||||
|
||||
// retrieve ID for compare MIME-type condition
|
||||
JSONObject resultConditions = resultRuleAction.getJSONObject("conditions");
|
||||
Iterator<String> condKeysIter = resultConditions.keys();
|
||||
String resultCondCompMimeTypeID = null;
|
||||
while (condKeysIter.hasNext())
|
||||
{
|
||||
String key = condKeysIter.next();
|
||||
|
||||
JSONObject resultCondition = resultConditions.getJSONObject(key);
|
||||
String condDefName = resultCondition.getString("conditionDefinitionName");
|
||||
|
||||
if (condDefName.equals(CompareMimeTypeEvaluator.NAME))
|
||||
{
|
||||
resultCondCompMimeTypeID = resultCondition.getString("id");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assertNotNull(resultCondCompMimeTypeID);
|
||||
|
||||
//
|
||||
// retrieve compare MIME-type condition
|
||||
//
|
||||
JSONObject resCompMimeTypeCond = resultConditions.getJSONObject(resultCondCompMimeTypeID);
|
||||
|
||||
//
|
||||
// check compare MIME type condition's properties
|
||||
//
|
||||
assertEquals(CompareMimeTypeEvaluator.NAME, resCompMimeTypeCond.getString("conditionDefinitionName"));
|
||||
assertEquals(false, resCompMimeTypeCond.getBoolean("invertCondition"));
|
||||
|
||||
//
|
||||
// retrieve compare MIME-type condition's parameter JSON and check its value
|
||||
//
|
||||
JSONObject resCondCmpMimeTypeParams = resCompMimeTypeCond.getJSONObject("parameterValues");
|
||||
assertEquals("image/png", resCondCmpMimeTypeParams.getString(ComparePropertyValueEvaluator.PARAM_VALUE));
|
||||
}
|
||||
|
||||
public void testGetRules() throws Exception
|
||||
@@ -606,9 +715,9 @@ public class RuleServiceTest extends BaseWebScriptTest
|
||||
// create parameters for nested actions
|
||||
JSONObject actionCopyParamsJson = new JSONObject();
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_ASSOC_QNAME,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "copy"));
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_DESTINATION_FOLDER, this.testDestFolder1);
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_ASSOC_TYPE_QNAME, ContentModel.ASSOC_CONTAINS);
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "copy").toString());
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_DESTINATION_FOLDER, this.testDestFolder1.toString());
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_ASSOC_TYPE_QNAME, ContentModel.ASSOC_CONTAINS.toString());
|
||||
|
||||
// create nested actions
|
||||
JSONObject actionCopyJson = getActionJsonObject(null, CopyActionExecuter.NAME, "CopyTitle", "CopyDesc", false,
|
||||
@@ -650,8 +759,234 @@ public class RuleServiceTest extends BaseWebScriptTest
|
||||
assertTrue(postedRuleFound == true);
|
||||
}
|
||||
|
||||
public void testPostRules()
|
||||
throws Exception
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testPutRule() throws Exception
|
||||
{
|
||||
// -------------------------
|
||||
// Create a Rule - POST Rule
|
||||
// -------------------------
|
||||
|
||||
// create condition parameters
|
||||
JSONObject condCompMimeTypeParams = new JSONObject();
|
||||
condCompMimeTypeParams.put(ComparePropertyValueEvaluator.PARAM_VALUE, "image/png");
|
||||
|
||||
//
|
||||
// create conditions JSON
|
||||
//
|
||||
JSONObject conditionCompMimeType = getConditionJsonObject(null, condCompMimeTypeParams, "compare-mime-type", false, null);
|
||||
JSONArray conditions = new JSONArray();
|
||||
conditions.put(conditionCompMimeType);
|
||||
|
||||
//
|
||||
// create parameters for nested actions JSON
|
||||
//
|
||||
JSONObject actionCopyParamsJson = new JSONObject();
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_ASSOC_QNAME,
|
||||
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "copy").toString());
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_DESTINATION_FOLDER, this.testDestFolder1.toString());
|
||||
actionCopyParamsJson.put(MoveActionExecuter.PARAM_ASSOC_TYPE_QNAME, ContentModel.ASSOC_CONTAINS.toString());
|
||||
|
||||
//
|
||||
// create nested actions JSON
|
||||
//
|
||||
JSONObject actionCopyJson = getActionJsonObject(null, CopyActionExecuter.NAME, "CopyTitle", "CopyDesc", false,
|
||||
actionCopyParamsJson, null, null, null, null);
|
||||
JSONArray nestedActions = new JSONArray();
|
||||
nestedActions.put(actionCopyJson);
|
||||
|
||||
//
|
||||
// create rule's composite action JSON
|
||||
//
|
||||
JSONObject compoActionJson = getActionJsonObject(null, CompositeActionExecuter.NAME, "Rule1Action", "Rule1ActionDesc",
|
||||
false, null, conditions, nestedActions, null, null);
|
||||
|
||||
//
|
||||
// create rule to POST JSON
|
||||
//
|
||||
List<String> ruleTypes = new ArrayList<String>();
|
||||
ruleTypes.add(RuleType.UPDATE);
|
||||
JSONObject ruleJson = getRuleJsonObject(this.owningNodeRef1, null, "Rule", "RuleDesc", ruleTypes,
|
||||
compoActionJson, false, false, false, null);
|
||||
|
||||
//
|
||||
// POST rule JSON to rules collection resource JSON
|
||||
//
|
||||
JSONObject resultRuleJson = postRules(this.owningNodeRef1, ruleJson);
|
||||
|
||||
// get the rule node ref from the rule details returned so that
|
||||
// we can retrieve the rule later
|
||||
String ruleNodeRefStr = resultRuleJson.getString("ruleNodeRef");
|
||||
NodeRef ruleNodeRef = new NodeRef(ruleNodeRefStr);
|
||||
|
||||
// --------------------------
|
||||
// Update the Rule - PUT Rule
|
||||
// --------------------------
|
||||
|
||||
// create parameter for compare MIME-type condition with updated parameter value
|
||||
JSONObject putCondCompMimeTypeParams = new JSONObject();
|
||||
putCondCompMimeTypeParams.put(ComparePropertyValueEvaluator.PARAM_VALUE, "image/jpeg");
|
||||
|
||||
// retrieve ID for compare MIME-type condition
|
||||
JSONObject resultRuleAction = resultRuleJson.getJSONObject("action");
|
||||
JSONObject resultConditions = resultRuleAction.getJSONObject("conditions");
|
||||
Iterator<String> condKeysIter = resultConditions.keys();
|
||||
String resultCondCompMimeTypeID = null;
|
||||
while (condKeysIter.hasNext())
|
||||
{
|
||||
String key = condKeysIter.next();
|
||||
|
||||
JSONObject resultCondition = resultConditions.getJSONObject(key);
|
||||
String condDefName = resultCondition.getString("conditionDefinitionName");
|
||||
|
||||
if (condDefName.equals("compare-mime-type"))
|
||||
{
|
||||
resultCondCompMimeTypeID = resultCondition.getString("id");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assertNotNull(resultCondCompMimeTypeID);
|
||||
|
||||
// create compare MIME-type condition with updated condition parameters and updated properties
|
||||
JSONObject putConditionCompMimeType = new JSONObject();
|
||||
putConditionCompMimeType.put("id", resultCondCompMimeTypeID);
|
||||
putConditionCompMimeType.put("parameterValues", putCondCompMimeTypeParams);
|
||||
putConditionCompMimeType.put("conditionDefinitionName", "compare-mime-type");
|
||||
putConditionCompMimeType.put("invertCondition", true);
|
||||
|
||||
// create conditions JSON array and add updated compare MIME-type condition
|
||||
JSONArray putConditions = new JSONArray();
|
||||
putConditions.put(putConditionCompMimeType);
|
||||
|
||||
// create parameters for copy action JSON with updated parameter values
|
||||
JSONObject putCopyActionParams = new JSONObject();
|
||||
putCopyActionParams.put(MoveActionExecuter.PARAM_DESTINATION_FOLDER, this.testDestFolder2.toString());
|
||||
|
||||
// retrieve ID for copy action
|
||||
JSONObject resultActions = resultRuleAction.getJSONObject("actions");
|
||||
Iterator<String> actionKeysIter = resultActions.keys();
|
||||
String resultCopyActionID = null;
|
||||
while (actionKeysIter.hasNext())
|
||||
{
|
||||
String key = actionKeysIter.next();
|
||||
|
||||
JSONObject resultAction = resultActions.getJSONObject(key);
|
||||
String actionDefName = resultAction.getString("actionDefinitionName");
|
||||
|
||||
if (actionDefName.equals(CopyActionExecuter.NAME))
|
||||
{
|
||||
resultCopyActionID = resultAction.getString("id");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assertNotNull(resultCopyActionID);
|
||||
|
||||
// create copy action with updated action parameters and updated properties
|
||||
JSONObject putCopyAction = new JSONObject();
|
||||
putCopyAction.put("id", resultCopyActionID);
|
||||
putCopyAction.put("actionDefinitionName", CopyActionExecuter.NAME);
|
||||
putCopyAction.put("title", "CopyTitleUpdated");
|
||||
putCopyAction.put("description", "CopyDescUpdated");
|
||||
putCopyAction.put("executeAsync", true);
|
||||
putCopyAction.put("parameterValues", putCopyActionParams);
|
||||
|
||||
// create nested actions JSON array and add updated copy action
|
||||
JSONArray putNestedActions = new JSONArray();
|
||||
putNestedActions.put(putCopyAction);
|
||||
|
||||
// create rule action JSON (root action) with updated properties, conditions and nested actions
|
||||
JSONObject putRuleAction = new JSONObject();
|
||||
putRuleAction.put("id", resultRuleAction.getString("id"));
|
||||
putRuleAction.put("actionDefinitionName", CompositeActionExecuter.NAME);
|
||||
putRuleAction.put("actions", putNestedActions);
|
||||
putRuleAction.put("conditions", putConditions);
|
||||
|
||||
// create updated rule types JSON array
|
||||
JSONArray putRuleTypes = new JSONArray();
|
||||
putRuleTypes.put(RuleType.INBOUND);
|
||||
|
||||
// create rule JSON with updated composite action, updated rule types and updated rule properties
|
||||
JSONObject putRuleJson = new JSONObject();
|
||||
putRuleJson.put("title", "RuleTitleUpdated");
|
||||
putRuleJson.put("description", "RuleDescUpdated");
|
||||
putRuleJson.put("ruleTypes", putRuleTypes);
|
||||
putRuleJson.put("action", putRuleAction);
|
||||
putRuleJson.put("executeAsync", true);
|
||||
putRuleJson.put("ruleDisabled", true);
|
||||
|
||||
//
|
||||
// update rule resource with updated rule JSON with PUT Rule
|
||||
//
|
||||
|
||||
String url = "/api/rules/" + ruleNodeRef.getStoreRef().getProtocol() + "/"
|
||||
+ ruleNodeRef.getStoreRef().getIdentifier() + "/" + ruleNodeRef.getId();
|
||||
|
||||
sendRequest(new PutRequest(url, putRuleJson.toString(), "application/json"),
|
||||
Status.STATUS_OK);
|
||||
|
||||
// -----------------------------------------------
|
||||
// Get the updated Rule - GET Rule
|
||||
// and validate that the response thereof contains
|
||||
// the updated field values
|
||||
// -----------------------------------------------
|
||||
|
||||
//
|
||||
// get the updated rule
|
||||
//
|
||||
Response responseGetRule = sendRequest(new GetRequest(url), Status.STATUS_OK);
|
||||
JSONObject resGetRule = new JSONObject(responseGetRule.getContentAsString());
|
||||
|
||||
//
|
||||
// check updated rule fields
|
||||
//
|
||||
assertEquals("RuleTitleUpdated", resGetRule.getString("title"));
|
||||
assertEquals("RuleDescUpdated", resGetRule.getString("description"));
|
||||
assertEquals(true, resGetRule.getBoolean("executeAsync"));
|
||||
assertEquals(true, resGetRule.getBoolean("ruleDisabled"));
|
||||
|
||||
//
|
||||
// retrieve updated copy action
|
||||
//
|
||||
JSONObject resRuleAction = resGetRule.getJSONObject("action");
|
||||
JSONObject resNestedActions = resRuleAction.getJSONObject("actions");
|
||||
String copyActionId = putCopyAction.getString("id");
|
||||
JSONObject resCopyAction = resNestedActions.getJSONObject(copyActionId);
|
||||
|
||||
//
|
||||
// check updated copy action fields
|
||||
//
|
||||
assertEquals(CopyActionExecuter.NAME, resCopyAction.getString("actionDefinitionName"));
|
||||
assertEquals("CopyTitleUpdated", resCopyAction.getString("title"));
|
||||
assertEquals("CopyDescUpdated" , resCopyAction.getString("description"));
|
||||
assertEquals(true, resCopyAction.getBoolean("executeAsync"));
|
||||
|
||||
//
|
||||
// check updated copy action parameters
|
||||
//
|
||||
JSONObject resCopyActionParams = resCopyAction.getJSONObject("parameterValues");
|
||||
assertEquals(this.testDestFolder2.toString(), resCopyActionParams.getString(MoveActionExecuter.PARAM_DESTINATION_FOLDER));
|
||||
|
||||
//
|
||||
// retrieve updated compare MIME-type condition
|
||||
//
|
||||
JSONObject resConditions = resRuleAction.getJSONObject("conditions");
|
||||
String compMimeTypeCondId = putConditionCompMimeType.getString("id");
|
||||
JSONObject resCompMimeTypeCond = resConditions.getJSONObject(compMimeTypeCondId);
|
||||
|
||||
//
|
||||
// check updated compare MIME type condition's fields
|
||||
//
|
||||
assertEquals(true, resCompMimeTypeCond.getBoolean("invertCondition"));
|
||||
|
||||
//
|
||||
// retrieve compare MIME-type condition's parameter JSON and check its value
|
||||
//
|
||||
JSONObject resCondCmpMimeTypeParams = resCompMimeTypeCond.getJSONObject("parameterValues");
|
||||
assertEquals("image/jpeg", resCondCmpMimeTypeParams.getString(ComparePropertyValueEvaluator.PARAM_VALUE));
|
||||
}
|
||||
|
||||
public void testPostRules() throws Exception
|
||||
{
|
||||
// create condition parameters for compare MIME type condition
|
||||
JSONObject condCompMimeTypeParams = new JSONObject();
|
||||
@@ -692,8 +1027,6 @@ public class RuleServiceTest extends BaseWebScriptTest
|
||||
// validate rule result
|
||||
//
|
||||
|
||||
NodeRef resultRuleNodeRef = new NodeRef(resultRule.getString("ruleNodeRef"));
|
||||
|
||||
assertEquals(this.owningNodeRef1.toString(), resultRule.getString("owningNodeRef"));
|
||||
assertEquals("Rule1", resultRule.getString("title"));
|
||||
assertEquals("Rule1Desc", resultRule.getString("description"));
|
||||
@@ -800,8 +1133,6 @@ public class RuleServiceTest extends BaseWebScriptTest
|
||||
JSONArray result = new JSONArray(response.getContentAsString());
|
||||
|
||||
assertTrue(result.length() > 0);
|
||||
|
||||
System.out.println(result);
|
||||
}
|
||||
|
||||
public void testGetConditionDef() throws Exception
|
||||
|
@@ -155,7 +155,7 @@ public class RulesGet extends DeclarativeWebScript
|
||||
|
||||
// add objects to model for the template to render
|
||||
model.put(MODEL_PROP_KEY_RULES, rules);
|
||||
model.put(MODEL_PROP_KEY_OWNING_NODE_REF, owningNodeRef);
|
||||
model.put(MODEL_PROP_KEY_OWNING_NODE_REF, owningNodeRef.toString());
|
||||
|
||||
return model;
|
||||
}
|
||||
|
@@ -171,30 +171,48 @@ public class RulesHelper
|
||||
rule = new Rule();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//
|
||||
// set rule properties
|
||||
//
|
||||
|
||||
try
|
||||
{
|
||||
if ((ruleJson.isNull("title") == true) && (update == false))
|
||||
{
|
||||
// the "title" field is mandatory, it is missing in the rule details,
|
||||
// and we are creating a new rule, so throw an exception
|
||||
// the "title" field is missing in the rule details,
|
||||
// and we are creating a new rule,
|
||||
// but the "title" field is mandatory, so throw an exception
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "A new rule is being created but the 'title' "
|
||||
+ "field, which is mandatory, has not been included in the rule details");
|
||||
}
|
||||
// otherwise go ahead and set the value if the field is present
|
||||
// otherwise just go ahead and set the value if the field is present
|
||||
// to over both creating and updating scenarios
|
||||
else if (ruleJson.isNull("title") == false)
|
||||
{
|
||||
String ruleTitle = ruleJson.getString("title");
|
||||
rule.setTitle(ruleTitle);
|
||||
}
|
||||
}
|
||||
catch (JSONException je)
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "There was a problem reading the 'title' property "
|
||||
+ "in the received Rule JSON. It may contain invalid characters", je);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (ruleJson.isNull("description") == false)
|
||||
{
|
||||
rule.setDescription(ruleJson.getString("description"));
|
||||
}
|
||||
}
|
||||
catch (JSONException je)
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "There was a problem reading the 'description' property "
|
||||
+ "in the received Rule JSON. It may contain invalid characters. The title of the offending rule is '"
|
||||
+ ruleJson.optString("title") + "'", je);
|
||||
}
|
||||
|
||||
|
||||
// set values from the respective Boolean fields below, but if the
|
||||
// if the value given for a field does not equate to either
|
||||
@@ -221,12 +239,15 @@ public class RulesHelper
|
||||
// set rule types present in the rule details onto the rule
|
||||
//
|
||||
|
||||
try
|
||||
{
|
||||
if ((ruleJson.isNull("ruleTypes") == true) && (update == false))
|
||||
{
|
||||
// the "ruleTypes" field is mandatory, it is missing in the rule details,
|
||||
// and we are creating a new rule so throw an exception
|
||||
// the "ruleTypes" field is mandatory for rule creation. it is missing in the rule details
|
||||
// from which we are creating a new rule, so throw an exception
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "A new rule is being created but the 'ruleTypes' "
|
||||
+ "field, which is mandatory, has not been included in the rule details");
|
||||
+ "property, which is mandatory, has not been included in the rule details. The title of the "
|
||||
+ "offending rule is '" + ruleJson.optString("title") + "'");
|
||||
}
|
||||
else if (ruleJson.isNull("ruleTypes") == false)
|
||||
{
|
||||
@@ -238,7 +259,8 @@ public class RulesHelper
|
||||
if (numRuleTypes < 1)
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "At least one rule type needs to be present in "
|
||||
+ "in the rule details sent in the request content.");
|
||||
+ "in the rule details sent in the request content. The title of the "
|
||||
+ "offending rule is '" + ruleJson.optString("title") + "'");
|
||||
}
|
||||
|
||||
// add to the rule the rule type names sent in the rule details
|
||||
@@ -253,23 +275,43 @@ public class RulesHelper
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "An invalid rule type name was given in the "
|
||||
+ "rule details sent in the request content. Invalid rule type name given is: '"
|
||||
+ ruleTypeNameJson + "'");
|
||||
+ ruleTypeNameJson + "'. The title of the offending rule containing the invalid rule type "
|
||||
+ "is '" + ruleJson.optString("title") + "'");
|
||||
}
|
||||
}
|
||||
rule.setRuleTypes(ruleTypes);
|
||||
}
|
||||
}
|
||||
catch (JSONException je)
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "There was a problem reading the 'ruleTypes' "
|
||||
+ "property in the received Rule JSON. It may not be a JSON Array or one of the rule types "
|
||||
+ "therein may contain invalid characters. The title of the offending rule is '"
|
||||
+ ruleJson.optString("title") + "'", je);
|
||||
}
|
||||
|
||||
if ((ruleJson.isNull("action") == true) && (update == false))
|
||||
{
|
||||
// the "action" field is mandatory, it is missing in the rule details,
|
||||
// and we are creating a new rule so throw an exception
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "A new rule is being created but the 'action' "
|
||||
+ "field, which is mandatory, has not been included in the rule details");
|
||||
+ "field, which is mandatory, has not been included in the rule details. The title of the "
|
||||
+ "offending rule is '" + ruleJson.optString("title") + "'");
|
||||
}
|
||||
else
|
||||
{
|
||||
// set the action supplied in the rule details onto the rule
|
||||
JSONObject ruleActionJson = ruleJson.getJSONObject("action");
|
||||
JSONObject ruleActionJson;
|
||||
try
|
||||
{
|
||||
ruleActionJson = ruleJson.getJSONObject("action");
|
||||
}
|
||||
catch (JSONException je)
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "There was a problem reading the 'action' "
|
||||
+ "property in the received rule JSON. It is mandatory and may be missing from the "
|
||||
+ "rule JSON. The title of the offending rule is '" + ruleJson.optString("title") + "'", je);
|
||||
}
|
||||
|
||||
// if we're doing an update then the rule should already have
|
||||
// this action set on it, so get the action object already on
|
||||
@@ -277,7 +319,19 @@ public class RulesHelper
|
||||
Action ruleActionToUpdate = null;
|
||||
if (update == true)
|
||||
{
|
||||
String ruleActionJsonId = ruleActionJson.getString("id");
|
||||
String ruleActionJsonId;
|
||||
try
|
||||
{
|
||||
ruleActionJsonId = ruleActionJson.getString("id");
|
||||
}
|
||||
catch (JSONException je)
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "There was a problem reading the 'id' "
|
||||
+ "property in the rule's root action from the received rule JSON. It is mandatory when "
|
||||
+ "updating a rule and may be missing from the received rule JSON. The title of the "
|
||||
+ "offending rule is '" + ruleJson.optString("title") + "'", je);
|
||||
}
|
||||
|
||||
ruleActionToUpdate = rule.getAction();
|
||||
|
||||
// throw a web script exception if the ID of the rule's action,
|
||||
@@ -299,12 +353,6 @@ public class RulesHelper
|
||||
Action action = getActionFromJson(ruleActionJson, ruleActionToUpdate);
|
||||
rule.setAction(action);
|
||||
}
|
||||
}
|
||||
catch (JSONException je)
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
|
||||
"Problem creating rule from Rule Details sent in the request content.", je);
|
||||
}
|
||||
|
||||
return rule;
|
||||
}
|
||||
@@ -316,7 +364,8 @@ public class RulesHelper
|
||||
* then this indicates that this action is to be updated from the action details
|
||||
* provided in the given JSON object and then returned.
|
||||
* If a 'null' is passed into this parameter, then this indicates that a new action is to
|
||||
* be created from scratch and returned.
|
||||
* be created from scratch, populated with the action details provided in the given JSON object
|
||||
* and then returned.
|
||||
*
|
||||
* @param actionJson the action JSON object used to create/update the action with
|
||||
* @param actionToUpdate The action to be updated.
|
||||
@@ -324,7 +373,6 @@ public class RulesHelper
|
||||
*
|
||||
* @return The action created/updated from the given action JSON object
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Action getActionFromJson(JSONObject actionJson, Action actionToUpdate)
|
||||
{
|
||||
ActionService actionService = this.serviceRegistry.getActionService();
|
||||
@@ -336,32 +384,47 @@ public class RulesHelper
|
||||
//
|
||||
|
||||
Action action = null;
|
||||
boolean updateAction = false;
|
||||
|
||||
// if an action has been given to update with fields present in the given action
|
||||
// JSON object, then set that action to the current action, and set the updateAction
|
||||
// indicator to true
|
||||
if (actionToUpdate != null)
|
||||
{
|
||||
action = actionToUpdate;
|
||||
updateAction = true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//
|
||||
// create an action object from an "action" JSON object
|
||||
//
|
||||
|
||||
String actionDefinitionName = actionJson.getString("actionDefinitionName");
|
||||
String actionDefinitionName;
|
||||
try
|
||||
{
|
||||
actionDefinitionName = actionJson.getString("actionDefinitionName");
|
||||
}
|
||||
catch (JSONException je)
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "There was a problem reading the "
|
||||
+ "'actionDefinitionName' property from the the received action JSON. It is mandatory "
|
||||
+ "and may be missing from the received action JSON. The 'title' of the offending action is '"
|
||||
+ actionJson.optString("title") + "'", je);
|
||||
}
|
||||
JSONArray nestedActionsJson = actionJson.optJSONArray("actions");
|
||||
|
||||
// if action's definition name denotes that it is a composite action and the
|
||||
// action JSON object has nested actions, then treat it as a composite action
|
||||
if ((actionDefinitionName.equals(COMPOSITE_ACTION_DEF_NAME)) == true && (nestedActionsJson != null))
|
||||
{
|
||||
// if we are updating an existing action and the given
|
||||
// actionToUpdate is not a composite action, then throw a
|
||||
// web script exception
|
||||
if ((actionToUpdate != null) && ((actionToUpdate instanceof CompositeAction) == false))
|
||||
// if we are updating an action which is a composite action,
|
||||
// but the action definition name in the action JSON is not 'composite-action'
|
||||
// throw a web script exception
|
||||
if ((updateAction == true) && ((action instanceof CompositeAction) == false))
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "The action directly associated with the "
|
||||
+ "rule you wish to update is not a composite action. Thus this action could not be updated with "
|
||||
+ "the given action JSON - the action details sent");
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "The action you wish to update "
|
||||
+ "is not a composite action object, but the action definition name in the action JSON is "
|
||||
+ "'composite-action'. Thus this action could not be updated with the action JSON sent");
|
||||
}
|
||||
|
||||
// TODO remove this look-up map when the back-end provides an easy way to lookup actions
|
||||
@@ -370,7 +433,7 @@ public class RulesHelper
|
||||
// if we are updating an existing composite action then create a map to easily look up the
|
||||
// nested action objects for each nested action details provided in the action JSON object
|
||||
Map<String, Action> nestedActionsMap = new HashMap<String, Action>();
|
||||
if ((actionToUpdate != null) && ((actionToUpdate instanceof CompositeAction) == true))
|
||||
if ((updateAction == true) && ((action instanceof CompositeAction) == true))
|
||||
{
|
||||
List<Action> nestedActions = ((CompositeAction)action).getActions();
|
||||
for (Action nestedAction: nestedActions)
|
||||
@@ -380,7 +443,7 @@ public class RulesHelper
|
||||
}
|
||||
// else if we are not updating then create composite action object
|
||||
// for scratch
|
||||
else if (actionToUpdate == null)
|
||||
else if (updateAction == false)
|
||||
{
|
||||
action = actionService.createCompositeAction();
|
||||
}
|
||||
@@ -398,9 +461,20 @@ public class RulesHelper
|
||||
|
||||
// if we are doing an action update, then update the nested actions from
|
||||
// the nested action JSON
|
||||
if (actionToUpdate != null)
|
||||
if (updateAction == true)
|
||||
{
|
||||
String nestedActionJsonID = nestedActionJson.getString("id");
|
||||
String nestedActionJsonID;
|
||||
try
|
||||
{
|
||||
nestedActionJsonID = nestedActionJson.getString("id");
|
||||
}
|
||||
catch (JSONException je)
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "There was a problem reading the "
|
||||
+ "'id' property from the received action JSON. It is mandatory when updating an action"
|
||||
+ "and may be missing from the received action JSON. The 'title' of the offending action is '"
|
||||
+ nestedActionJson.optString("title") + "'", je);
|
||||
}
|
||||
|
||||
// lookup to see if nested action from nested action JSON
|
||||
// already exists on composite action, in which case, update
|
||||
@@ -409,9 +483,11 @@ public class RulesHelper
|
||||
Action nestedActionToUpdate = nestedActionsMap.get(nestedActionJsonID);
|
||||
if (nestedActionToUpdate != null)
|
||||
{
|
||||
// remove the existing nested action to then be updated below with the
|
||||
// updated one
|
||||
// first remove the nested action to be updated from the parent
|
||||
// composite action
|
||||
((CompositeAction)action).removeAction(nestedActionToUpdate);
|
||||
|
||||
// update that nested action with the details in the nested action JSON
|
||||
nestedAction = getActionFromJson(nestedActionJson, nestedActionToUpdate);
|
||||
}
|
||||
}
|
||||
@@ -422,6 +498,8 @@ public class RulesHelper
|
||||
nestedAction = getActionFromJson(nestedActionJson, null);
|
||||
}
|
||||
|
||||
// add the nested action (newly created or just updated) to
|
||||
// the composite action
|
||||
((CompositeAction)action).addAction(nestedAction);
|
||||
}
|
||||
}
|
||||
@@ -436,11 +514,10 @@ public class RulesHelper
|
||||
+ "name thereof is not '" + COMPOSITE_ACTION_DEF_NAME + "' as expected. Instead, the action's "
|
||||
+ "definition name is '" + actionDefinitionName + "'.");
|
||||
}
|
||||
// else the action's definition name is 'composite-action' but no nested actions were provided in the action JSON
|
||||
// (in which case we will just treat the action as a non-composite action anyway), otherwise the action is not
|
||||
// defined as a composite action, and no nested actions were sent in the action JSON, so just create it as a
|
||||
// non-composite action
|
||||
else
|
||||
|
||||
// if we are not updating an existing action and there are no nested actions in the action JSON,
|
||||
// just create a new action from the action definition without any recursive nested action handling
|
||||
if ((updateAction == false) && (nestedActionsJson == null))
|
||||
{
|
||||
action = actionService.createAction(actionDefinitionName);
|
||||
}
|
||||
@@ -449,19 +526,29 @@ public class RulesHelper
|
||||
// set action properties
|
||||
//
|
||||
|
||||
|
||||
if ((actionJson.isNull("title") == true) && (actionToUpdate == null))
|
||||
try
|
||||
{
|
||||
// the "title" field is mandatory, it is missing in the rule details,
|
||||
// and we are creating a new rule, so throw an exception
|
||||
if ((actionJson.isNull("title") == true) && (updateAction == false))
|
||||
{
|
||||
// the "title" field is missing in the action details,
|
||||
// and we are creating a new rule,
|
||||
// but the "title" field is mandatory, so throw an exception
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "A new rule is being created but the 'title' "
|
||||
+ "field, which is mandatory, has not been included in the rule details");
|
||||
}
|
||||
// otherwise go ahead and set the value if the field is present
|
||||
// to cover both create and update scenarios
|
||||
else if (actionJson.isNull("title") == false)
|
||||
{
|
||||
action.setTitle(actionJson.getString("title"));
|
||||
}
|
||||
}
|
||||
catch (JSONException je)
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "There was a problem reading the "
|
||||
+ "'title' property from the received action JSON. It is mandatory and may be "
|
||||
+ "missing from the received action JSON, or else it may contain invalid characters.", je);
|
||||
}
|
||||
|
||||
if (actionJson.isNull("description") == false)
|
||||
{
|
||||
@@ -480,12 +567,14 @@ public class RulesHelper
|
||||
|
||||
// set compensating action on current action if a compensating action is present
|
||||
// in the action JSON Object
|
||||
try
|
||||
{
|
||||
if (actionJson.isNull("compensatingAction") == false)
|
||||
{
|
||||
JSONObject compActionJson = actionJson.getJSONObject("compensatingAction");
|
||||
Action compActionToUpdate = null;
|
||||
|
||||
if (actionToUpdate != null)
|
||||
if (updateAction)
|
||||
{
|
||||
compActionToUpdate = action.getCompensatingAction();
|
||||
}
|
||||
@@ -493,6 +582,15 @@ public class RulesHelper
|
||||
|
||||
action.setCompensatingAction(compAction);
|
||||
}
|
||||
}
|
||||
catch (JSONException je)
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "There was a problem reading the "
|
||||
+ "'compensatingAction' property from the received action JSON. The value of the property "
|
||||
+ "may not be a JSON Object or something may be wrong with one of the properties in the JSON "
|
||||
+ "Object for the compensating action itself. The 'title' of the offending action is '"
|
||||
+ actionJson.optString("title") + "'", je);
|
||||
}
|
||||
|
||||
// get the action's definition
|
||||
ParameterizedItemDefinition actionDef = actionService.getActionDefinition(actionDefinitionName);
|
||||
@@ -510,60 +608,127 @@ public class RulesHelper
|
||||
// set conditions on the current action
|
||||
//
|
||||
|
||||
// if action JSON "conditions" property has a value
|
||||
// then populate the current action's conditions with the
|
||||
// conditions' details from within the action JSON
|
||||
if (actionJson.isNull("conditions") == false)
|
||||
{
|
||||
JSONArray conditionsJson = actionJson.getJSONArray("conditions");
|
||||
JSONArray conditionsJson = actionJson.optJSONArray("conditions");
|
||||
|
||||
// if we are doing an update then build up a condition map
|
||||
// do be able to do a condition look-up by ID for each condition included
|
||||
// in the condition JSON - the condition details
|
||||
// if conditionsJson is 'null' then throw a web script exception, because this means that
|
||||
// the conditions property does not contain a JSON Array. The conditions property of an incoming
|
||||
// action JSON object should be a JSON Array
|
||||
if (conditionsJson == null)
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "The 'conditions' property of the incoming "
|
||||
+ "action JSON titled '" + actionJson.optString("title") + "' is not a JSON Array");
|
||||
}
|
||||
|
||||
// If we are updating an existing action, then build up a map
|
||||
// (keyed by condition ID) of conditions associated with that existing action.
|
||||
// So for each condition JSON object (inside the incoming action JSON object),
|
||||
// if the condition ID thereof is found in the map, then update the existing condition
|
||||
// with the details sent in the JSON
|
||||
|
||||
Map<String, ActionCondition> conditionsMap = new HashMap<String, ActionCondition>();
|
||||
if (actionToUpdate != null)
|
||||
if (updateAction == true)
|
||||
{
|
||||
List<ActionCondition> actionConditions = actionToUpdate.getActionConditions();
|
||||
List<ActionCondition> actionConditions = action.getActionConditions();
|
||||
for (ActionCondition actionCondition : actionConditions)
|
||||
{
|
||||
conditionsMap.put(actionCondition.getId(), actionCondition);
|
||||
}
|
||||
}
|
||||
|
||||
// get each condition and add it to the action
|
||||
//
|
||||
// for each condition JSON object (associated with the incoming action JSON object):
|
||||
// - if we are doing an update then update the corresponding condition object (if one exists)
|
||||
// with the fields provided in the condition JSON object
|
||||
// - if we are doing a create then create a new condition from the details provided
|
||||
// in the condition JSON
|
||||
|
||||
int numConditionsJson = conditionsJson.length();
|
||||
for (int conditionJsonIndex = 0; conditionJsonIndex < numConditionsJson; conditionJsonIndex++)
|
||||
{
|
||||
ActionCondition condition = null;
|
||||
JSONObject conditionJson = conditionsJson.getJSONObject(conditionJsonIndex);
|
||||
|
||||
JSONObject conditionJson;
|
||||
try
|
||||
{
|
||||
conditionJson = conditionsJson.getJSONObject(conditionJsonIndex);
|
||||
}
|
||||
catch (JSONException je)
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "There was a problem reading the "
|
||||
+ "condition held at index " + conditionJsonIndex + " in the JSON Array held in the "
|
||||
+ "'conditions' property from the received action JSON. The value held at that "
|
||||
+ "index may not be a JSON Object. The 'title' of the action with the offending "
|
||||
+ "'conditions' property is '" + actionJson.optString("title") + "'", je);
|
||||
}
|
||||
|
||||
String conditionDefName = null;
|
||||
|
||||
// if we are doing an update, then get the existing condition matching
|
||||
// the condition ID given in the condition JSON, and update that with
|
||||
// the condition fields given therein
|
||||
if (actionToUpdate != null)
|
||||
// if we are doing an update, the current condition JSON has an ID,
|
||||
// and a condition already exists matching that ID, then set the current
|
||||
// condition to that existing condition and retrieve its definition name
|
||||
if ((updateAction == true) && (conditionJson.isNull("id") == false))
|
||||
{
|
||||
String conditionJsonId = conditionJson.getString("id");
|
||||
String conditionJsonId;
|
||||
try
|
||||
{
|
||||
conditionJsonId = conditionJson.getString("id");
|
||||
}
|
||||
catch (JSONException je)
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "There was a problem reading the "
|
||||
+ "'id' property from a condition in the received action JSON. When doing an update "
|
||||
+ "this condition property is mandatory and may be missing from this condition in the "
|
||||
+ "action JSON sent or else the property may contain invalid parameters. "
|
||||
+ "The 'conditionDefinitionName' of the offending condition is '"
|
||||
+ conditionJson.optString("conditionDefinitionName") + "'", je);
|
||||
}
|
||||
|
||||
// set the current condition being processed to the existing conditions
|
||||
condition = conditionsMap.get(conditionJsonId);
|
||||
|
||||
// get the condition definition name
|
||||
if (condition != null)
|
||||
{
|
||||
conditionDefName = condition.getActionConditionDefinitionName();
|
||||
}
|
||||
// we are not doing an update, so create the condition using the given condition
|
||||
// definition name and then populate this new condition from the fields given in
|
||||
// the condition JSON
|
||||
else
|
||||
{
|
||||
// we are not doing an update, so if the conditionDefinitionName has not been provided
|
||||
// in the condition JSON then throw a web script exception
|
||||
if (conditionJson.isNull("conditionDefinitionName"))
|
||||
|
||||
// remove the condition to be updated from its parent action
|
||||
// The updated condition is added to the action at the end of the
|
||||
// loop
|
||||
action.removeActionCondition(condition);
|
||||
}
|
||||
|
||||
// if the current condition is still 'null' (we are not updating an existing condition),
|
||||
// and if the conditionDefinitionName has not been provided in the condition JSON, then
|
||||
// throw a web script exception because we need to create a new condition using the condition
|
||||
// definition name provided in the condition JSON object
|
||||
if ((condition == null) && (conditionJson.isNull("conditionDefinitionName")))
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "A condition details at index: '"
|
||||
+ conditionJsonIndex + "' for action ID '" + action.getId() + " could not be created "
|
||||
+ "because the 'conditionDefinitionName' field is missing from the condition details sent");
|
||||
}
|
||||
|
||||
// else condition def name has been provided in the condition details
|
||||
else
|
||||
if (condition == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
conditionDefName = conditionJson.getString("conditionDefinitionName");
|
||||
}
|
||||
catch (JSONException je)
|
||||
{
|
||||
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "There was a problem reading the "
|
||||
+ "'conditionDefinitionName' property from a condition in the received action JSON. "
|
||||
+ "This condition property is mandatory and may be missing from this condition in the "
|
||||
+ "action JSON sent. The 'conditionDefinitionName' of the offending condition is '"
|
||||
+ conditionJson.optString("conditionDefinitionName") + "'", je);
|
||||
}
|
||||
|
||||
condition = actionService.createActionCondition(conditionDefName);
|
||||
}
|
||||
@@ -572,7 +737,8 @@ public class RulesHelper
|
||||
ParameterizedItemDefinition conditionDef = actionService.getActionConditionDefinition(conditionDefName);
|
||||
|
||||
//
|
||||
// set the condition's properties
|
||||
// populate the condition (newly created, or one being updated)
|
||||
// with fields given in the condition JSONs the condition's properties
|
||||
//
|
||||
|
||||
// Set the value for the 'invertCondition' field if that field is sent
|
||||
@@ -580,7 +746,7 @@ public class RulesHelper
|
||||
// either 'true' or 'false', then set it to a default value of false
|
||||
if (conditionJson.isNull("invertCondition") == false)
|
||||
{
|
||||
condition.setInvertCondition(conditionJson.getBoolean("invertCondition"));
|
||||
condition.setInvertCondition(conditionJson.optBoolean("invertCondition"));
|
||||
}
|
||||
|
||||
//
|
||||
@@ -595,19 +761,8 @@ public class RulesHelper
|
||||
|
||||
// add condition to action object
|
||||
action.addActionCondition(condition);
|
||||
|
||||
// increment the condition JSON index
|
||||
conditionJsonIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (JSONException je)
|
||||
{
|
||||
|
||||
|
||||
throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR,
|
||||
"Problem creating rule from JSON passed into Web Script.", je);
|
||||
}
|
||||
|
||||
return action;
|
||||
}
|
||||
|
@@ -133,7 +133,7 @@ public class RulesPost extends DeclarativeWebScript
|
||||
// URL template tokens
|
||||
NodeRef owningNodeRef = this.rulesHelper.getNodeRefFromWebScriptUrl(req, storeType, storeId, id);
|
||||
|
||||
// apply rule to actionable node
|
||||
// apply rule to rule owning node
|
||||
this.ruleService.saveRule(owningNodeRef, rule);
|
||||
|
||||
// add objects to model for the template to render
|
||||
|
Reference in New Issue
Block a user