From de853940891dccf88f64a86cb90fff4dc8adc32b Mon Sep 17 00:00:00 2001 From: Roy Wetherall Date: Sun, 7 Feb 2010 22:23:29 +0000 Subject: [PATCH] Merge DEV/BELARUS/HEAD-2010_01_18 to HEAD 18441 : Rest API (SAIL-196, SAIL-197, SAIL-198, SAIL-199, SAIL-202, SAIL-201) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@18487 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../actionconditiondefinitions.get.desc.xml | 8 + .../rule/actionconditiondefinitions.get.js | 7 + .../actionconditiondefinitions.get.json.ftl | 27 + .../rule/actiondefinitions.get.desc.xml | 8 + .../repository/rule/actiondefinitions.get.js | 7 + .../rule/actiondefinitions.get.json.ftl | 36 ++ .../repository/rule/rule.delete.desc.xml | 8 + .../repository/rule/rule.delete.json.ftl | 3 + .../repository/rule/rule.get.desc.xml | 8 + .../repository/rule/rule.get.json.ftl | 3 + .../org/alfresco/repository/rule/rule.lib.ftl | 105 ++++ .../repository/rule/rule.post.desc.xml | 8 + .../repository/rule/rule.post.json.ftl | 6 + .../repository/rule/rule.put.desc.xml | 8 + .../repository/rule/rule.put.json.ftl | 3 + .../repository/rule/rules.get.desc.xml | 8 + .../repository/rule/rules.get.json.ftl | 10 + .../repository/rule/ruleset.get.desc.xml | 8 + .../repository/rule/ruleset.get.json.ftl | 53 ++ .../repository/rule/ruletypes.get.desc.xml | 8 + .../alfresco/repository/rule/ruletypes.get.js | 7 + .../repository/rule/ruletypes.get.json.ftl | 12 + .../web-scripts-application-context.xml | 48 +- .../scripts/rule/AbstractRuleWebScript.java | 213 +++++++ .../rule/ActionConditionDefinitionsGet.java | 59 ++ .../scripts/rule/ActionDefinitionsGet.java | 59 ++ .../repo/web/scripts/rule/RuleDelete.java | 88 +++ .../repo/web/scripts/rule/RuleGet.java | 90 +++ .../repo/web/scripts/rule/RulePost.java | 313 +++++++++++ .../repo/web/scripts/rule/RulePut.java | 375 +++++++++++++ .../web/scripts/rule/RuleServiceTest.java | 531 ++++++++++++++++++ .../repo/web/scripts/rule/RuleTypesGet.java | 60 ++ .../repo/web/scripts/rule/RulesGet.java | 75 +++ .../repo/web/scripts/rule/RulesetGet.java | 102 ++++ .../web/scripts/rule/ruleset/RuleRef.java | 93 +++ .../web/scripts/rule/ruleset/RuleSet.java | 151 +++++ 36 files changed, 2607 insertions(+), 1 deletion(-) create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/actionconditiondefinitions.get.desc.xml create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/actionconditiondefinitions.get.js create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/actionconditiondefinitions.get.json.ftl create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/actiondefinitions.get.desc.xml create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/actiondefinitions.get.js create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/actiondefinitions.get.json.ftl create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.delete.desc.xml create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.delete.json.ftl create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.get.desc.xml create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.get.json.ftl create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.lib.ftl create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.post.desc.xml create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.post.json.ftl create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.put.desc.xml create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.put.json.ftl create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/rules.get.desc.xml create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/rules.get.json.ftl create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruleset.get.desc.xml create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruleset.get.json.ftl create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruletypes.get.desc.xml create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruletypes.get.js create mode 100755 config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruletypes.get.json.ftl create mode 100755 source/java/org/alfresco/repo/web/scripts/rule/AbstractRuleWebScript.java create mode 100755 source/java/org/alfresco/repo/web/scripts/rule/ActionConditionDefinitionsGet.java create mode 100755 source/java/org/alfresco/repo/web/scripts/rule/ActionDefinitionsGet.java create mode 100755 source/java/org/alfresco/repo/web/scripts/rule/RuleDelete.java create mode 100755 source/java/org/alfresco/repo/web/scripts/rule/RuleGet.java create mode 100755 source/java/org/alfresco/repo/web/scripts/rule/RulePost.java create mode 100755 source/java/org/alfresco/repo/web/scripts/rule/RulePut.java create mode 100755 source/java/org/alfresco/repo/web/scripts/rule/RuleServiceTest.java create mode 100755 source/java/org/alfresco/repo/web/scripts/rule/RuleTypesGet.java create mode 100755 source/java/org/alfresco/repo/web/scripts/rule/RulesGet.java create mode 100755 source/java/org/alfresco/repo/web/scripts/rule/RulesetGet.java create mode 100755 source/java/org/alfresco/repo/web/scripts/rule/ruleset/RuleRef.java create mode 100755 source/java/org/alfresco/repo/web/scripts/rule/ruleset/RuleSet.java diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/actionconditiondefinitions.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/actionconditiondefinitions.get.desc.xml new file mode 100755 index 0000000000..d159d1f26c --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/actionconditiondefinitions.get.desc.xml @@ -0,0 +1,8 @@ + + Action Condition Definition Collection + Gets a collection of action conditions available. + /api/actionconditiondefinitions + argument + user + required + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/actionconditiondefinitions.get.js b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/actionconditiondefinitions.get.js new file mode 100755 index 0000000000..1f4d5004ea --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/actionconditiondefinitions.get.js @@ -0,0 +1,7 @@ +function main() +{ + var actionconditiondefinitions = actions.getActionConditionDefinitions(); + model.actionconditiondefinitions = actionconditiondefinitions; +} + +main(); \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/actionconditiondefinitions.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/actionconditiondefinitions.get.json.ftl new file mode 100755 index 0000000000..2be8802a41 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/actionconditiondefinitions.get.json.ftl @@ -0,0 +1,27 @@ +{ + "data": + [ +<#list actionconditiondefinitions as actionconditiondefinition> + { + "name" : "${jsonUtils.encodeJSONString(actionconditiondefinition.name)}", + "displayLabel" : <#if actionconditiondefinition.title??>"${jsonUtils.encodeJSONString(actionconditiondefinition.title)}"<#else>null, + "description" : <#if actionconditiondefinition.description??>"${jsonUtils.encodeJSONString(actionconditiondefinition.description)}"<#else>null, + "adHocPropertiesAllowed" : ${actionconditiondefinition.adhocPropertiesAllowed?string}, + "parameterDefinitions" : + [ + <#if actionconditiondefinition.parameterDefinitions??> + <#list actionconditiondefinition.parameterDefinitions as parameterDefinition> + { + "name" : "${jsonUtils.encodeJSONString(parameterDefinition.name)}", + "displayLabel" : <#if parameterDefinition.displayLabel??>"${jsonUtils.encodeJSONString(parameterDefinition.displayLabel)}"<#else>null, + "type" : "${shortQName(parameterDefinition.type)}", + "isMultiValued" : ${parameterDefinition.multiValued?string}, + "isMandatory" : ${parameterDefinition.mandatory?string} + }<#if (parameterDefinition_has_next)>, + + + ] + }<#if (actionconditiondefinition_has_next)>, + + ] +} \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/actiondefinitions.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/actiondefinitions.get.desc.xml new file mode 100755 index 0000000000..e36de1d2a8 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/actiondefinitions.get.desc.xml @@ -0,0 +1,8 @@ + + Action Definition Collection + Gets a collection of the available actions. + /api/actiondefinitions + argument + user + required + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/actiondefinitions.get.js b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/actiondefinitions.get.js new file mode 100755 index 0000000000..2fe368703f --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/actiondefinitions.get.js @@ -0,0 +1,7 @@ +function main() +{ + var actiondefinitions = actions.getActionDefinitions(); + model.actiondefinitions = actiondefinitions; +} + +main(); \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/actiondefinitions.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/actiondefinitions.get.json.ftl new file mode 100755 index 0000000000..01abba521a --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/actiondefinitions.get.json.ftl @@ -0,0 +1,36 @@ +{ + "data": + [ +<#list actiondefinitions as actiondefinition> + { + "name" : "${jsonUtils.encodeJSONString(actiondefinition.name)}", + "displayLabel" : <#if actiondefinition.title??>"${jsonUtils.encodeJSONString(actiondefinition.title)}"<#else>null, + "description" : <#if actiondefinition.description??>"${jsonUtils.encodeJSONString(actiondefinition.description)}"<#else>null, + "adHocPropertiesAllowed" : ${actiondefinition.adhocPropertiesAllowed?string}, + "parameterDefinitions" : + [ + <#if actiondefinition.parameterDefinitions??> + <#list actiondefinition.parameterDefinitions as parameterDefinition> + { + "name" : "${jsonUtils.encodeJSONString(parameterDefinition.name)}", + "displayLabel" : <#if parameterDefinition.displayLabel??>"${jsonUtils.encodeJSONString(parameterDefinition.displayLabel)}"<#else>null, + "type" : "${shortQName(parameterDefinition.type)}", + "isMultiValued" : ${parameterDefinition.multiValued?string}, + "isMandatory" : ${parameterDefinition.mandatory?string} + }<#if (parameterDefinition_has_next)>, + + + ], + "applicableTypes" : + [ + <#if actiondefinition.applicableTypes??> + <#list actiondefinition.applicableTypes as applicableType> + "${shortQName(applicableType)}" + <#if (applicableType_has_next)>, + + + ] + }<#if (actiondefinition_has_next)>, + + ] +} \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.delete.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.delete.desc.xml new file mode 100755 index 0000000000..abe975d39d --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.delete.desc.xml @@ -0,0 +1,8 @@ + + Rule + Deletes a rule. + /api/node/{store_type}/{store_id}/{id}/ruleset/rules/{rule_id} + argument + user + required + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.delete.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.delete.json.ftl new file mode 100755 index 0000000000..05b949647c --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.delete.json.ftl @@ -0,0 +1,3 @@ +{ + "success": true +} \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.get.desc.xml new file mode 100755 index 0000000000..25b981e132 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.get.desc.xml @@ -0,0 +1,8 @@ + + Get Rule + Get the details of a rule. The details returned are fully expanded, including child actions (if composite action), conditions and compensating actions. + /api/node/{store_type}/{store_id}/{id}/ruleset/rules/{rule_id} + argument + user + required + \ 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 new file mode 100755 index 0000000000..a5f033c723 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.get.json.ftl @@ -0,0 +1,3 @@ +<#import "rule.lib.ftl" as ruleLib/> + +<@ruleLib.ruleJSON rule=rule /> \ 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 new file mode 100755 index 0000000000..4d0768817c --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.lib.ftl @@ -0,0 +1,105 @@ +<#-- renders a rule action object --> + +<#macro actionJSON action> +<#escape x as jsonUtils.encodeJSONString(x)> + { + "id" : "${action.id}", + "actionDefinitionName" : "${action.actionDefinitionName}", + <#if action.description??>"description" : "${action.description}", + <#if action.title??>"title" : "${action.title}", + <#if action.parameterValues?? && action.parameterValues?size > 0> + "parameterValues" : + { + <@parameterValuesJSON parameterValues=action.parameterValues /> + }, + + "executeAsync" : ${action.executeAsychronously?string}, + <#if action.runAsUser??> + "runAsUser" : "${action.runAsUser}", + + <#if action.actions?? && action.actions?size > 0> + "actions" : + [ + <#list action.actions as innerAction> + <@actionJSON action=innerAction /> + <#if innerAction_has_next>, + + ], + + <#if action.actionConditions?? && action.actionConditions?size > 0> + "conditions" : + [ + <#list action.actionConditions as actionCondition> + { + "id" : "${actionCondition.id}", + "conditionDefinitionName" : "${actionCondition.actionConditionDefinitionName}", + "invertCondition" : ${actionCondition.invertCondition?string}, + <#if actionCondition.parameterValues?? && actionCondition.parameterValues?size > 0> + "parameterValues" : + { + <@parameterValuesJSON parameterValues=actionCondition.parameterValues /> + }, + + "url" : "${"/api/node/" + storeType + "/" + storeId + "/" + id + "/ruleset/rules/" + rule.nodeRef.id + "/action/conditions/" + actionCondition.id}" + }<#if (actionCondition_has_next)>, + + ], + + <#if action.compensatingAction??> + "compensatingAction" : <@actionJSON action=action.compensatingAction />, + + "url" : "${"/api/node/" + storeType + "/" + storeId + "/" + id + "/ruleset/rules/" + rule.nodeRef.id + "/action/actions/" + action.id}" + } + + + +<#-- renders a complete rule object --> +<#macro ruleJSON rule> +<#escape x as jsonUtils.encodeJSONString(x)> + { + "id" : "${rule.nodeRef.id}", + "title" : "${rule.title}", + <#if rule.description??> + "description" : "${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}" + } + + + +<#-- renders a summary rule object --> +<#macro rulesummaryJSON rule> +<#escape x as jsonUtils.encodeJSONString(x)> + { + "id" : "${rule.nodeRef.id}", + "title" : "${rule.title}", + <#if rule.description??> + "description" : "${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}" + } + + + +<#-- renders parameters values map --> +<#macro parameterValuesJSON parameterValues> + <#list parameterValues?keys as parameterValue> + <#assign val = parameterValues[parameterValue]> + "${parameterValue}" : + <#if val?is_boolean == true> + ${val?string} + <#elseif val?is_date == true> + "${val?string("EEE MMM dd HH:mm:ss zzz yyyy")}" + <#else> + "${jsonUtils.encodeJSONString(val?string)}" + + <#if (parameterValue_has_next)>, + + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.post.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.post.desc.xml new file mode 100755 index 0000000000..7b0a9d4d89 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.post.desc.xml @@ -0,0 +1,8 @@ + + Get Rule + Creates a new rule. + /api/node/{store_type}/{store_id}/{id}/ruleset/rules + argument + user + required + \ No newline at end of file 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 new file mode 100755 index 0000000000..fcf3074cb0 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.post.json.ftl @@ -0,0 +1,6 @@ +<#import "rule.lib.ftl" as ruleLib/> + +{ + "data" : + <@ruleLib.rulesummaryJSON rule=rule /> +} \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.put.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.put.desc.xml new file mode 100755 index 0000000000..78807c7a41 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.put.desc.xml @@ -0,0 +1,8 @@ + + Update Rule + Update the details of a rule. + /api/node/{store_type}/{store_id}/{id}/ruleset/rules/{rule_id} + argument + user + required + \ 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 new file mode 100755 index 0000000000..a5f033c723 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rule.put.json.ftl @@ -0,0 +1,3 @@ +<#import "rule.lib.ftl" as ruleLib/> + +<@ruleLib.ruleJSON rule=rule /> \ 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 new file mode 100755 index 0000000000..341fa9d978 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rules.get.desc.xml @@ -0,0 +1,8 @@ + + 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. + /api/node/{store_type}/{store_id}/{id}/ruleset/rules?ruleType={rule_type?} + argument + user + required + \ No newline at end of file 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 new file mode 100755 index 0000000000..c54a8436bb --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/rules.get.json.ftl @@ -0,0 +1,10 @@ +<#import "rule.lib.ftl" as ruleLib/> +{ + "data" : + [ + <#list rules as rule> + <@ruleLib.rulesummaryJSON rule=rule /> + <#if rule_has_next>, + + ] +} \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruleset.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruleset.get.desc.xml new file mode 100755 index 0000000000..68532fbbdf --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruleset.get.desc.xml @@ -0,0 +1,8 @@ + + Get Rule Set + Gets the rule set for a node. + /api/node/{store_type}/{store_id}/{id}/ruleset?ruleType={rule_type?} + argument + user + required + \ 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 new file mode 100755 index 0000000000..a61f3a2d9c --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruleset.get.json.ftl @@ -0,0 +1,53 @@ +<#import "rule.lib.ftl" as ruleLib/> + +{ + "data" : + { + <#if ruleset.rules?? && ruleset.rules?size > 0> + "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>, + + ], + + <#if ruleset.inheritedRules?? && ruleset.inheritedRules?size > 0> + "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>, + + ], + + <#if ruleset.linkedToRuleSet??> + "linkedToRuleSet" : "${ruleset.linkedToRuleSet}", + + <#if ruleset.linkedFromRuleSets?? && ruleset.linkedFromRuleSets?size > 0> + "linkedFromRuleSets" : + [ + <#list ruleset.linkedFromRuleSets as linkedFromRuleSet> + "${linkedFromRuleSet}"<#if linkedFromRuleSet_has_next>, + + ], + + "url" : "${"/api/node/" + ruleset.rulesetNodeRef.storeRef.protocol + "/" + ruleset.rulesetNodeRef.storeRef.identifier + "/" + ruleset.rulesetNodeRef.id + "/ruleset"}" + } +} \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruletypes.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruletypes.get.desc.xml new file mode 100755 index 0000000000..e61b98d0c9 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruletypes.get.desc.xml @@ -0,0 +1,8 @@ + + Rule Type Collection + Gets all Rule Types defined by the system. + /api/ruletypes + argument + user + required + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruletypes.get.js b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruletypes.get.js new file mode 100755 index 0000000000..806e802977 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruletypes.get.js @@ -0,0 +1,7 @@ +function main() +{ + var ruletypes = ruleService.getRuleTypes(); + model.ruletypes = ruletypes; +} + +main(); \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruletypes.get.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruletypes.get.json.ftl new file mode 100755 index 0000000000..35bfd1acbd --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/rule/ruletypes.get.json.ftl @@ -0,0 +1,12 @@ +{ + "data": + [ +<#list ruletypes as ruletype> + { + "name" : "${jsonUtils.encodeJSONString(ruletype.name)}", + "displayLabel" : "${jsonUtils.encodeJSONString(ruletype.displayLabel)}", + "url" : "${"/api/ruletypes/" + jsonUtils.encodeJSONString(ruletype.name)}" + }<#if (ruletype_has_next)>, + + ] +} \ No newline at end of file diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml index 8bd901ea69..1f8fcc787c 100644 --- a/config/alfresco/web-scripts-application-context.xml +++ b/config/alfresco/web-scripts-application-context.xml @@ -596,7 +596,7 @@ ${imap.server.enabled} - + @@ -605,5 +605,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/rule/AbstractRuleWebScript.java b/source/java/org/alfresco/repo/web/scripts/rule/AbstractRuleWebScript.java new file mode 100755 index 0000000000..c0816de7d0 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/rule/AbstractRuleWebScript.java @@ -0,0 +1,213 @@ +/* + * 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.text.SimpleDateFormat; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import javax.servlet.http.HttpServletResponse; + +import org.alfresco.service.cmr.action.ActionConditionDefinition; +import org.alfresco.service.cmr.action.ActionDefinition; +import org.alfresco.service.cmr.action.ActionService; +import org.alfresco.service.cmr.action.ParameterDefinition; +import org.alfresco.service.cmr.dictionary.DictionaryService; +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.RuleService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.webscripts.DeclarativeWebScript; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * @author unknown + * + */ +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 NamespaceService namespaceService; + + private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + + private static Map propertyTypes = null; + + /** + * Sets the node service instance + * + * @param nodeService the node service to set + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * Set rule service instance + * + * @param ruleService the rule service to set + */ + public void setRuleService(RuleService ruleService) + { + this.ruleService = ruleService; + } + + /** + * Set dictionary service instance + * + * @param dictionaryService the dictionary service to set + */ + public void setDictionaryService(DictionaryService dictionaryService) + { + this.dictionaryService = dictionaryService; + } + + /** + * Set action service instance + * + * @param actionService the action service to set + */ + public void setActionService(ActionService actionService) + { + this.actionService = actionService; + } + + /** + * Set namespace service instance + * + * @param namespaceService the namespace service to set + */ + public void setNamespaceService(NamespaceService namespaceService) + { + this.namespaceService = namespaceService; + } + + /** + * Parses the request and providing it's valid returns the NodeRef. + * + * @param req The webscript request + * @return The NodeRef passed in the request + * + */ + protected NodeRef parseRequestForNodeRef(WebScriptRequest req) + { + // get the parameters that represent the NodeRef, we know they are present + // otherwise this webscript would not have matched + Map templateVars = req.getServiceMatch().getTemplateVars(); + 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()); + } + + return nodeRef; + } + + protected QName getPropertyType(String propertyName) + { + if (propertyTypes == null) + { + // no parameter types was cached + 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(); + + + for (ParameterDefinition parameterDefinition : parameterDefinitions) + { + try + { + // cache parameter + lock.writeLock().lock(); + propertyTypes.put(parameterDefinition.getName(), parameterDefinition.getType()); + } + finally + { + lock.writeLock().unlock(); + } + } + } + } + + QName result = null; + try + { + // getting cached parameter type + lock.readLock().lock(); + result = propertyTypes.get(propertyName); + } + finally + { + lock.readLock().unlock(); + } + + return result; + } +} diff --git a/source/java/org/alfresco/repo/web/scripts/rule/ActionConditionDefinitionsGet.java b/source/java/org/alfresco/repo/web/scripts/rule/ActionConditionDefinitionsGet.java new file mode 100755 index 0000000000..ff8280d9b7 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/rule/ActionConditionDefinitionsGet.java @@ -0,0 +1,59 @@ +/* + * 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.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.service.cmr.action.ActionConditionDefinition; +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 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/ActionDefinitionsGet.java b/source/java/org/alfresco/repo/web/scripts/rule/ActionDefinitionsGet.java new file mode 100755 index 0000000000..bdd5f37ac9 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/rule/ActionDefinitionsGet.java @@ -0,0 +1,59 @@ +/* + * 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.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.service.cmr.action.ActionDefinition; +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 ActionDefinitionsGet extends AbstractRuleWebScript +{ + @SuppressWarnings("unused") + private static Log logger = LogFactory.getLog(ActionDefinitionsGet.class); + + @Override + 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/RuleDelete.java b/source/java/org/alfresco/repo/web/scripts/rule/RuleDelete.java new file mode 100755 index 0000000000..91253c1fb9 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/rule/RuleDelete.java @@ -0,0 +1,88 @@ +/* + * 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.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletResponse; + +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.rule.Rule; +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.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * @author unknown + * + */ +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); + + // filter by rule id + for (Rule rule : rules) + { + if (rule.getNodeRef().getId().equalsIgnoreCase(ruleId)) + { + ruleToDelete = rule; + break; + } + } + + if (ruleToDelete == null) + { + 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 new file mode 100755 index 0000000000..8d94b464cc --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/rule/RuleGet.java @@ -0,0 +1,90 @@ +/* + * 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.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletResponse; + +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.rule.Rule; +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.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * @author unknown + * + */ +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) + { + if (rule.getNodeRef().getId().equalsIgnoreCase(ruleId)) + { + ruleToReturn = rule; + break; + } + } + + if (ruleToReturn == null) + { + 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()); + + 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 new file mode 100755 index 0000000000..bf9ceb84f8 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/rule/RulePost.java @@ -0,0 +1,313 @@ +/* + * 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.io.IOException; +import java.io.Serializable; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.repo.action.ActionConditionImpl; +import org.alfresco.repo.action.ActionImpl; +import org.alfresco.repo.action.CompositeActionImpl; +import org.alfresco.service.cmr.action.Action; +import org.alfresco.service.cmr.action.ActionCondition; +import org.alfresco.service.cmr.dictionary.DataTypeDefinition; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; +import org.alfresco.service.cmr.rule.Rule; +import org.alfresco.service.namespace.QName; +import org.alfresco.util.GUID; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONTokener; +import org.springframework.extensions.webscripts.Cache; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * @author unknown + * + */ +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()); + } + catch (IOException 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); + } + + return model; + } + + 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"); + } + + 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"); + } + + JSONArray types = jsonRule.getJSONArray("ruleType"); + List ruleTypes = new ArrayList(); + + for (int i = 0; i < types.length(); 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; + } + + 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); + } + else + { + result = new ActionImpl(null, actionId, jsonAction.getString("actionDefinitionName")); + } + + 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)); + } + + 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); + } + } + + if (jsonAction.has("conditions")) + { + JSONArray jsonConditions = jsonAction.getJSONArray("conditions"); + + for (int i = 0; i < jsonConditions.length(); 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(); + + 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)); + } + + return result; + } + + protected Map parseJsonParameterValues(JSONObject jsonParameterValues) throws JSONException + { + Map parameterValues = new HashMap(); + + // get parameters names + JSONArray names = jsonParameterValues.names(); + + 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(propertyName); + + if (typeQName == null) + { + if (propertyValue.toString().equals("true") || propertyValue.toString().equals("false")) + { + typeQName = DataTypeDefinition.BOOLEAN; + } + else + { + typeQName = DataTypeDefinition.TEXT; + } + } + + Serializable value = null; + + if (typeQName.equals(DataTypeDefinition.ANY)) + { + try + { + value = dateFormate.parse(propertyValue.toString()); + } + catch (ParseException e) + { + try + { + value = Long.valueOf(propertyValue.toString()); + } + catch (NumberFormatException e1) + { + // do nothing + } + } + } + + 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/RulePut.java b/source/java/org/alfresco/repo/web/scripts/rule/RulePut.java new file mode 100755 index 0000000000..681bcd2d1a --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/rule/RulePut.java @@ -0,0 +1,375 @@ +/* + * 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.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +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.service.cmr.action.Action; +import org.alfresco.service.cmr.action.ActionCondition; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.rule.Rule; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONTokener; +import org.springframework.extensions.webscripts.Cache; +import org.springframework.extensions.webscripts.Status; +import org.springframework.extensions.webscripts.WebScriptException; +import org.springframework.extensions.webscripts.WebScriptRequest; + +/** + * @author unknown + * + */ +public class RulePut extends RulePost +{ + @SuppressWarnings("unused") + private static Log logger = LogFactory.getLog(RulePut.class); + + @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) + { + if (rule.getNodeRef().getId().equalsIgnoreCase(ruleId)) + { + ruleToUpdate = rule; + break; + } + } + + if (ruleToUpdate == null) + { + 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()); + } + catch (IOException 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); + } + + 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)); + } + 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"); + + // update rule action + 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 + result = actionToUpdate; + } + else + { + // create new object as id was not sent by client + result = parseJsonAction(jsonAction); + 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)); + } + + 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(); + } + else + { + 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); + } + else + { + //create new action as id was not sent + 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 + result.getActionConditions().clear(); + } + else + { + List existingConditions = result.getActionConditions(); + List newConditions = new ArrayList(); + + for (int i = 0; i < jsonConditions.length(); 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); + newConditions.add(updatedActionCondition); + } + else + { + // 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()); + + actionToUpdate.setCompensatingAction(compensatingAction); + } + return result; + } + + protected ActionCondition updateActionConditionFromJson(JSONObject jsonCondition, ActionConditionImpl conditionToUpdate) throws JSONException + { + ActionConditionImpl result = null; + + if (jsonCondition.has("id")) + { + // update exiting object + result = conditionToUpdate; + } + else + { + // create new onject as id was not sent + 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)); + } + + return result; + } + + private Action getAction(List actions, String id) + { + Action result = null; + for (Action action : actions) + { + if (action.getId().equalsIgnoreCase(id)) + { + result = action; + break; + } + } + + return result; + } + + private ActionCondition getCondition(List conditions, String id) + { + ActionCondition result = null; + for (ActionCondition сondition : conditions) + { + if (сondition.getId().equalsIgnoreCase(id)) + { + result = сondition; + break; + } + } + + 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 new file mode 100755 index 0000000000..750cbea15e --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/rule/RuleServiceTest.java @@ -0,0 +1,531 @@ +/* + * 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.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.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.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.springframework.extensions.webscripts.TestWebScriptServer.DeleteRequest; +import org.springframework.extensions.webscripts.TestWebScriptServer.GetRequest; +import org.springframework.extensions.webscripts.TestWebScriptServer.PostRequest; +import org.springframework.extensions.webscripts.TestWebScriptServer.PutRequest; +import org.springframework.extensions.webscripts.TestWebScriptServer.Response; + +/** + * Unit test to test rules Web Script API + * + * @author unknown + * + */ +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_RULES = "/api/node/{0}/{1}/{2}/ruleset/rules"; + 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_FOLDER = "test_folder-" + System.currentTimeMillis(); + private static final String COMPANY_HOME_PATH = "/app:company_home"; + + private NodeService nodeService; + private FileFolderService fileFolderService; + private NamespaceService namespaceService; + private SearchService searchService; + private AuthenticationComponent authenticationComponent; + private RuleService ruleService; + + private NodeRef testNodeRef; + + @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); + } + + private void createTestFolder() + { + NodeRef storeRootNodeRef = nodeService.getRootNode(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE); + + NodeRef companyHomeNodeRef; + + List nodeRefs = searchService.selectNodes(storeRootNodeRef, COMPANY_HOME_PATH, null, namespaceService, false); + + if (nodeRefs.size() > 1) + { + throw new RuntimeException("Multiple possible roots for : \n" + " root path: " + COMPANY_HOME_PATH + "\n" + " results: " + nodeRefs); + } + else if (nodeRefs.size() == 0) + { + throw new RuntimeException("No root found for : \n" + " root path: " + COMPANY_HOME_PATH); + } + else + { + companyHomeNodeRef = nodeRefs.get(0); + } + 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); + } + + @Override + protected void tearDown() throws Exception + { + super.tearDown(); + + fileFolderService.delete(testNodeRef); + this.authenticationComponent.clearCurrentSecurityContext(); + } + + private JSONObject createRule() throws Exception + { + JSONObject jsonRule = buildTestRule(); + + Response response = sendRequest(new PostRequest(formatRulesUrl(testNodeRef), jsonRule.toString(), "application/json"), 200); + + JSONObject result = new JSONObject(response.getContentAsString()); + + return result; + } + + private JSONArray getNodeRules() throws Exception + { + Response response = sendRequest(new GetRequest(formatRulesUrl(testNodeRef)), 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); + + // 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("outbound", ruleType.getString(0)); + + assertFalse(result.getBoolean("applyToChildren")); + assertFalse(result.getBoolean("executeAsynchronously")); + assertFalse(result.getBoolean("disabled")); + 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.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("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")); + + assertEquals(before.has("url"), after.has("url")); + } + + private void checkRuleset(JSONObject result, String ruleId) 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")); + + } + + 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")); + } + } + + 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")); + assertTrue(actionConditionDefinition.has("adHocPropertiesAllowed")); + assertTrue(actionConditionDefinition.has("parameterDefinitions")); + } + } + + public void testCreateRule() throws Exception + { + JSONObject result = createRule(); + + checkRuleSummary(result); + + List rules = ruleService.getRules(testNodeRef); + + assertEquals(1, rules.size()); + + } + + public void testGetRulesCollection() throws Exception + { + JSONArray data = getNodeRules(); + + assertEquals(0, data.length()); + + createRule(); + + data = getNodeRules(); + + assertEquals(1, data.length()); + } + + public void testGetRuleset() throws Exception + { + JSONObject jsonRule = createRule(); + + String ruleId = jsonRule.getJSONObject("data").getString("id"); + + Response response = sendRequest(new GetRequest(formatRulesetUrl(testNodeRef)), 200); + JSONObject result = new JSONObject(response.getContentAsString()); + + checkRuleset(result, ruleId); + } + + public void testGetRuleDetails() throws Exception + { + JSONObject jsonRule = createRule(); + + 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(); + + 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(); + + 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 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("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)); + } + + return result; + } + + 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 new file mode 100755 index 0000000000..338567accc --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/rule/RuleTypesGet.java @@ -0,0 +1,60 @@ +/* + * 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.HashMap; +import java.util.List; +import java.util.Map; + +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 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 new file mode 100755 index 0000000000..25d6da1ddb --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/rule/RulesGet.java @@ -0,0 +1,75 @@ +/* + * 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.HashMap; +import java.util.List; +import java.util.Map; + +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 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()); + + 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 new file mode 100755 index 0000000000..7dae30a984 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/rule/RulesetGet.java @@ -0,0 +1,102 @@ +/* + * 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.repo.web.scripts.rule.ruleset.RuleSet; +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 RulesetGet extends AbstractRuleWebScript +{ + @SuppressWarnings("unused") + private static Log logger = LogFactory.getLog(RulesetGet.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; + } + + 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))); + } + ruleset.setRules(rulesToSet); + + + List inheritedRulesToSet = new ArrayList(); + + for (Rule rule : inheritedRules) + { + inheritedRulesToSet.add(new RuleRef(rule, ruleService.getOwningNodeRef(rule))); + } + ruleset.setInheritedRules(inheritedRulesToSet); + + 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 new file mode 100755 index 0000000000..f01f3572cc --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/rule/ruleset/RuleRef.java @@ -0,0 +1,93 @@ +/* + * 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.ruleset; + +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.rule.Rule; + + + +/** + * Rule object for REST API + * + * @author unknown + * + */ +public class RuleRef +{ + + /** Serial version UID */ + private static final long serialVersionUID = -923276130307938661L; + + private NodeRef owningNodeRef; + + private Rule rule; + + public RuleRef(Rule rule, NodeRef owningNodeRef) + { + this.rule = rule; + this.owningNodeRef = owningNodeRef; + } + + /** + * Set the rule + * + * @param rule the rule to set + */ + public void setRule(Rule rule) + { + this.rule = rule; + } + + /** + * Return the rule + * + * @return rule + */ + public Rule getRule() + { + return rule; + } + + /** + * Set the owning node reference for rule + * + * @param owningNodeRef the owning node reference to set + */ + public void setOwningNodeRef(NodeRef owningNodeRef) + { + this.owningNodeRef = owningNodeRef; + } + + /** + * Returns the owning node reference for a rule. + * + * @return the owning node reference + */ + public NodeRef getOwningNodeRef() + { + return owningNodeRef; + } +} 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 new file mode 100755 index 0000000000..7a7fa7052a --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/rule/ruleset/RuleSet.java @@ -0,0 +1,151 @@ +/* + * 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.ruleset; + +import java.io.Serializable; +import java.util.List; + +import org.alfresco.service.cmr.repository.NodeRef; + +/** + * @author unknown + * + */ +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 + * + * @param rules the list of rules to set + */ + public void setRules(List rules) + { + this.rules = rules; + } + + /** + * Get list of the rules "owned" by this rule set + * + * @return list of "owned" rules + */ + public List getRules() + { + return rules; + } + + /** + * Set list of the rules inherited by this rule set from parent + * + * @param inheritedRules the list of inherited rules to set + */ + public void setInheritedRules(List inheritedRules) + { + this.inheritedRules = inheritedRules; + } + + /** + * Get list of the rules inherited by this rule set from parent + * + * @return list of inherited rules + */ + public List getInheritedRules() + { + return inheritedRules; + } + + /** + * Set the nodeRef to which this ruleset belongs + * + * @param rulesetNodeRef the ruleset nodeRef to set + */ + public void setRulesetNodeRef(NodeRef rulesetNodeRef) + { + this.rulesetNodeRef = rulesetNodeRef; + } + + /** + * Get the nodeRef to which this ruleset belongs + * + * @return ruleset nodeRef + */ + public NodeRef getRulesetNodeRef() + { + return rulesetNodeRef; + } + + /** + * Set the nodeRef to which this ruleset linked to + * + * @param linkedToRuleSet the nodeRef to set + */ + public void setLinkedToRuleSet(NodeRef linkedToRuleSet) + { + this.linkedToRuleSet = linkedToRuleSet; + } + + /** + * Get the nodeRef to which this ruleset linked to + * + * @return linked to nodeRef + */ + public NodeRef getLinkedToRuleSet() + { + return linkedToRuleSet; + } + + /** + * Set the list of nodeRefs that link to this ruleset + * + * @param linkedFromRuleSets the list of nodeRefs to set + */ + public void setLinkedFromRuleSets(List linkedFromRuleSets) + { + this.linkedFromRuleSets = linkedFromRuleSets; + } + + /** + * Get the list of nodeRefs that link to this ruleset + * + * @return the list of nodeRefs + */ + public List getLinkedFromRuleSets() + { + return linkedFromRuleSets; + } + +}