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#if>,
+ "description" : <#if actionconditiondefinition.description??>"${jsonUtils.encodeJSONString(actionconditiondefinition.description)}"<#else>null#if>,
+ "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#if>,
+ "type" : "${shortQName(parameterDefinition.type)}",
+ "isMultiValued" : ${parameterDefinition.multiValued?string},
+ "isMandatory" : ${parameterDefinition.mandatory?string}
+ }<#if (parameterDefinition_has_next)>,#if>
+ #list>
+ #if>
+ ]
+ }<#if (actionconditiondefinition_has_next)>,#if>
+ #list>
+ ]
+}
\ 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#if>,
+ "description" : <#if actiondefinition.description??>"${jsonUtils.encodeJSONString(actiondefinition.description)}"<#else>null#if>,
+ "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#if>,
+ "type" : "${shortQName(parameterDefinition.type)}",
+ "isMultiValued" : ${parameterDefinition.multiValued?string},
+ "isMandatory" : ${parameterDefinition.mandatory?string}
+ }<#if (parameterDefinition_has_next)>,#if>
+ #list>
+ #if>
+ ],
+ "applicableTypes" :
+ [
+ <#if actiondefinition.applicableTypes??>
+ <#list actiondefinition.applicableTypes as applicableType>
+ "${shortQName(applicableType)}"
+ <#if (applicableType_has_next)>,#if>
+ #list>
+ #if>
+ ]
+ }<#if (actiondefinition_has_next)>,#if>
+ #list>
+ ]
+}
\ 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>
+ <#if action.title??>"title" : "${action.title}",#if>
+ <#if action.parameterValues?? && action.parameterValues?size > 0>
+ "parameterValues" :
+ {
+ <@parameterValuesJSON parameterValues=action.parameterValues />
+ },
+ #if>
+ "executeAsync" : ${action.executeAsychronously?string},
+ <#if action.runAsUser??>
+ "runAsUser" : "${action.runAsUser}",
+ #if>
+ <#if action.actions?? && action.actions?size > 0>
+ "actions" :
+ [
+ <#list action.actions as innerAction>
+ <@actionJSON action=innerAction />
+ <#if innerAction_has_next>,#if>
+ #list>
+ ],
+ #if>
+ <#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 />
+ },
+ #if>
+ "url" : "${"/api/node/" + storeType + "/" + storeId + "/" + id + "/ruleset/rules/" + rule.nodeRef.id + "/action/conditions/" + actionCondition.id}"
+ }<#if (actionCondition_has_next)>,#if>
+ #list>
+ ],
+ #if>
+ <#if action.compensatingAction??>
+ "compensatingAction" : <@actionJSON action=action.compensatingAction />,
+ #if>
+ "url" : "${"/api/node/" + storeType + "/" + storeId + "/" + id + "/ruleset/rules/" + rule.nodeRef.id + "/action/actions/" + action.id}"
+ }
+#escape>
+#macro>
+
+<#-- 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}",
+ #if>
+ "ruleType" : [<#list rule.ruleTypes as ruleType>"${ruleType}"<#if (ruleType_has_next)>, #if>#list>],
+ "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}"
+ }
+#escape>
+#macro>
+
+<#-- 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}",
+ #if>
+ "ruleType" : [<#list rule.ruleTypes as ruleType>"${ruleType}"<#if (ruleType_has_next)>, #if>#list>],
+ "disabled" : ${rule.ruleDisabled?string},
+ "url" : "${"/api/node/" + storeType + "/" + storeId + "/" + id + "/ruleset/rules/" + rule.nodeRef.id}"
+ }
+#escape>
+#macro>
+
+<#-- 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>
+ <#if (parameterValue_has_next)>,#if>
+ #list>
+#macro>
\ 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>,#if>
+ #list>
+ ]
+}
\ 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}",
+ #if>
+ "ruleType" : [<#list ruleRef.rule.ruleTypes as ruleType>"${ruleType}"<#if (ruleType_has_next)>, #if>#list>],
+ "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>
+ #list>
+ ],
+ #if>
+ <#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}",
+ #if>
+ "ruleType" : [<#list inheritedRuleRef.rule.ruleTypes as ruleType>"${ruleType}"<#if (ruleType_has_next)>, #if>#list>],
+ "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>
+ #list>
+ ],
+ #if>
+ <#if ruleset.linkedToRuleSet??>
+ "linkedToRuleSet" : "${ruleset.linkedToRuleSet}",
+ #if>
+ <#if ruleset.linkedFromRuleSets?? && ruleset.linkedFromRuleSets?size > 0>
+ "linkedFromRuleSets" :
+ [
+ <#list ruleset.linkedFromRuleSets as linkedFromRuleSet>
+ "${linkedFromRuleSet}"<#if linkedFromRuleSet_has_next>,#if>
+ #list>
+ ],
+ #if>
+ "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)>,#if>
+ #list>
+ ]
+}
\ 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}
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ 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;
+ }
+
+}