diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/inheritedrules.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/inheritedrules.get.desc.xml new file mode 100755 index 0000000000..a4d4575758 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/inheritedrules.get.desc.xml @@ -0,0 +1,8 @@ + + Get Inherited Rules Collection + Gets a list of all inherited rules for a given node. The node can be specified either using a node reference or a query path. + /api/node/{store_type}/{store_id}/{id}/ruleset/inheritedrules?ruleType={rule_type?} + argument + user + required + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/inheritedrules.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/inheritedrules.get.json.ftl new file mode 100755 index 0000000000..c263994139 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/inheritedrules.get.json.ftl @@ -0,0 +1,10 @@ +<#import "rule.lib.ftl" as ruleLib/> +{ + "data" : + [ + <#list inheritedRuleRefs as inheritedRuleRef> + <@ruleLib.ruleRefOwningSummaryJSON ruleRef=inheritedRuleRef /> + <#if inheritedRuleRef_has_next>, + + ] +} \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.get.json.ftl index a5f033c723..cf3c0b6826 100755 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.get.json.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.get.json.ftl @@ -1,3 +1,3 @@ <#import "rule.lib.ftl" as ruleLib/> -<@ruleLib.ruleJSON rule=rule /> \ No newline at end of file +<@ruleLib.ruleRefJSON ruleRef=ruleRef /> \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.lib.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.lib.ftl index b4174458a5..1a1302c6d8 100755 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.lib.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.lib.ftl @@ -40,7 +40,7 @@ <@parameterValuesJSON parameterValues=actionCondition.parameterValues /> }, - "url" : "${"/api/node/" + storeType + "/" + storeId + "/" + id + "/ruleset/rules/" + rule.nodeRef.id + "/action/conditions/" + actionCondition.id}" + "url" : "${"/api/node/" + ruleRef.owningFileInfo.nodeRef.storeRef.protocol + "/" + ruleRef.owningFileInfo.nodeRef.storeRef.identifier + "/" + ruleRef.owningFileInfo.nodeRef.id + "/ruleset/rules/" + ruleRef.rule.nodeRef.id + "/action/conditions/" + actionCondition.id}" }<#if (actionCondition_has_next)>, ], @@ -48,42 +48,68 @@ <#if action.compensatingAction??> "compensatingAction" : <@actionJSON action=action.compensatingAction />, - "url" : "${"/api/node/" + storeType + "/" + storeId + "/" + id + "/ruleset/rules/" + rule.nodeRef.id + "/action/actions/" + action.id}" + "url" : "${"/api/node/" + ruleRef.owningFileInfo.nodeRef.storeRef.protocol + "/" + ruleRef.owningFileInfo.nodeRef.storeRef.identifier + "/" + ruleRef.owningFileInfo.nodeRef.id + "/ruleset/rules/" + ruleRef.rule.nodeRef.id + "/action/actions/" + action.id}" } <#-- renders a complete rule object --> -<#macro ruleJSON rule> +<#macro ruleRefJSON ruleRef> <#escape x as jsonUtils.encodeJSONString(x)> { - "id" : "${rule.nodeRef.id}", - "title" : "${rule.title}", - <#if rule.description??> - "description" : "${rule.description}", + "id" : "${ruleRef.rule.nodeRef.id}", + "title" : "${ruleRef.rule.title}", + <#if ruleRef.rule.description??> + "description" : "${ruleRef.rule.description}", - "ruleType" : [<#list rule.ruleTypes as ruleType>"${ruleType}"<#if (ruleType_has_next)>, ], - "applyToChildren" : ${rule.appliedToChildren?string}, - "executeAsynchronously" : ${rule.executeAsynchronously?string}, - "disabled" : ${rule.ruleDisabled?string}, - "action" : <@actionJSON action=rule.action />, - "url" : "${"/api/node/" + storeType + "/" + storeId + "/" + id + "/ruleset/rules/" + rule.nodeRef.id}" + "ruleType" : [<#list ruleRef.rule.ruleTypes as ruleType>"${ruleType}"<#if (ruleType_has_next)>, ], + "applyToChildren" : ${ruleRef.rule.appliedToChildren?string}, + "executeAsynchronously" : ${ruleRef.rule.executeAsynchronously?string}, + "disabled" : ${ruleRef.rule.ruleDisabled?string}, + "action" : <@actionJSON action=ruleRef.rule.action />, + "owningNode" : + { + "nodeRef" : "${ruleRef.owningFileInfo.nodeRef}", + "name" : "${ruleRef.owningFileInfo.name}" + }, + "url" : "${"/api/node/" + ruleRef.owningFileInfo.nodeRef.storeRef.protocol + "/" + ruleRef.owningFileInfo.nodeRef.storeRef.identifier + "/" + ruleRef.owningFileInfo.nodeRef.id + "/ruleset/rules/" + ruleRef.rule.nodeRef.id}" } -<#-- renders a summary rule object --> -<#macro rulesummaryJSON rule> +<#-- renders a summary rule object with owning nodeRef --> +<#macro ruleRefOwningSummaryJSON ruleRef> <#escape x as jsonUtils.encodeJSONString(x)> { - "id" : "${rule.nodeRef.id}", - "title" : "${rule.title}", - <#if rule.description??> - "description" : "${rule.description}", + "id" : "${ruleRef.rule.nodeRef.id}", + "title" : "${ruleRef.rule.title}", + <#if ruleRef.rule.description??> + "description" : "${ruleRef.rule.description}", - "ruleType" : [<#list rule.ruleTypes as ruleType>"${ruleType}"<#if (ruleType_has_next)>, ], - "disabled" : ${rule.ruleDisabled?string}, - "url" : "${"/api/node/" + storeType + "/" + storeId + "/" + id + "/ruleset/rules/" + rule.nodeRef.id}" + "ruleType" : [<#list ruleRef.rule.ruleTypes as ruleType>"${ruleType}"<#if (ruleType_has_next)>, ], + "disabled" : ${ruleRef.rule.ruleDisabled?string}, + "owningNode" : + { + "nodeRef" : "${ruleRef.owningFileInfo.nodeRef}", + "name" : "${ruleRef.owningFileInfo.name}" + }, + "url" : "${"/api/node/" + ruleRef.owningFileInfo.nodeRef.storeRef.protocol + "/" + ruleRef.owningFileInfo.nodeRef.storeRef.identifier + "/" + ruleRef.owningFileInfo.nodeRef.id + "/ruleset/rules/" + ruleRef.rule.nodeRef.id}" + } + + + +<#-- renders a summary rule object without owning nodeRef --> +<#macro ruleRefSummaryJSON ruleRef> +<#escape x as jsonUtils.encodeJSONString(x)> + { + "id" : "${ruleRef.rule.nodeRef.id}", + "title" : "${ruleRef.rule.title}", + <#if ruleRef.rule.description??> + "description" : "${ruleRef.rule.description}", + + "ruleType" : [<#list ruleRef.rule.ruleTypes as ruleType>"${ruleType}"<#if (ruleType_has_next)>, ], + "disabled" : ${ruleRef.rule.ruleDisabled?string}, + "url" : "${"/api/node/" + ruleRef.owningFileInfo.nodeRef.storeRef.protocol + "/" + ruleRef.owningFileInfo.nodeRef.storeRef.identifier + "/" + ruleRef.owningFileInfo.nodeRef.id + "/ruleset/rules/" + ruleRef.rule.nodeRef.id}" } @@ -97,8 +123,14 @@ ${val?string} <#elseif val?is_date == true> "${val?string("EEE MMM dd HH:mm:ss zzz yyyy")}" + <#elseif val?is_sequence> + [ + <#list val as element> + "${jsonUtils.encodeJSONString(element?string)}"<#if (element_has_next)>, + + ] <#else> - "${jsonUtils.encodeJSONString(val?string)}" + "${jsonUtils.encodeJSONString(shortQName(val?string))}" <#if (parameterValue_has_next)>, diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.post.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.post.json.ftl index fcf3074cb0..6e19e24eb2 100755 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.post.json.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.post.json.ftl @@ -2,5 +2,5 @@ { "data" : - <@ruleLib.rulesummaryJSON rule=rule /> + <@ruleLib.ruleRefSummaryJSON ruleRef=ruleRef /> } \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.put.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.put.json.ftl index a5f033c723..cf3c0b6826 100755 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.put.json.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.put.json.ftl @@ -1,3 +1,3 @@ <#import "rule.lib.ftl" as ruleLib/> -<@ruleLib.ruleJSON rule=rule /> \ No newline at end of file +<@ruleLib.ruleRefJSON ruleRef=ruleRef /> \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rules.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rules.get.desc.xml index 341fa9d978..7caf018b5d 100755 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rules.get.desc.xml +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rules.get.desc.xml @@ -1,6 +1,6 @@ Get Rules Collection - Gets a list of all the rules for a given node. The node can be specified either using a node reference or a query path. + Gets a list of all owned rules for a given node. The node can be specified either using a node reference or a query path. /api/node/{store_type}/{store_id}/{id}/ruleset/rules?ruleType={rule_type?} argument user diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rules.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rules.get.json.ftl index c54a8436bb..13c851019b 100755 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rules.get.json.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rules.get.json.ftl @@ -2,9 +2,9 @@ { "data" : [ - <#list rules as rule> - <@ruleLib.rulesummaryJSON rule=rule /> - <#if rule_has_next>, + <#list ruleRefs as ruleRef> + <@ruleLib.ruleRefOwningSummaryJSON ruleRef=ruleRef /> + <#if ruleRef_has_next>, ] } \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruleset.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruleset.get.json.ftl index a61f3a2d9c..66d732d4da 100755 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruleset.get.json.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruleset.get.json.ftl @@ -7,16 +7,8 @@ "rules" : [ <#list ruleset.rules as ruleRef> - { - "id" : "${ruleRef.rule.nodeRef.id}", - "title" : "${ruleRef.rule.title}", - <#if ruleRef.rule.description??> - "description" : "${ruleRef.rule.description}", - - "ruleType" : [<#list ruleRef.rule.ruleTypes as ruleType>"${ruleType}"<#if (ruleType_has_next)>, ], - "disabled" : ${ruleRef.rule.ruleDisabled?string}, - "url" : "${"/api/node/" + ruleRef.owningNodeRef.storeRef.protocol + "/" + ruleRef.owningNodeRef.storeRef.identifier + "/" + ruleRef.owningNodeRef.id + "/ruleset/rules/" + ruleRef.rule.nodeRef.id}" - }<#if ruleRef_has_next>, + <@ruleLib.ruleRefOwningSummaryJSON ruleRef=ruleRef /> + <#if ruleRef_has_next>, ], @@ -24,27 +16,19 @@ "inheritedRules" : [ <#list ruleset.inheritedRules as inheritedRuleRef> - { - "id" : "${inheritedRuleRef.rule.nodeRef.id}", - "title" : "${inheritedRuleRef.rule.title}", - <#if inheritedRuleRef.rule.description??> - "description" : "${inheritedRuleRef.rule.description}", - - "ruleType" : [<#list inheritedRuleRef.rule.ruleTypes as ruleType>"${ruleType}"<#if (ruleType_has_next)>, ], - "disabled" : ${inheritedRuleRef.rule.ruleDisabled?string}, - "url" : "${"/api/node/" + inheritedRuleRef.owningNodeRef.storeRef.protocol + "/" + inheritedRuleRef.owningNodeRef.storeRef.identifier + "/" + inheritedRuleRef.owningNodeRef.id + "/ruleset/rules/" + inheritedRuleRef.rule.nodeRef.id}" - }<#if inheritedRuleRef_has_next>, + <@ruleLib.ruleRefOwningSummaryJSON ruleRef=inheritedRuleRef /> + <#if inheritedRuleRef_has_next>, ], <#if ruleset.linkedToRuleSet??> - "linkedToRuleSet" : "${ruleset.linkedToRuleSet}", + "linkedToRuleSet" : "${"/api/node/" + ruleset.linkedToRuleSet.storeRef.protocol + "/" + ruleset.linkedToRuleSet.storeRef.identifier + "/" + ruleset.linkedToRuleSet.id + "/ruleset"}", <#if ruleset.linkedFromRuleSets?? && ruleset.linkedFromRuleSets?size > 0> "linkedFromRuleSets" : [ <#list ruleset.linkedFromRuleSets as linkedFromRuleSet> - "${linkedFromRuleSet}"<#if linkedFromRuleSet_has_next>, + "${"/api/node/" + linkedFromRuleSet.storeRef.protocol + "/" + linkedFromRuleSet.storeRef.identifier + "/" + linkedFromRuleSet.id + "/ruleset"}"<#if linkedFromRuleSet_has_next>, ], diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml index 2e7f55637d..c754e17eaf 100644 --- a/config/alfresco/web-scripts-application-context.xml +++ b/config/alfresco/web-scripts-application-context.xml @@ -597,6 +597,7 @@ + @@ -626,10 +627,14 @@ - + + + + + diff --git a/source/java/org/alfresco/repo/web/scripts/rule/AbstractRuleWebScript.java b/source/java/org/alfresco/repo/web/scripts/rule/AbstractRuleWebScript.java index a8cb438010..a6dbf30f17 100755 --- a/source/java/org/alfresco/repo/web/scripts/rule/AbstractRuleWebScript.java +++ b/source/java/org/alfresco/repo/web/scripts/rule/AbstractRuleWebScript.java @@ -46,6 +46,7 @@ import org.alfresco.service.cmr.action.ActionService; import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; @@ -69,19 +70,20 @@ import org.springframework.extensions.webscripts.WebScriptRequest; */ public abstract class AbstractRuleWebScript extends DeclarativeWebScript { - + public static final SimpleDateFormat dateFormate = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy"); - + protected NodeService nodeService; protected RuleService ruleService; protected DictionaryService dictionaryService; protected ActionService actionService; + protected FileFolderService fileFolderService; protected NamespaceService namespaceService; - + private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); - - private static Map propertyTypes = null; - + + private static Map> propertyTypes = null; + /** * Sets the node service instance * @@ -91,7 +93,7 @@ public abstract class AbstractRuleWebScript extends DeclarativeWebScript { this.nodeService = nodeService; } - + /** * Set rule service instance * @@ -101,7 +103,7 @@ public abstract class AbstractRuleWebScript extends DeclarativeWebScript { this.ruleService = ruleService; } - + /** * Set dictionary service instance * @@ -111,7 +113,7 @@ public abstract class AbstractRuleWebScript extends DeclarativeWebScript { this.dictionaryService = dictionaryService; } - + /** * Set action service instance * @@ -121,7 +123,17 @@ public abstract class AbstractRuleWebScript extends DeclarativeWebScript { this.actionService = actionService; } - + + /** + * Set file folder service instance + * + * @param fileFolderService the fileFolderService to set + */ + public void setFileFolderService(FileFolderService fileFolderService) + { + this.fileFolderService = fileFolderService; + } + /** * Set namespace service instance * @@ -131,7 +143,7 @@ public abstract class AbstractRuleWebScript extends DeclarativeWebScript { this.namespaceService = namespaceService; } - + /** * Parses the request and providing it's valid returns the NodeRef. * @@ -147,138 +159,210 @@ public abstract class AbstractRuleWebScript extends DeclarativeWebScript String storeType = templateVars.get("store_type"); String storeId = templateVars.get("store_id"); String nodeId = templateVars.get("id"); - + // create the NodeRef and ensure it is valid StoreRef storeRef = new StoreRef(storeType, storeId); NodeRef nodeRef = new NodeRef(storeRef, nodeId); - + if (!this.nodeService.exists(nodeRef)) { - throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find node: " + - nodeRef.toString()); + throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find node: " + nodeRef.toString()); } - + return nodeRef; } - - protected QName getPropertyType(String propertyName) + + protected QName getPropertyType(String name, boolean isAction, String propertyName) { + QName result = null; + if (propertyTypes == null) - { - // no parameter types was cached - propertyTypes = new HashMap(); - + { + propertyTypes = new HashMap>(); + // get parameters for all action definitions List actionDefinitions = actionService.getActionDefinitions(); + for (ActionDefinition actionDefinition : actionDefinitions) { - List parameterDefinitions = actionDefinition.getParameterDefinitions(); - - for (ParameterDefinition parameterDefinition : parameterDefinitions) - { - try - { - // cache parameter - lock.writeLock().lock(); - propertyTypes.put(parameterDefinition.getName(), parameterDefinition.getType()); - } - finally - { - lock.writeLock().unlock(); - } - } - } - - // get parameters for all action condition definitions - List actionConditionDefinitions = actionService.getActionConditionDefinitions(); - for (ActionConditionDefinition actionConditionDefinition : actionConditionDefinitions) - { - List parameterDefinitions = actionConditionDefinition.getParameterDefinitions(); - + List parameterDefinitions = actionDefinition.getParameterDefinitions(); + Map parameters = new HashMap(); for (ParameterDefinition parameterDefinition : parameterDefinitions) { - try - { - // cache parameter - lock.writeLock().lock(); - propertyTypes.put(parameterDefinition.getName(), parameterDefinition.getType()); - } - finally - { - lock.writeLock().unlock(); - } + String parameterName = parameterDefinition.getName(); + QName parameterType = parameterDefinition.getType(); + parameters.put(parameterName, parameterType); + } + + try + { + // cache parameter + lock.writeLock().lock(); + propertyTypes.put(actionDefinition.getName(), parameters); + } + finally + { + lock.writeLock().unlock(); + } + } + + // get parameters for all action condition definitions + List actionConditionDefinitions = actionService.getActionConditionDefinitions(); + + for (ActionConditionDefinition actionConditionDefinition : actionConditionDefinitions) + { + List parameterDefinitions = actionConditionDefinition.getParameterDefinitions(); + Map parameters = new HashMap(); + + for (ParameterDefinition parameterDefinition : parameterDefinitions) + { + String parameterName = parameterDefinition.getName(); + QName parameterType = parameterDefinition.getType(); + parameters.put(parameterName, parameterType); + } + + try + { + lock.writeLock().lock(); + propertyTypes.put(actionConditionDefinition.getName(), parameters); + } + finally + { + lock.writeLock().unlock(); } } } - - QName result = null; - try + + if (propertyTypes.containsKey(name)) { - // getting cached parameter type - lock.readLock().lock(); - result = propertyTypes.get(propertyName); + Map parameters; + try + { + lock.readLock().lock(); + parameters = propertyTypes.get(name); + } + finally + { + lock.readLock().unlock(); + } + result = parameters.get(propertyName); + return result; } - finally + else { - lock.readLock().unlock(); + if (isAction) + { + ActionDefinition actionDefinition = actionService.getActionDefinition(name); + List parameterDefinitions = actionDefinition.getParameterDefinitions(); + Map parameters = new HashMap(); + + for (ParameterDefinition parameterDefinition : parameterDefinitions) + { + String parameterName = parameterDefinition.getName(); + QName parameterType = parameterDefinition.getType(); + parameters.put(parameterName, parameterType); + + if (parameterName.equals(propertyName)) + { + result = parameterType; + } + } + + try + { + // cache parameter + lock.writeLock().lock(); + propertyTypes.put(name, parameters); + } + finally + { + lock.writeLock().unlock(); + } + } + else + { + ActionConditionDefinition actionConditionDefinition = actionService.getActionConditionDefinition(name); + List parameterDefinitions = actionConditionDefinition.getParameterDefinitions(); + Map parameters = new HashMap(); + + for (ParameterDefinition parameterDefinition : parameterDefinitions) + { + String parameterName = parameterDefinition.getName(); + QName parameterType = parameterDefinition.getType(); + parameters.put(parameterName, parameterType); + + if (parameterName.equals(propertyName)) + { + result = parameterType; + } + } + + try + { + lock.writeLock().lock(); + propertyTypes.put(name, parameters); + } + finally + { + lock.writeLock().unlock(); + } + } } - + return result; } - + protected Rule parseJsonRule(JSONObject jsonRule) throws JSONException { Rule result = new Rule(); - + if (jsonRule.has("title") == false || jsonRule.getString("title").length() == 0) { - throw new WebScriptException(Status.STATUS_BAD_REQUEST, - "Title missing when creating rule"); + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Title missing when creating rule"); } - + result.setTitle(jsonRule.getString("title")); - + result.setDescription(jsonRule.has("description") ? jsonRule.getString("description") : ""); - + if (jsonRule.has("ruleType") == false || jsonRule.getJSONArray("ruleType").length() == 0) { - throw new WebScriptException(Status.STATUS_BAD_REQUEST, - "Rule type missing when creating rule"); + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Rule type missing when creating rule"); } - + JSONArray types = jsonRule.getJSONArray("ruleType"); List ruleTypes = new ArrayList(); - + for (int i = 0; i < types.length(); i++) { - ruleTypes.add(types.getString(i)); + ruleTypes.add(types.getString(i)); } - + result.setRuleTypes(ruleTypes); - + result.applyToChildren(jsonRule.has("applyToChildren") ? jsonRule.getBoolean("applyToChildren") : false); - + result.setExecuteAsynchronously(jsonRule.has("executeAsynchronously") ? jsonRule.getBoolean("executeAsynchronously") : false); - + result.setRuleDisabled(jsonRule.has("disabled") ? jsonRule.getBoolean("disabled") : false); - + JSONObject jsonAction = jsonRule.getJSONObject("action"); - + // parse action object Action ruleAction = parseJsonAction(jsonAction); - + result.setAction(ruleAction); - - return result; + + return result; } - - protected ActionImpl parseJsonAction(JSONObject jsonAction) throws JSONException + + protected ActionImpl parseJsonAction(JSONObject jsonAction) throws JSONException { ActionImpl result = null; - + String actionId = jsonAction.has("id") ? jsonAction.getString("id") : GUID.generate(); - + if (jsonAction.getString("actionDefinitionName").equalsIgnoreCase("composite-action")) { result = new CompositeActionImpl(null, actionId); @@ -287,160 +371,176 @@ public abstract class AbstractRuleWebScript extends DeclarativeWebScript { result = new ActionImpl(null, actionId, jsonAction.getString("actionDefinitionName")); } - + // Post Action Queue parameter if (jsonAction.has("actionedUponNode")) { NodeRef actionedUponNode = new NodeRef(jsonAction.getString("actionedUponNode")); result.setNodeRef(actionedUponNode); } - + if (jsonAction.has("description")) { result.setDescription(jsonAction.getString("description")); } - + if (jsonAction.has("title")) { result.setTitle(jsonAction.getString("title")); } - + if (jsonAction.has("parameterValues")) { - JSONObject jsonParameterValues = jsonAction.getJSONObject("parameterValues"); - result.setParameterValues(parseJsonParameterValues(jsonParameterValues)); + JSONObject jsonParameterValues = jsonAction.getJSONObject("parameterValues"); + result.setParameterValues(parseJsonParameterValues(jsonParameterValues, result.getActionDefinitionName(), true)); } - + if (jsonAction.has("executeAsync")) { result.setExecuteAsynchronously(jsonAction.getBoolean("executeAsync")); } - + if (jsonAction.has("runAsUser")) { result.setRunAsUser(jsonAction.getString("runAsUser")); } - + if (jsonAction.has("actions")) { JSONArray jsonActions = jsonAction.getJSONArray("actions"); - + for (int i = 0; i < jsonActions.length(); i++) { JSONObject innerJsonAction = jsonActions.getJSONObject(i); - + Action innerAction = parseJsonAction(innerJsonAction); - + // we assume that only composite-action contains actions json array, so should be no cast exception - ((CompositeActionImpl)result).addAction(innerAction); + ((CompositeActionImpl) result).addAction(innerAction); } } - + if (jsonAction.has("conditions")) { JSONArray jsonConditions = jsonAction.getJSONArray("conditions"); - + for (int i = 0; i < jsonConditions.length(); i++) { - JSONObject jsonCondition = jsonConditions.getJSONObject(i); - + JSONObject jsonCondition = jsonConditions.getJSONObject(i); + // parse action conditions ActionCondition actionCondition = parseJsonActionCondition(jsonCondition); - + result.getActionConditions().add(actionCondition); - } + } } - + if (jsonAction.has("compensatingAction")) { Action compensatingAction = parseJsonAction(jsonAction.getJSONObject("compensatingAction")); result.setCompensatingAction(compensatingAction); } - + return result; } - + protected ActionConditionImpl parseJsonActionCondition(JSONObject jsonActionCondition) throws JSONException { - String id = jsonActionCondition.has("id") ? jsonActionCondition.getString("id"): GUID.generate(); - + String id = jsonActionCondition.has("id") ? jsonActionCondition.getString("id") : GUID.generate(); + ActionConditionImpl result = new ActionConditionImpl(id, jsonActionCondition.getString("conditionDefinitionName")); - + if (jsonActionCondition.has("invertCondition")) { result.setInvertCondition(jsonActionCondition.getBoolean("invertCondition")); } - + if (jsonActionCondition.has("parameterValues")) { - JSONObject jsonParameterValues = jsonActionCondition.getJSONObject("parameterValues"); - - result.setParameterValues(parseJsonParameterValues(jsonParameterValues)); + JSONObject jsonParameterValues = jsonActionCondition.getJSONObject("parameterValues"); + + result.setParameterValues(parseJsonParameterValues(jsonParameterValues, result.getActionConditionDefinitionName(), false)); } - + return result; } - - protected Map parseJsonParameterValues(JSONObject jsonParameterValues) throws JSONException + + @SuppressWarnings("unchecked") + protected Map parseJsonParameterValues(JSONObject jsonParameterValues, String name, boolean isAction) throws JSONException { Map parameterValues = new HashMap(); - + // get parameters names JSONArray names = jsonParameterValues.names(); - if (names != null) + if (names == null) { - for (int i = 0; i < names.length(); i++) + return null; + } + + for (int i = 0; i < names.length(); i++) + { + String propertyName = names.getString(i); + Object propertyValue = jsonParameterValues.get(propertyName); + + // get parameter repository type + QName typeQName = getPropertyType(name, isAction, propertyName); + + if (typeQName == null) { - String propertyName = names.getString(i); - Object propertyValue = jsonParameterValues.get(propertyName); - - // get parameter repository type - QName typeQName = getPropertyType(propertyName); - - if (typeQName == null) + if (propertyValue.toString().equals("true") || propertyValue.toString().equals("false")) { - if (propertyValue.toString().equals("true") || propertyValue.toString().equals("false")) - { - typeQName = DataTypeDefinition.BOOLEAN; - } - else - { - typeQName = DataTypeDefinition.TEXT; - } + typeQName = DataTypeDefinition.BOOLEAN; } - - Serializable value = null; - - if (typeQName.equals(DataTypeDefinition.ANY)) + else + { + typeQName = DataTypeDefinition.TEXT; + } + } + + Serializable value = null; + + if (typeQName.equals(DataTypeDefinition.QNAME)) + { + value = QName.createQName(propertyValue.toString(), namespaceService); + } + + if (typeQName.equals(DataTypeDefinition.ANY)) + { + try + { + value = dateFormate.parse(propertyValue.toString()); + } + catch (ParseException e) { try { - value = dateFormate.parse(propertyValue.toString()); + value = Long.valueOf(propertyValue.toString()); } - catch (ParseException e) + catch (NumberFormatException e1) { - try + if (propertyValue instanceof JSONArray) { - value = Long.valueOf(propertyValue.toString()); - } - catch (NumberFormatException e1) - { - // do nothing + value = new ArrayList(); + JSONArray array = (JSONArray) propertyValue; + for (int j = 0; j < array.length(); j++) + { + ((List) value).add(array.getString(j)); + } } } } - - if (value == null) - { - // convert to correct repository type - value = (Serializable)DefaultTypeConverter.INSTANCE.convert(dictionaryService.getDataType(typeQName), propertyValue); - } - - parameterValues.put(propertyName, value); } + + if (value == null) + { + // convert to correct repository type + value = (Serializable) DefaultTypeConverter.INSTANCE.convert(dictionaryService.getDataType(typeQName), propertyValue); + } + + parameterValues.put(propertyName, value); } - + return parameterValues; } } diff --git a/source/java/org/alfresco/repo/web/scripts/rule/ActionConditionDefinitionsGet.java b/source/java/org/alfresco/repo/web/scripts/rule/ActionConditionDefinitionsGet.java index ff8280d9b7..28fc82a972 100755 --- a/source/java/org/alfresco/repo/web/scripts/rule/ActionConditionDefinitionsGet.java +++ b/source/java/org/alfresco/repo/web/scripts/rule/ActionConditionDefinitionsGet.java @@ -43,17 +43,17 @@ public class ActionConditionDefinitionsGet extends AbstractRuleWebScript { @SuppressWarnings("unused") private static Log logger = LogFactory.getLog(ActionConditionDefinitionsGet.class); - + @Override protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) { Map model = new HashMap(); - + // get all action condition definitions List actionconditiondefinitions = actionService.getActionConditionDefinitions(); - + model.put("actionconditiondefinitions", actionconditiondefinitions); - + return model; - } + } } diff --git a/source/java/org/alfresco/repo/web/scripts/rule/ActionConstraintGet.java b/source/java/org/alfresco/repo/web/scripts/rule/ActionConstraintGet.java index 2c9d1719d9..7884740fb7 100755 --- a/source/java/org/alfresco/repo/web/scripts/rule/ActionConstraintGet.java +++ b/source/java/org/alfresco/repo/web/scripts/rule/ActionConstraintGet.java @@ -46,27 +46,26 @@ public class ActionConstraintGet extends AbstractRuleWebScript @SuppressWarnings("unused") private static Log logger = LogFactory.getLog(ActionConstraintGet.class); - + @Override protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) { Map model = new HashMap(); - + // get request parameters Map templateVars = req.getServiceMatch().getTemplateVars(); String name = templateVars.get("name"); - + // get specified parameter constraint ParameterConstraint parameterConstraint = actionService.getParameterConstraint(name); - + if (parameterConstraint == null) { - throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find parameter constraint with name: " + - name); + throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find parameter constraint with name: " + name); } - + model.put("actionConstraint", parameterConstraint); - + return model; } } diff --git a/source/java/org/alfresco/repo/web/scripts/rule/ActionConstraintsGet.java b/source/java/org/alfresco/repo/web/scripts/rule/ActionConstraintsGet.java index f78f9086de..f4af2217dd 100755 --- a/source/java/org/alfresco/repo/web/scripts/rule/ActionConstraintsGet.java +++ b/source/java/org/alfresco/repo/web/scripts/rule/ActionConstraintsGet.java @@ -42,31 +42,30 @@ import org.springframework.extensions.webscripts.WebScriptRequest; */ public class ActionConstraintsGet extends AbstractRuleWebScript { - + @SuppressWarnings("unused") private static Log logger = LogFactory.getLog(ActionConstraintsGet.class); - @Override protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) { Map model = new HashMap(); - + // get request parameters String[] names = req.getParameterValues("name"); - + List parameterConstraints = null; - + if (names != null && names.length > 0) { // filter is present in request parameterConstraints = new ArrayList(); - + // find specified parameter constraints for (String name : names) { ParameterConstraint parameterConstraint = actionService.getParameterConstraint(name); - + if (parameterConstraint != null) { parameterConstraints.add(parameterConstraint); @@ -78,9 +77,9 @@ public class ActionConstraintsGet extends AbstractRuleWebScript // no filter was provided, return all parameter constraints parameterConstraints = actionService.getParameterConstraints(); } - + model.put("actionConstraints", parameterConstraints); - + return model; } } diff --git a/source/java/org/alfresco/repo/web/scripts/rule/ActionDefinitionsGet.java b/source/java/org/alfresco/repo/web/scripts/rule/ActionDefinitionsGet.java index bdd5f37ac9..6ab47bbeec 100755 --- a/source/java/org/alfresco/repo/web/scripts/rule/ActionDefinitionsGet.java +++ b/source/java/org/alfresco/repo/web/scripts/rule/ActionDefinitionsGet.java @@ -48,12 +48,12 @@ public class ActionDefinitionsGet extends AbstractRuleWebScript protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) { Map model = new HashMap(); - + // get all action definitions List actiondefinitions = actionService.getActionDefinitions(); - + model.put("actiondefinitions", actiondefinitions); - + return model; } } diff --git a/source/java/org/alfresco/repo/web/scripts/rule/ActionQueuePost.java b/source/java/org/alfresco/repo/web/scripts/rule/ActionQueuePost.java index 8be7ffbecf..e3bc8cfcb3 100755 --- a/source/java/org/alfresco/repo/web/scripts/rule/ActionQueuePost.java +++ b/source/java/org/alfresco/repo/web/scripts/rule/ActionQueuePost.java @@ -48,36 +48,36 @@ public class ActionQueuePost extends AbstractRuleWebScript { @SuppressWarnings("unused") private static Log logger = LogFactory.getLog(ActionQueuePost.class); - + public static final String STATUS = "actionExecStatus"; public static final String STATUS_SUCCESS = "success"; public static final String STATUS_FAIL = "fail"; public static final String STATUS_QUEUED = "queued"; - + @Override protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) { Map model = new HashMap(); - + // get request parameters boolean async = Boolean.parseBoolean(req.getParameter("async")); - + ActionImpl action = null; JSONObject json = null; - + try { // read request json json = new JSONObject(new JSONTokener(req.getContent().getContent())); - + // parse request json action = parseJsonAction(json); NodeRef actionedUponNode = action.getNodeRef(); - + // clear nodeRef for action action.setNodeRef(null); json.remove("actionedUponNode"); - + if (async) { model.put(STATUS, STATUS_QUEUED); @@ -86,31 +86,29 @@ public class ActionQueuePost extends AbstractRuleWebScript { model.put(STATUS, STATUS_SUCCESS); } - + try { actionService.executeAction(action, actionedUponNode, true, async); } - catch(Throwable e) + catch (Throwable e) { model.put(STATUS, STATUS_FAIL); model.put("exception", e); } - + model.put("actionedUponNode", actionedUponNode.toString()); - model.put("action", json); + model.put("action", json); } catch (IOException iox) { - throw new WebScriptException(Status.STATUS_BAD_REQUEST, - "Could not read content from req.", iox); + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not read content from req.", iox); } catch (JSONException je) { - throw new WebScriptException(Status.STATUS_BAD_REQUEST, - "Could not parse JSON from req.", je); + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not parse JSON from req.", je); } - + return model; - } + } } diff --git a/source/java/org/alfresco/repo/web/scripts/rule/InheritedRulesGet.java b/source/java/org/alfresco/repo/web/scripts/rule/InheritedRulesGet.java new file mode 100755 index 0000000000..6917db2c94 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/rule/InheritedRulesGet.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2005-2009 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.repo.web.scripts.rule; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.repo.web.scripts.rule.ruleset.RuleRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.rule.Rule; +import org.alfresco.service.cmr.rule.RuleType; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.extensions.webscripts.Cache; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * @author unknown + * + */ +public class InheritedRulesGet extends AbstractRuleWebScript +{ + @SuppressWarnings("unused") + private static Log logger = LogFactory.getLog(InheritedRulesGet.class); + + @Override + protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) + { + Map model = new HashMap(); + + // get request parameters + NodeRef nodeRef = parseRequestForNodeRef(req); + String ruleType = req.getParameter("ruleType"); + + RuleType type = ruleService.getRuleType(ruleType); + + if (type == null) + { + ruleType = null; + } + + // get all rules (including inherited) filtered by rule type + List inheritedRules = ruleService.getRules(nodeRef, true, ruleType); + + // get owned rules (excluding inherited) filtered by rule type + List ownedRules = ruleService.getRules(nodeRef, false, ruleType); + + // remove owned rules + inheritedRules.removeAll(ownedRules); + + List inheritedRuleRefs = new ArrayList(); + + for (Rule rule : inheritedRules) + { + inheritedRuleRefs.add(new RuleRef(rule, fileFolderService.getFileInfo(ruleService.getOwningNodeRef(rule)))); + } + + model.put("inheritedRuleRefs", inheritedRuleRefs); + + return model; + } +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/rule/RuleDelete.java b/source/java/org/alfresco/repo/web/scripts/rule/RuleDelete.java index 91253c1fb9..b4a6340274 100755 --- a/source/java/org/alfresco/repo/web/scripts/rule/RuleDelete.java +++ b/source/java/org/alfresco/repo/web/scripts/rule/RuleDelete.java @@ -47,23 +47,23 @@ public class RuleDelete extends AbstractRuleWebScript { @SuppressWarnings("unused") private static Log logger = LogFactory.getLog(RuleDelete.class); - + @Override protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) { Map model = new HashMap(); - + NodeRef nodeRef = parseRequestForNodeRef(req); - + // get request parameters Map templateVars = req.getServiceMatch().getTemplateVars(); String ruleId = templateVars.get("rule_id"); - + Rule ruleToDelete = null; - + // get all rules for given nodeRef - List rules = ruleService.getRules(nodeRef); - + List rules = ruleService.getRules(nodeRef, false); + // filter by rule id for (Rule rule : rules) { @@ -73,16 +73,15 @@ public class RuleDelete extends AbstractRuleWebScript break; } } - + if (ruleToDelete == null) { - throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find rule with id: " + - ruleId); + throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find rule with id: " + ruleId); } - + // delete rule ruleService.removeRule(nodeRef, ruleToDelete); - + return model; } } diff --git a/source/java/org/alfresco/repo/web/scripts/rule/RuleGet.java b/source/java/org/alfresco/repo/web/scripts/rule/RuleGet.java index 8d94b464cc..8b7c3f50c7 100755 --- a/source/java/org/alfresco/repo/web/scripts/rule/RuleGet.java +++ b/source/java/org/alfresco/repo/web/scripts/rule/RuleGet.java @@ -30,6 +30,7 @@ import java.util.Map; import javax.servlet.http.HttpServletResponse; +import org.alfresco.repo.web.scripts.rule.ruleset.RuleRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.rule.Rule; import org.apache.commons.logging.Log; @@ -47,23 +48,23 @@ public class RuleGet extends AbstractRuleWebScript { @SuppressWarnings("unused") private static Log logger = LogFactory.getLog(RuleGet.class); - + @Override protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) { Map model = new HashMap(); - + NodeRef nodeRef = parseRequestForNodeRef(req); - + // get request parameters Map templateVars = req.getServiceMatch().getTemplateVars(); String ruleId = templateVars.get("rule_id"); - + Rule ruleToReturn = null; - + // get all rules for given nodeRef List rules = ruleService.getRules(nodeRef); - + // filter by rule id for (Rule rule : rules) { @@ -73,18 +74,16 @@ public class RuleGet extends AbstractRuleWebScript break; } } - + if (ruleToReturn == null) { - throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find rule with id: " + - ruleId); + throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find rule with id: " + ruleId); } - - model.put("rule", ruleToReturn); - model.put("storeType", nodeRef.getStoreRef().getProtocol()); - model.put("storeId", nodeRef.getStoreRef().getIdentifier()); - model.put("id", nodeRef.getId()); - + + RuleRef ruleRefToReturn = new RuleRef(ruleToReturn, fileFolderService.getFileInfo(ruleService.getOwningNodeRef(ruleToReturn))); + + model.put("ruleRef", ruleRefToReturn); + return model; } } diff --git a/source/java/org/alfresco/repo/web/scripts/rule/RulePost.java b/source/java/org/alfresco/repo/web/scripts/rule/RulePost.java index 3eb9b2f54c..54026cfb5a 100755 --- a/source/java/org/alfresco/repo/web/scripts/rule/RulePost.java +++ b/source/java/org/alfresco/repo/web/scripts/rule/RulePost.java @@ -28,6 +28,7 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; +import org.alfresco.repo.web.scripts.rule.ruleset.RuleRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.rule.Rule; import org.apache.commons.logging.Log; @@ -45,48 +46,45 @@ import org.springframework.extensions.webscripts.WebScriptRequest; * */ public class RulePost extends AbstractRuleWebScript -{ +{ @SuppressWarnings("unused") private static Log logger = LogFactory.getLog(RulePost.class); @Override protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) - { + { Map model = new HashMap(); - + // get request parameters NodeRef nodeRef = parseRequestForNodeRef(req); - + Rule rule = null; JSONObject json = null; - + try { // read request json json = new JSONObject(new JSONTokener(req.getContent().getContent())); - + // parse request json rule = parseJsonRule(json); - + // create rule ruleService.saveRule(nodeRef, rule); - - model.put("rule", rule); - model.put("storeType", nodeRef.getStoreRef().getProtocol()); - model.put("storeId", nodeRef.getStoreRef().getIdentifier()); - model.put("id", nodeRef.getId()); + + RuleRef ruleRef = new RuleRef(rule, fileFolderService.getFileInfo(ruleService.getOwningNodeRef(rule))); + + model.put("ruleRef", ruleRef); } catch (IOException iox) { - throw new WebScriptException(Status.STATUS_BAD_REQUEST, - "Could not read content from req.", iox); + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not read content from req.", iox); } catch (JSONException je) { - throw new WebScriptException(Status.STATUS_BAD_REQUEST, - "Could not parse JSON from req.", je); + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not parse JSON from req.", je); } - + return model; } } diff --git a/source/java/org/alfresco/repo/web/scripts/rule/RulePut.java b/source/java/org/alfresco/repo/web/scripts/rule/RulePut.java index 681bcd2d1a..f7b376d1ae 100755 --- a/source/java/org/alfresco/repo/web/scripts/rule/RulePut.java +++ b/source/java/org/alfresco/repo/web/scripts/rule/RulePut.java @@ -35,6 +35,7 @@ import javax.servlet.http.HttpServletResponse; import org.alfresco.repo.action.ActionConditionImpl; import org.alfresco.repo.action.ActionImpl; import org.alfresco.repo.action.CompositeActionImpl; +import org.alfresco.repo.web.scripts.rule.ruleset.RuleRef; import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ActionCondition; import org.alfresco.service.cmr.repository.NodeRef; @@ -61,20 +62,20 @@ public class RulePut extends RulePost @Override protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) - { + { Map model = new HashMap(); - + // get request parameters NodeRef nodeRef = parseRequestForNodeRef(req); - + Map templateVars = req.getServiceMatch().getTemplateVars(); String ruleId = templateVars.get("rule_id"); - + Rule ruleToUpdate = null; - + // get all rules for given nodeRef List rules = ruleService.getRules(nodeRef); - + //filter by rule id for (Rule rule : rules) { @@ -84,99 +85,95 @@ public class RulePut extends RulePost break; } } - + if (ruleToUpdate == null) { - throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find rule with id: " + - ruleId); + throw new WebScriptException(HttpServletResponse.SC_NOT_FOUND, "Unable to find rule with id: " + ruleId); } - + JSONObject json = null; - + try { // read request json json = new JSONObject(new JSONTokener(req.getContent().getContent())); - + // parse request json updateRuleFromJSON(json, ruleToUpdate); - + // save changes ruleService.saveRule(nodeRef, ruleToUpdate); - - model.put("rule", ruleToUpdate); - model.put("storeType", nodeRef.getStoreRef().getProtocol()); - model.put("storeId", nodeRef.getStoreRef().getIdentifier()); - model.put("id", nodeRef.getId()); + + RuleRef updatedRuleRef = new RuleRef(ruleToUpdate, fileFolderService.getFileInfo(ruleService.getOwningNodeRef(ruleToUpdate))); + + model.put("ruleRef", updatedRuleRef); } catch (IOException iox) { - throw new WebScriptException(Status.STATUS_BAD_REQUEST, - "Could not read content from req.", iox); + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not read content from req.", iox); } catch (JSONException je) { - throw new WebScriptException(Status.STATUS_BAD_REQUEST, - "Could not parse JSON from req.", je); + throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Could not parse JSON from req.", je); } - + return model; } - + protected void updateRuleFromJSON(JSONObject jsonRule, Rule ruleToUpdate) throws JSONException { if (jsonRule.has("title")) { ruleToUpdate.setTitle(jsonRule.getString("title")); - } - + } + if (jsonRule.has("description")) { ruleToUpdate.setDescription(jsonRule.getString("description")); } - + if (jsonRule.has("ruleType")) { JSONArray jsonTypes = jsonRule.getJSONArray("ruleType"); List types = new ArrayList(); - + for (int i = 0; i < jsonTypes.length(); i++) { - types.add(jsonTypes.getString(i)); + types.add(jsonTypes.getString(i)); } ruleToUpdate.setRuleTypes(types); } - + if (jsonRule.has("applyToChildren")) { ruleToUpdate.applyToChildren(jsonRule.getBoolean("applyToChildren")); } - + if (jsonRule.has("executeAsynchronously")) { ruleToUpdate.setExecuteAsynchronously(jsonRule.getBoolean("executeAsynchronously")); } - + if (jsonRule.has("disabled")) { ruleToUpdate.setRuleDisabled(jsonRule.getBoolean("disabled")); } - + if (jsonRule.has("action")) - { - JSONObject jsonAction = jsonRule.getJSONObject("action"); - + { + JSONObject jsonAction = jsonRule.getJSONObject("action"); + // update rule action - Action action = updateActionFromJson(jsonAction, (ActionImpl)ruleToUpdate.getAction()); - + Action action = updateActionFromJson(jsonAction, (ActionImpl) ruleToUpdate.getAction()); + ruleToUpdate.setAction(action); } } - + protected Action updateActionFromJson(JSONObject jsonAction, ActionImpl actionToUpdate) throws JSONException { ActionImpl result = null; - + if (jsonAction.has("id")) { // update existing action @@ -186,82 +183,82 @@ public class RulePut extends RulePost { // create new object as id was not sent by client result = parseJsonAction(jsonAction); - return result; + return result; } - + if (jsonAction.has("description")) { result.setDescription(jsonAction.getString("description")); } - + if (jsonAction.has("title")) { result.setTitle(jsonAction.getString("title")); } - + if (jsonAction.has("parameterValues")) { JSONObject jsonParameterValues = jsonAction.getJSONObject("parameterValues"); - result.setParameterValues(parseJsonParameterValues(jsonParameterValues)); + result.setParameterValues(parseJsonParameterValues(jsonParameterValues, result.getActionDefinitionName(), true)); } - + if (jsonAction.has("executeAsync")) { result.setExecuteAsynchronously(jsonAction.getBoolean("executeAsync")); } - + if (jsonAction.has("runAsUser")) { result.setRunAsUser(jsonAction.getString("runAsUser")); } - + if (jsonAction.has("actions")) { JSONArray jsonActions = jsonAction.getJSONArray("actions"); if (jsonActions.length() == 0) { // empty array was sent -> clear list - ((CompositeActionImpl)result).getActions().clear(); + ((CompositeActionImpl) result).getActions().clear(); } else { - List existingActions = ((CompositeActionImpl)result).getActions(); - List newActions = new ArrayList(); - + List existingActions = ((CompositeActionImpl) result).getActions(); + List newActions = new ArrayList(); + for (int i = 0; i < jsonActions.length(); i++) { JSONObject innerJsonAction = jsonActions.getJSONObject(i); - + if (innerJsonAction.has("id")) { // update existing object String actionId = innerJsonAction.getString("id"); - + Action existingAction = getAction(existingActions, actionId); existingActions.remove(existingAction); - - Action updatedAction = updateActionFromJson(innerJsonAction, (ActionImpl)existingAction); - newActions.add(updatedAction); + + Action updatedAction = updateActionFromJson(innerJsonAction, (ActionImpl) existingAction); + newActions.add(updatedAction); } else { //create new action as id was not sent - newActions.add(parseJsonAction(innerJsonAction)); - } + newActions.add(parseJsonAction(innerJsonAction)); + } } existingActions.clear(); - + for (Action action : newActions) { existingActions.add(action); } } } - + if (jsonAction.has("conditions")) - { + { JSONArray jsonConditions = jsonAction.getJSONArray("conditions"); - + if (jsonConditions.length() == 0) { // empty array was sent -> clear list @@ -271,20 +268,20 @@ public class RulePut extends RulePost { List existingConditions = result.getActionConditions(); List newConditions = new ArrayList(); - + for (int i = 0; i < jsonConditions.length(); i++) { - JSONObject jsonCondition = jsonConditions.getJSONObject(i); - + JSONObject jsonCondition = jsonConditions.getJSONObject(i); + if (jsonCondition.has("id")) - { + { // update existing object String conditionId = jsonCondition.getString("id"); - + ActionCondition existingCondition = getCondition(existingConditions, conditionId); existingConditions.remove(existingCondition); - - ActionCondition updatedActionCondition = updateActionConditionFromJson(jsonCondition, (ActionConditionImpl)existingCondition); + + ActionCondition updatedActionCondition = updateActionConditionFromJson(jsonCondition, (ActionConditionImpl) existingCondition); newConditions.add(updatedActionCondition); } else @@ -292,31 +289,31 @@ public class RulePut extends RulePost // create new object as id was not sent newConditions.add(parseJsonActionCondition(jsonCondition)); } - } - + } + existingConditions.clear(); - + for (ActionCondition condition : newConditions) { existingConditions.add(condition); } - } - } - + } + } + if (jsonAction.has("compensatingAction")) { JSONObject jsonCompensatingAction = jsonAction.getJSONObject("compensatingAction"); - Action compensatingAction = updateActionFromJson(jsonCompensatingAction, (ActionImpl)actionToUpdate.getCompensatingAction()); - + Action compensatingAction = updateActionFromJson(jsonCompensatingAction, (ActionImpl) actionToUpdate.getCompensatingAction()); + actionToUpdate.setCompensatingAction(compensatingAction); } return result; } - + protected ActionCondition updateActionConditionFromJson(JSONObject jsonCondition, ActionConditionImpl conditionToUpdate) throws JSONException { ActionConditionImpl result = null; - + if (jsonCondition.has("id")) { // update exiting object @@ -328,21 +325,21 @@ public class RulePut extends RulePost result = parseJsonActionCondition(jsonCondition); return result; } - + if (jsonCondition.has("invertCondition")) { result.setInvertCondition(jsonCondition.getBoolean("invertCondition")); } - + if (jsonCondition.has("parameterValues")) { JSONObject jsonParameterValues = jsonCondition.getJSONObject("parameterValues"); - result.setParameterValues(parseJsonParameterValues(jsonParameterValues)); + result.setParameterValues(parseJsonParameterValues(jsonParameterValues, result.getActionConditionDefinitionName(), false)); } - + return result; } - + private Action getAction(List actions, String id) { Action result = null; @@ -354,22 +351,22 @@ public class RulePut extends RulePost break; } } - + return result; } - + private ActionCondition getCondition(List conditions, String id) { - ActionCondition result = null; + ActionCondition result = null; for (ActionCondition сondition : conditions) { if (сondition.getId().equalsIgnoreCase(id)) { result = сondition; break; - } + } } - - return result; + + return result; } } diff --git a/source/java/org/alfresco/repo/web/scripts/rule/RuleServiceTest.java b/source/java/org/alfresco/repo/web/scripts/rule/RuleServiceTest.java index 61b17c00ee..90d2818392 100755 --- a/source/java/org/alfresco/repo/web/scripts/rule/RuleServiceTest.java +++ b/source/java/org/alfresco/repo/web/scripts/rule/RuleServiceTest.java @@ -28,18 +28,16 @@ import java.text.MessageFormat; import java.util.List; import org.alfresco.model.ContentModel; -import org.alfresco.repo.rule.RuleModel; import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.web.scripts.BaseWebScriptTest; +import org.alfresco.service.cmr.action.ActionService; +import org.alfresco.service.cmr.action.ParameterConstraint; import org.alfresco.service.cmr.model.FileFolderService; -import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.rule.Rule; import org.alfresco.service.cmr.rule.RuleService; -import org.alfresco.service.cmr.search.SearchService; -import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.json.JSONArray; import org.json.JSONException; @@ -62,310 +60,342 @@ public class RuleServiceTest extends BaseWebScriptTest private static final String URL_RULETYPES = "/api/ruletypes"; private static final String URL_ACTIONDEFINITIONS = "/api/actiondefinitions"; private static final String URL_ACTIONCONDITIONDEFINITIONS = "/api/actionconditiondefinitions"; - + private static final String URL_ACTIONCONSTRAINTS = "/api/actionConstraints"; private static final String URL_ACTIONCONSTRAINT = "/api/actionConstraints/{0}"; - + private static final String URL_QUEUE_ACTION = "/api/actionQueue?async={0}"; - + private static final String URL_RULES = "/api/node/{0}/{1}/{2}/ruleset/rules"; + private static final String URL_INHERITED_RULES = "/api/node/{0}/{1}/{2}/ruleset/inheritedrules"; private static final String URL_RULESET = "/api/node/{0}/{1}/{2}/ruleset"; private static final String URL_RULE = "/api/node/{0}/{1}/{2}/ruleset/rules/{3}"; - + + private static final String TEST_STORE_IDENTIFIER = "test_store-" + System.currentTimeMillis(); private static final String TEST_FOLDER = "test_folder-" + System.currentTimeMillis(); - - private static final String COMPANY_HOME_PATH = "/app:company_home"; - + private static final String TEST_FOLDER_2 = "test_folder-2-" + System.currentTimeMillis(); + private NodeService nodeService; private FileFolderService fileFolderService; - private NamespaceService namespaceService; - private SearchService searchService; private AuthenticationComponent authenticationComponent; private RuleService ruleService; - + private ActionService actionService; + private NodeRef testNodeRef; - private NodeRef companyHome; - + private NodeRef testNodeRef2; + private NodeRef testWorkNodeRef; + @Override protected void setUp() throws Exception - { - super.setUp(); - this.nodeService = (NodeService)getServer().getApplicationContext().getBean("NodeService"); - this.fileFolderService = (FileFolderService)getServer().getApplicationContext().getBean("FileFolderService"); - this.namespaceService = (NamespaceService)getServer().getApplicationContext().getBean("NamespaceService"); - this.searchService = (SearchService)getServer().getApplicationContext().getBean("SearchService"); - this.ruleService = (RuleService)getServer().getApplicationContext().getBean("RuleService"); - this.authenticationComponent = (AuthenticationComponent)getServer().getApplicationContext().getBean("authenticationComponent"); - - this.authenticationComponent.setSystemUserAsCurrentUser(); - - createTestFolder(); - - assertNotNull(testNodeRef); - assertNotNull(companyHome); - } - - private void createTestFolder() { - NodeRef storeRootNodeRef = nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE); - - NodeRef companyHomeNodeRef; + super.setUp(); + this.nodeService = (NodeService) getServer().getApplicationContext().getBean("NodeService"); + this.fileFolderService = (FileFolderService) getServer().getApplicationContext().getBean("FileFolderService"); + this.ruleService = (RuleService) getServer().getApplicationContext().getBean("RuleService"); + this.actionService = (ActionService) getServer().getApplicationContext().getBean("ActionService"); + this.authenticationComponent = (AuthenticationComponent) getServer().getApplicationContext().getBean("authenticationComponent"); - List nodeRefs = searchService.selectNodes(storeRootNodeRef, COMPANY_HOME_PATH, null, namespaceService, false); - - if (nodeRefs.size() > 1) + this.authenticationComponent.setSystemUserAsCurrentUser(); + + createTestFolders(); + + assertNotNull(testWorkNodeRef); + assertNotNull(testNodeRef); + assertNotNull(testNodeRef2); + } + + private void createTestFolders() + { + StoreRef testStore = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, TEST_STORE_IDENTIFIER); + + if (!nodeService.exists(testStore)) { - throw new RuntimeException("Multiple possible roots for : \n" + " root path: " + COMPANY_HOME_PATH + "\n" + " results: " + nodeRefs); + testStore = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, TEST_STORE_IDENTIFIER); } - else if (nodeRefs.size() == 0) + + NodeRef rootNodeRef = nodeService.getRootNode(testStore); + + testWorkNodeRef = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{test}testnode"), ContentModel.TYPE_FOLDER).getChildRef(); + + testNodeRef = fileFolderService.create(testWorkNodeRef, TEST_FOLDER, ContentModel.TYPE_FOLDER).getNodeRef(); + testNodeRef2 = fileFolderService.create(testWorkNodeRef, TEST_FOLDER_2, ContentModel.TYPE_FOLDER).getNodeRef(); + } + + private String formatRulesUrl(NodeRef nodeRef, boolean inherited) + { + if (inherited) { - throw new RuntimeException("No root found for : \n" + " root path: " + COMPANY_HOME_PATH); + return MessageFormat.format(URL_INHERITED_RULES, nodeRef.getStoreRef().getProtocol(), nodeRef.getStoreRef().getIdentifier(), nodeRef.getId()); } else { - companyHomeNodeRef = nodeRefs.get(0); - companyHome = companyHomeNodeRef; + return MessageFormat.format(URL_RULES, nodeRef.getStoreRef().getProtocol(), nodeRef.getStoreRef().getIdentifier(), nodeRef.getId()); } - FileInfo fileInfo = fileFolderService.create(companyHomeNodeRef, TEST_FOLDER, ContentModel.TYPE_FOLDER); - - testNodeRef = fileInfo.getNodeRef(); - - this.nodeService.addAspect(testNodeRef, RuleModel.ASPECT_RULES, null); - } - - private String formatRulesUrl(NodeRef nodeRef) - { - return MessageFormat.format(URL_RULES, nodeRef.getStoreRef().getProtocol(), nodeRef.getStoreRef().getIdentifier(), nodeRef.getId()); } - + private String formatRulesetUrl(NodeRef nodeRef) { return MessageFormat.format(URL_RULESET, nodeRef.getStoreRef().getProtocol(), nodeRef.getStoreRef().getIdentifier(), nodeRef.getId()); } - + private String formateRuleUrl(NodeRef nodeRef, String ruleId) { return MessageFormat.format(URL_RULE, nodeRef.getStoreRef().getProtocol(), nodeRef.getStoreRef().getIdentifier(), nodeRef.getId(), ruleId); } - + private String formateActionConstraintUrl(String name) { return MessageFormat.format(URL_ACTIONCONSTRAINT, name); } - + private String formateQueueActionUrl(boolean async) { return MessageFormat.format(URL_QUEUE_ACTION, async); } - + @Override protected void tearDown() throws Exception { super.tearDown(); - - fileFolderService.delete(testNodeRef); + nodeService.deleteNode(testNodeRef2); + nodeService.deleteNode(testNodeRef); + nodeService.deleteNode(testWorkNodeRef); this.authenticationComponent.clearCurrentSecurityContext(); } - - private JSONObject createRule() throws Exception + + private JSONObject createRule(NodeRef ruleOwnerNodeRef) throws Exception { JSONObject jsonRule = buildTestRule(); - - Response response = sendRequest(new PostRequest(formatRulesUrl(testNodeRef), jsonRule.toString(), "application/json"), 200); - - JSONObject result = new JSONObject(response.getContentAsString()); - + + Response response = sendRequest(new PostRequest(formatRulesUrl(ruleOwnerNodeRef, false), jsonRule.toString(), "application/json"), 200); + + JSONObject result = new JSONObject(response.getContentAsString()); + return result; } - - private JSONArray getNodeRules() throws Exception + + private JSONArray getNodeRules(NodeRef nodeRef, boolean inherited) throws Exception { - Response response = sendRequest(new GetRequest(formatRulesUrl(testNodeRef)), 200); + Response response = sendRequest(new GetRequest(formatRulesUrl(nodeRef, inherited)), 200); JSONObject result = new JSONObject(response.getContentAsString()); - + assertNotNull(result); - + assertTrue(result.has("data")); - + JSONArray data = result.getJSONArray("data"); - + return data; } - + private void checkRuleComplete(JSONObject result) throws Exception { - assertNotNull("Response is null.", result); - + assertNotNull("Response is null.", result); + // if id present in response -> rule was created assertTrue(result.has("id")); - + assertEquals(result.getString("title"), "test_rule"); assertEquals(result.getString("description"), "this is description for test_rule"); - + JSONArray ruleType = result.getJSONArray("ruleType"); - - assertEquals(1, ruleType.length()); + + assertEquals(1, ruleType.length()); assertEquals("outbound", ruleType.getString(0)); - - assertFalse(result.getBoolean("applyToChildren")); + + assertTrue(result.getBoolean("applyToChildren")); assertFalse(result.getBoolean("executeAsynchronously")); assertFalse(result.getBoolean("disabled")); + assertTrue(result.has("owningNode")); + JSONObject owningNode = result.getJSONObject("owningNode"); + assertTrue(owningNode.has("nodeRef")); + assertTrue(owningNode.has("name")); assertTrue(result.has("url")); - + JSONObject jsonAction = result.getJSONObject("action"); - + assertTrue(jsonAction.has("id")); - + assertEquals(jsonAction.getString("actionDefinitionName"), "composite-action"); assertEquals(jsonAction.getString("description"), "this is description for composite-action"); assertEquals(jsonAction.getString("title"), "test_title"); - + assertTrue(jsonAction.has("parameterValues")); - - assertTrue(jsonAction.getBoolean("executeAsync")); - + + assertTrue(jsonAction.getBoolean("executeAsync")); + assertTrue(jsonAction.has("actions")); assertTrue(jsonAction.has("conditions")); assertTrue(jsonAction.has("compensatingAction")); assertTrue(jsonAction.has("url")); } - + private void checkRuleSummary(JSONObject result) throws Exception { assertNotNull("Response is null.", result); - + assertTrue(result.has("data")); - + JSONObject data = result.getJSONObject("data"); - + // if id present in response -> rule was created assertTrue(data.has("id")); - + assertEquals(data.getString("title"), "test_rule"); assertEquals(data.getString("description"), "this is description for test_rule"); - + JSONArray ruleType = data.getJSONArray("ruleType"); - - assertEquals(1, ruleType.length()); + + assertEquals(1, ruleType.length()); assertEquals("outbound", ruleType.getString(0)); - + assertFalse(data.getBoolean("disabled")); assertTrue(data.has("url")); - + } - + private void checkUpdatedRule(JSONObject before, JSONObject after) throws JSONException { // check saving of basic feilds assertEquals("It seams that 'id' is not correct", before.getString("id"), after.getString("id")); - + assertEquals("It seams that 'title' was not saved", before.getString("title"), after.getString("title")); - + assertEquals("It seams that 'description' was not saved", before.getString("description"), after.getString("description")); - + assertEquals("It seams that 'ruleType' was not saved", before.getJSONArray("ruleType").length(), after.getJSONArray("ruleType").length()); - + assertEquals(before.getBoolean("applyToChildren"), after.getBoolean("applyToChildren")); assertEquals(before.getBoolean("executeAsynchronously"), after.getBoolean("executeAsynchronously")); assertEquals(before.getBoolean("disabled"), after.getBoolean("disabled")); - + // check saving of collections JSONObject afterAction = after.getJSONObject("action"); - + // we didn't change actions collection assertEquals(1, afterAction.getJSONArray("actions").length()); - + // conditions should be empty (should not present in response), - assertFalse(afterAction.has("conditions")); - + assertFalse(afterAction.has("conditions")); + assertEquals(before.has("url"), after.has("url")); } - - private void checkRuleset(JSONObject result, String ruleId) throws Exception + + private void checkRuleset(JSONObject result, int rulesCount, String[] ruleIds, int inhRulesCount, String[] parentRuleIds) throws Exception { assertNotNull("Response is null.", result); - + assertTrue(result.has("data")); - + JSONObject data = result.getJSONObject("data"); - - assertTrue(data.has("rules")); - - assertEquals(1, data.getJSONArray("rules").length()); - - JSONObject ruleSummary = data.getJSONArray("rules").getJSONObject(0); - - assertEquals(ruleId, ruleSummary.getString("id")); - - assertTrue(ruleSummary.has("title")); - assertTrue(ruleSummary.has("ruleType")); - assertTrue(ruleSummary.has("disabled")); - assertTrue(ruleSummary.has("url")); - - assertFalse(data.has("inheritedRules")); - + + if (data.has("rules")) + { + JSONArray rulesArray = data.getJSONArray("rules"); + + assertEquals(rulesCount, rulesArray.length()); + + for (int i = 0; i < rulesArray.length(); i++) + { + JSONObject ruleSum = rulesArray.getJSONObject(i); + assertTrue(ruleSum.has("id")); + assertEquals(ruleIds[i], ruleSum.getString("id")); + assertTrue(ruleSum.has("title")); + assertTrue(ruleSum.has("ruleType")); + assertTrue(ruleSum.has("disabled")); + assertTrue(ruleSum.has("owningNode")); + JSONObject owningNode = ruleSum.getJSONObject("owningNode"); + assertTrue(owningNode.has("nodeRef")); + assertTrue(owningNode.has("name")); + assertTrue(ruleSum.has("url")); + } + } + + if (data.has("inheritedRules")) + { + JSONArray inheritedRulesArray = data.getJSONArray("inheritedRules"); + + assertEquals(inhRulesCount, inheritedRulesArray.length()); + + for (int i = 0; i < inheritedRulesArray.length(); i++) + { + JSONObject ruleSum = inheritedRulesArray.getJSONObject(i); + assertTrue(ruleSum.has("id")); + assertEquals(parentRuleIds[i], ruleSum.getString("id")); + assertTrue(ruleSum.has("title")); + assertTrue(ruleSum.has("ruleType")); + assertTrue(ruleSum.has("disabled")); + assertTrue(ruleSum.has("owningNode")); + JSONObject owningNode = ruleSum.getJSONObject("owningNode"); + assertTrue(owningNode.has("nodeRef")); + assertTrue(owningNode.has("name")); + assertTrue(ruleSum.has("url")); + } + } + + assertTrue(data.has("url")); } - + public void testGetRuleTypes() throws Exception { Response response = sendRequest(new GetRequest(URL_RULETYPES), 200); JSONObject result = new JSONObject(response.getContentAsString()); - + assertNotNull(result); - + assertTrue(result.has("data")); - + JSONArray data = result.getJSONArray("data"); - + for (int i = 0; i < data.length(); i++) { JSONObject ruleType = data.getJSONObject(i); - + assertTrue(ruleType.has("name")); assertTrue(ruleType.has("displayLabel")); assertTrue(ruleType.has("url")); } } - + public void testGetActionDefinitions() throws Exception { Response response = sendRequest(new GetRequest(URL_ACTIONDEFINITIONS), 200); JSONObject result = new JSONObject(response.getContentAsString()); - + assertNotNull(result); - + assertTrue(result.has("data")); - + JSONArray data = result.getJSONArray("data"); - + for (int i = 0; i < data.length(); i++) { JSONObject actionDefinition = data.getJSONObject(i); - + assertTrue(actionDefinition.has("name")); assertTrue(actionDefinition.has("displayLabel")); assertTrue(actionDefinition.has("description")); assertTrue(actionDefinition.has("adHocPropertiesAllowed")); assertTrue(actionDefinition.has("parameterDefinitions")); - assertTrue(actionDefinition.has("applicableTypes")); + assertTrue(actionDefinition.has("applicableTypes")); } } - + public void testGetActionConditionDefinitions() throws Exception { Response response = sendRequest(new GetRequest(URL_ACTIONCONDITIONDEFINITIONS), 200); JSONObject result = new JSONObject(response.getContentAsString()); - + assertNotNull(result); - + assertTrue(result.has("data")); - + JSONArray data = result.getJSONArray("data"); - + for (int i = 0; i < data.length(); i++) { JSONObject actionConditionDefinition = data.getJSONObject(i); - + assertTrue(actionConditionDefinition.has("name")); assertTrue(actionConditionDefinition.has("displayLabel")); assertTrue(actionConditionDefinition.has("description")); @@ -378,26 +408,26 @@ public class RuleServiceTest extends BaseWebScriptTest { Response response = sendRequest(new GetRequest(URL_ACTIONCONSTRAINTS), 200); JSONObject result = new JSONObject(response.getContentAsString()); - + assertNotNull(result); - + assertTrue(result.has("data")); - - JSONArray data = result.getJSONArray("data"); - + + JSONArray data = result.getJSONArray("data"); + for (int i = 0; i < data.length(); i++) { JSONObject actionConstraint = data.getJSONObject(i); - + assertTrue(actionConstraint.has("name")); assertTrue(actionConstraint.has("values")); - + JSONArray values = actionConstraint.getJSONArray("values"); - + for (int j = 0; j < values.length(); j++) { JSONObject value = values.getJSONObject(j); - + assertTrue(value.has("value")); assertTrue(value.has("displayLabel")); } @@ -406,65 +436,75 @@ public class RuleServiceTest extends BaseWebScriptTest public void testGetActionConstraint() throws Exception { - Response response = sendRequest(new GetRequest(formateActionConstraintUrl("ac-compare-operations")), 200); + + List constraints = actionService.getParameterConstraints(); + + if (constraints.size() == 0) + { + return; + } + + String name = constraints.get(0).getName(); + + Response response = sendRequest(new GetRequest(formateActionConstraintUrl(name)), 200); JSONObject result = new JSONObject(response.getContentAsString()); - + assertNotNull(result); - - assertTrue(result.has("data")); - + + assertTrue(result.has("data")); + JSONObject data = result.getJSONObject("data"); - + assertTrue(data.has("name")); assertTrue(data.has("values")); - + JSONArray values = data.getJSONArray("values"); - + for (int i = 0; i < values.length(); i++) { JSONObject value = values.getJSONObject(i); - + assertTrue(value.has("value")); assertTrue(value.has("displayLabel")); } } - + public void testQueueAction() throws Exception { String url = formateQueueActionUrl(false); - - JSONObject copyAction = buildCopyAction(companyHome); - + + JSONObject copyAction = buildCopyAction(testWorkNodeRef); + copyAction.put("actionedUponNode", testNodeRef); - + // execute before response (should be successful) Response successResponse = sendRequest(new PostRequest(url, copyAction.toString(), "application/json"), 200); - + JSONObject successResult = new JSONObject(successResponse.getContentAsString()); - + assertNotNull(successResult); - + assertTrue(successResult.has("data")); - + JSONObject successData = successResult.getJSONObject("data"); - + assertTrue(successData.has("status")); assertEquals("success", successData.getString("status")); assertTrue(successData.has("actionedUponNode")); assertFalse(successData.has("exception")); assertTrue(successData.has("action")); - + // execute before response (should fail) Response failResponse = sendRequest(new PostRequest(url, copyAction.toString(), "application/json"), 200); - + JSONObject failResult = new JSONObject(failResponse.getContentAsString()); - + assertNotNull(failResult); - + assertTrue(failResult.has("data")); - + JSONObject failData = failResult.getJSONObject("data"); - + assertTrue(failData.has("status")); assertEquals("fail", failData.getString("status")); assertTrue(failData.has("actionedUponNode")); @@ -473,225 +513,268 @@ public class RuleServiceTest extends BaseWebScriptTest assertTrue(exception.has("message")); assertTrue(exception.has("stackTrace")); assertTrue(failData.has("action")); - + // execute after response (should fail but error should not present in response) String asyncUrl = formateQueueActionUrl(true); Response response = sendRequest(new PostRequest(asyncUrl, copyAction.toString(), "application/json"), 200); - + // wait while action executed Thread.sleep(1000); - + JSONObject result = new JSONObject(response.getContentAsString()); - + assertNotNull(result); - + assertTrue(result.has("data")); - + JSONObject data = result.getJSONObject("data"); - + assertTrue(data.has("status")); assertEquals("queued", data.getString("status")); assertTrue(data.has("actionedUponNode")); assertFalse(data.has("exception")); assertTrue(data.has("action")); } - + public void testCreateRule() throws Exception { - JSONObject result = createRule(); - - checkRuleSummary(result); - + JSONObject result = createRule(testNodeRef); + + checkRuleSummary(result); + List rules = ruleService.getRules(testNodeRef); - + assertEquals(1, rules.size()); - + } - + public void testGetRulesCollection() throws Exception { - JSONArray data = getNodeRules(); - + JSONArray data = getNodeRules(testNodeRef, false); + assertEquals(0, data.length()); - - createRule(); - - data = getNodeRules(); - + + createRule(testNodeRef); + + data = getNodeRules(testNodeRef, false); + assertEquals(1, data.length()); - } - + + for (int i = 0; i < data.length(); i++) + { + JSONObject ruleSum = data.getJSONObject(i); + assertTrue(ruleSum.has("id")); + assertTrue(ruleSum.has("title")); + assertTrue(ruleSum.has("ruleType")); + assertTrue(ruleSum.has("disabled")); + assertTrue(ruleSum.has("owningNode")); + JSONObject owningNode = ruleSum.getJSONObject("owningNode"); + assertTrue(owningNode.has("nodeRef")); + assertTrue(owningNode.has("name")); + assertTrue(ruleSum.has("url")); + } + } + + public void testGetInheritedRulesCollection() throws Exception + { + JSONArray data = getNodeRules(testNodeRef, true); + + assertEquals(0, data.length()); + + createRule(testWorkNodeRef); + + data = getNodeRules(testNodeRef, true); + + assertEquals(1, data.length()); + + for (int i = 0; i < data.length(); i++) + { + JSONObject ruleSum = data.getJSONObject(i); + assertTrue(ruleSum.has("id")); + assertTrue(ruleSum.has("title")); + assertTrue(ruleSum.has("ruleType")); + assertTrue(ruleSum.has("disabled")); + assertTrue(ruleSum.has("owningNode")); + JSONObject owningNode = ruleSum.getJSONObject("owningNode"); + assertTrue(owningNode.has("nodeRef")); + assertTrue(owningNode.has("name")); + assertTrue(ruleSum.has("url")); + } + } + public void testGetRuleset() throws Exception { - JSONObject jsonRule = createRule(); - - String ruleId = jsonRule.getJSONObject("data").getString("id"); - + JSONObject parentRule = createRule(testWorkNodeRef); + String[] parentRuleIds = new String[] { parentRule.getJSONObject("data").getString("id") }; + + JSONObject jsonRule = createRule(testNodeRef); + String[] ruleIds = new String[] { jsonRule.getJSONObject("data").getString("id") }; + Response response = sendRequest(new GetRequest(formatRulesetUrl(testNodeRef)), 200); JSONObject result = new JSONObject(response.getContentAsString()); - - checkRuleset(result, ruleId); + + checkRuleset(result, 1, ruleIds, 1, parentRuleIds); } - - public void testGetRuleDetails() throws Exception + + public void testGetRuleDetails() throws Exception { - JSONObject jsonRule = createRule(); - + JSONObject jsonRule = createRule(testNodeRef); + String ruleId = jsonRule.getJSONObject("data").getString("id"); - + Response response = sendRequest(new GetRequest(formateRuleUrl(testNodeRef, ruleId)), 200); JSONObject result = new JSONObject(response.getContentAsString()); - + checkRuleComplete(result); } - + public void testUpdateRule() throws Exception { - JSONObject jsonRule = createRule(); - + JSONObject jsonRule = createRule(testNodeRef); + String ruleId = jsonRule.getJSONObject("data").getString("id"); - + Response getResponse = sendRequest(new GetRequest(formateRuleUrl(testNodeRef, ruleId)), 200); - + JSONObject before = new JSONObject(getResponse.getContentAsString()); - + // do some changes before.put("description", "this is modified description for test_rule"); - + // do some changes for action object JSONObject beforeAction = before.getJSONObject("action"); // no changes for actions list beforeAction.remove("actions"); // clear conditions beforeAction.put("conditions", new JSONArray()); - + Response putResponse = sendRequest(new PutRequest(formateRuleUrl(testNodeRef, ruleId), before.toString(), "application/json"), 200); - + JSONObject after = new JSONObject(putResponse.getContentAsString()); - + // sent and retrieved objects should be the same (except ids and urls) // this means that all changes was saved checkUpdatedRule(before, after); } - + public void testDeleteRule() throws Exception { - JSONObject jsonRule = createRule(); - + JSONObject jsonRule = createRule(testNodeRef); + assertEquals(1, ruleService.getRules(testNodeRef).size()); - + String ruleId = jsonRule.getJSONObject("data").getString("id"); - + Response response = sendRequest(new DeleteRequest(formateRuleUrl(testNodeRef, ruleId)), 200); JSONObject result = new JSONObject(response.getContentAsString()); - + assertNotNull(result); - + assertTrue(result.has("success")); - + boolean success = result.getBoolean("success"); - + assertTrue(success); - + // no more rules present assertEquals(0, ruleService.getRules(testNodeRef).size()); } - - private JSONObject buildCopyAction(NodeRef destination) throws JSONException + + private JSONObject buildCopyAction(NodeRef destination) throws JSONException { JSONObject result = new JSONObject(); - + // add actionDefinitionName result.put("actionDefinitionName", "copy"); - + // build parameterValues JSONObject parameterValues = new JSONObject(); parameterValues.put("destination-folder", destination); - parameterValues.put("assoc-name", QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "copy")); - parameterValues.put("assoc-type", ContentModel.ASSOC_CONTAINS); - + parameterValues.put("assoc-name", "cm:copy"); + parameterValues.put("assoc-type", "cm:contains"); + // add parameterValues result.put("parameterValues", parameterValues); - + // add executeAsync result.put("executeAsync", false); - + return result; } - + private JSONObject buildTestRule() throws JSONException { JSONObject result = new JSONObject(); - + result.put("title", "test_rule"); result.put("description", "this is description for test_rule"); - + JSONArray ruleType = new JSONArray(); ruleType.put("outbound"); - + result.put("ruleType", ruleType); - - result.put("applyToChildren", false); - + + result.put("applyToChildren", true); + result.put("executeAsynchronously", false); - + result.put("disabled", false); - + result.put("action", buildTestAction("composite-action", true, true)); - + return result; } - + private JSONObject buildTestAction(String actionName, boolean addActions, boolean addCompensatingAction) throws JSONException { JSONObject result = new JSONObject(); - + result.put("actionDefinitionName", actionName); result.put("description", "this is description for " + actionName); result.put("title", "test_title"); - + JSONObject parameterValues = new JSONObject(); parameterValues.put("test_name", "test_value"); - + result.put("parameterValues", parameterValues); - + result.put("executeAsync", addActions); - + if (addActions) { JSONArray actions = new JSONArray(); - + actions.put(buildTestAction("counter", false, false)); - + result.put("actions", actions); } - + JSONArray conditions = new JSONArray(); - + conditions.put(buildTestCondition("no-condition")); - + result.put("conditions", conditions); - + if (addCompensatingAction) { - result.put("compensatingAction", buildTestAction("executeScript", false, false)); + result.put("compensatingAction", buildTestAction("script", false, false)); } - + return result; } - - private JSONObject buildTestCondition(String conditionName) throws JSONException + + private JSONObject buildTestCondition(String conditionName) throws JSONException { JSONObject result = new JSONObject(); - + result.put("conditionDefinitionName", conditionName); result.put("invertCondition", false); - + JSONObject parameterValues = new JSONObject(); parameterValues.put("test_name", "test_value"); - + result.put("parameterValues", parameterValues); - + return result; } } diff --git a/source/java/org/alfresco/repo/web/scripts/rule/RuleTypesGet.java b/source/java/org/alfresco/repo/web/scripts/rule/RuleTypesGet.java index 338567accc..e4ca9d161e 100755 --- a/source/java/org/alfresco/repo/web/scripts/rule/RuleTypesGet.java +++ b/source/java/org/alfresco/repo/web/scripts/rule/RuleTypesGet.java @@ -44,17 +44,17 @@ public class RuleTypesGet extends AbstractRuleWebScript @SuppressWarnings("unused") private static Log logger = LogFactory.getLog(RuleTypesGet.class); - + @Override protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) { Map model = new HashMap(); - + // get all rule types List ruletypes = ruleService.getRuleTypes(); - + model.put("ruletypes", ruletypes); - + return model; } } diff --git a/source/java/org/alfresco/repo/web/scripts/rule/RulesGet.java b/source/java/org/alfresco/repo/web/scripts/rule/RulesGet.java index 25d6da1ddb..8bba31b732 100755 --- a/source/java/org/alfresco/repo/web/scripts/rule/RulesGet.java +++ b/source/java/org/alfresco/repo/web/scripts/rule/RulesGet.java @@ -24,10 +24,12 @@ */ package org.alfresco.repo.web.scripts.rule; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.alfresco.repo.web.scripts.rule.ruleset.RuleRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.rule.Rule; import org.alfresco.service.cmr.rule.RuleType; @@ -45,31 +47,35 @@ public class RulesGet extends AbstractRuleWebScript { @SuppressWarnings("unused") private static Log logger = LogFactory.getLog(RulesGet.class); - + @Override protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) - { + { Map model = new HashMap(); // get request parameters NodeRef nodeRef = parseRequestForNodeRef(req); String ruleType = req.getParameter("ruleType"); - + RuleType type = ruleService.getRuleType(ruleType); - + if (type == null) { ruleType = null; } - - // get all rules (including inherited) filtered by rule type - List rules = ruleService.getRules(nodeRef, true, ruleType); - - model.put("rules", rules); - model.put("storeType", nodeRef.getStoreRef().getProtocol()); - model.put("storeId", nodeRef.getStoreRef().getIdentifier()); - model.put("id", nodeRef.getId()); - + + // get all rules (excluding inherited) filtered by rule type + List rules = ruleService.getRules(nodeRef, false, ruleType); + + List ruleRefs = new ArrayList(); + + for (Rule rule : rules) + { + ruleRefs.add(new RuleRef(rule, fileFolderService.getFileInfo(ruleService.getOwningNodeRef(rule)))); + } + + model.put("ruleRefs", ruleRefs); + return model; } } diff --git a/source/java/org/alfresco/repo/web/scripts/rule/RulesetGet.java b/source/java/org/alfresco/repo/web/scripts/rule/RulesetGet.java index 7dae30a984..12286c29eb 100755 --- a/source/java/org/alfresco/repo/web/scripts/rule/RulesetGet.java +++ b/source/java/org/alfresco/repo/web/scripts/rule/RulesetGet.java @@ -51,52 +51,55 @@ public class RulesetGet extends AbstractRuleWebScript @Override protected Map executeImpl(WebScriptRequest req, Status status, Cache cache) - { + { Map model = new HashMap(); - + // get request parameters NodeRef nodeRef = parseRequestForNodeRef(req); String ruleType = req.getParameter("ruleType"); - + RuleType type = ruleService.getRuleType(ruleType); - + if (type == null) { ruleType = null; } - + RuleSet ruleset = new RuleSet(); - + // get all "owned" rules List ownedRules = ruleService.getRules(nodeRef, false, ruleType); - + // get all rules (including inherited) List inheritedRules = ruleService.getRules(nodeRef, true, ruleType); - + // remove "owned" rules inheritedRules.removeAll(ownedRules); - + List rulesToSet = new ArrayList(); - + for (Rule rule : ownedRules) { - rulesToSet.add(new RuleRef(rule, ruleService.getOwningNodeRef(rule))); - } + rulesToSet.add(new RuleRef(rule, fileFolderService.getFileInfo(ruleService.getOwningNodeRef(rule)))); + } ruleset.setRules(rulesToSet); - - + List inheritedRulesToSet = new ArrayList(); - + for (Rule rule : inheritedRules) { - inheritedRulesToSet.add(new RuleRef(rule, ruleService.getOwningNodeRef(rule))); - } + inheritedRulesToSet.add(new RuleRef(rule, fileFolderService.getFileInfo(ruleService.getOwningNodeRef(rule)))); + } ruleset.setInheritedRules(inheritedRulesToSet); - + + ruleset.setLinkedToRuleSet(ruleService.getLinkedToRuleNode(nodeRef)); + + ruleset.setLinkedFromRuleSets(ruleService.getLinkedFromRuleNodes(nodeRef)); + ruleset.setRulesetNodeRef(nodeRef); - + model.put("ruleset", ruleset); - + return model; } } diff --git a/source/java/org/alfresco/repo/web/scripts/rule/ruleset/RuleRef.java b/source/java/org/alfresco/repo/web/scripts/rule/ruleset/RuleRef.java index f01f3572cc..c3288357a4 100755 --- a/source/java/org/alfresco/repo/web/scripts/rule/ruleset/RuleRef.java +++ b/source/java/org/alfresco/repo/web/scripts/rule/ruleset/RuleRef.java @@ -24,11 +24,9 @@ */ package org.alfresco.repo.web.scripts.rule.ruleset; -import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.rule.Rule; - - /** * Rule object for REST API * @@ -40,17 +38,17 @@ public class RuleRef /** Serial version UID */ private static final long serialVersionUID = -923276130307938661L; - - private NodeRef owningNodeRef; - + + private FileInfo owningFileInfo; + private Rule rule; - - public RuleRef(Rule rule, NodeRef owningNodeRef) + + public RuleRef(Rule rule, FileInfo owningFileInfo) { this.rule = rule; - this.owningNodeRef = owningNodeRef; + this.owningFileInfo = owningFileInfo; } - + /** * Set the rule * @@ -60,7 +58,7 @@ public class RuleRef { this.rule = rule; } - + /** * Return the rule * @@ -70,24 +68,24 @@ public class RuleRef { return rule; } - + /** - * Set the owning node reference for rule + * Set the owning file info reference for rule * - * @param owningNodeRef the owning node reference to set + * @param owningNodeRef the owning file info reference to set */ - public void setOwningNodeRef(NodeRef owningNodeRef) + public void setOwningFileInfo(FileInfo owningFileInfo) { - this.owningNodeRef = owningNodeRef; + this.owningFileInfo = owningFileInfo; } - + /** - * Returns the owning node reference for a rule. + * Returns the owning file info reference for a rule. * - * @return the owning node reference + * @return the owning file info reference */ - public NodeRef getOwningNodeRef() + public FileInfo getOwningFileInfo() { - return owningNodeRef; + return owningFileInfo; } } diff --git a/source/java/org/alfresco/repo/web/scripts/rule/ruleset/RuleSet.java b/source/java/org/alfresco/repo/web/scripts/rule/ruleset/RuleSet.java index 7a7fa7052a..9f96757be3 100755 --- a/source/java/org/alfresco/repo/web/scripts/rule/ruleset/RuleSet.java +++ b/source/java/org/alfresco/repo/web/scripts/rule/ruleset/RuleSet.java @@ -35,19 +35,19 @@ import org.alfresco.service.cmr.repository.NodeRef; */ public class RuleSet implements Serializable { - + private static final long serialVersionUID = 6985140035928444095L; - + private List rules = null; - + private List inheritedRules = null; - + private NodeRef rulesetNodeRef; - + private NodeRef linkedToRuleSet; - + private List linkedFromRuleSets; - + /** * Set list of the rules "owned" by this rule set * @@ -57,7 +57,7 @@ public class RuleSet implements Serializable { this.rules = rules; } - + /** * Get list of the rules "owned" by this rule set * @@ -67,7 +67,7 @@ public class RuleSet implements Serializable { return rules; } - + /** * Set list of the rules inherited by this rule set from parent * @@ -77,7 +77,7 @@ public class RuleSet implements Serializable { this.inheritedRules = inheritedRules; } - + /** * Get list of the rules inherited by this rule set from parent * @@ -87,7 +87,7 @@ public class RuleSet implements Serializable { return inheritedRules; } - + /** * Set the nodeRef to which this ruleset belongs * @@ -97,7 +97,7 @@ public class RuleSet implements Serializable { this.rulesetNodeRef = rulesetNodeRef; } - + /** * Get the nodeRef to which this ruleset belongs * @@ -107,7 +107,7 @@ public class RuleSet implements Serializable { return rulesetNodeRef; } - + /** * Set the nodeRef to which this ruleset linked to * @@ -117,7 +117,7 @@ public class RuleSet implements Serializable { this.linkedToRuleSet = linkedToRuleSet; } - + /** * Get the nodeRef to which this ruleset linked to * @@ -127,7 +127,7 @@ public class RuleSet implements Serializable { return linkedToRuleSet; } - + /** * Set the list of nodeRefs that link to this ruleset * @@ -137,7 +137,7 @@ public class RuleSet implements Serializable { this.linkedFromRuleSets = linkedFromRuleSets; } - + /** * Get the list of nodeRefs that link to this ruleset *