- Rule and action tasks for 1.4

- Updated W/S include paths

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3526 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Roy Wetherall
2006-08-16 13:27:35 +00:00
parent 895935e8d6
commit 29beac8efb
16 changed files with 501 additions and 193 deletions

View File

@@ -40,7 +40,6 @@ import org.alfresco.service.cmr.rule.Rule;
import org.alfresco.service.cmr.rule.RuleService;
import org.alfresco.service.cmr.rule.RuleServiceException;
import org.alfresco.service.cmr.rule.RuleType;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.util.GUID;
@@ -88,11 +87,6 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
*/
private ActionService actionService;
/**
* The search service
*/
private SearchService searchService;
/**
* The dictionary service
*/
@@ -126,10 +120,15 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
private TransactionListener ruleTransactionListener = new RuleTransactionListener(this);
/**
* Indicates whether the rules are disabled for the curren thread
* Indicates whether the rules are disabled for the current thread
*/
private ThreadLocal<Boolean> rulesDisabled = new ThreadLocal<Boolean>();
/**
* Global flag that indicates whether the
*/
private boolean globalRulesDisabled = false;
/**
* Set the permission-safe node service
*
@@ -170,16 +169,6 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
this.runtimeActionService = runtimeActionService;
}
/**
* Set the search service
*
* @param searchService the search service
*/
public void setSearchService(SearchService searchService)
{
this.searchService = searchService;
}
/**
* Set the dictionary service
*
@@ -189,6 +178,16 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
{
this.dictionaryService = dictionaryService;
}
/**
* Set the global rules disabled flag
*
* @param rulesDisabled true to disable allr ules, false otherwise
*/
public void setRulesDisabled(boolean rulesDisabled)
{
this.globalRulesDisabled = rulesDisabled;
}
/**
* Gets the saved rule folder reference
@@ -253,7 +252,7 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
*/
public boolean isEnabled()
{
return (this.rulesDisabled.get() == null);
return (this.globalRulesDisabled == false && this.rulesDisabled.get() == null);
}
/**
@@ -331,7 +330,7 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
if (this.runtimeNodeService.exists(nodeRef) == true && checkNodeType(nodeRef) == true)
{
if (includeInherited == true)
if (includeInherited == true && this.nodeService.hasAspect(nodeRef, RuleModel.ASPECT_IGNORE_INHERITED_RULES) == false)
{
// Get any inherited rules
for (Rule rule : getInheritedRules(nodeRef, ruleTypeName, null))
@@ -441,58 +440,62 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
private List<Rule> getInheritedRules(NodeRef nodeRef, String ruleTypeName, Set<NodeRef> visitedNodeRefs)
{
List<Rule> inheritedRules = new ArrayList<Rule>();
// Create the visited nodes set if it has not already been created
if (visitedNodeRefs == null)
{
visitedNodeRefs = new HashSet<NodeRef>();
}
// This check prevents stack over flow when we have a cyclic node graph
if (visitedNodeRefs.contains(nodeRef) == false)
{
visitedNodeRefs.add(nodeRef);
List<Rule> allInheritedRules = new ArrayList<Rule>();
List<ChildAssociationRef> parents = this.runtimeNodeService.getParentAssocs(nodeRef);
for (ChildAssociationRef parent : parents)
{
List<Rule> rules = getRules(parent.getParentRef(), false);
for (Rule rule : rules)
{
// Add is we hanvn't already added and it should be applied to the children
if (rule.isAppliedToChildren() == true && allInheritedRules.contains(rule) == false)
{
allInheritedRules.add(rule);
}
}
for (Rule rule : getInheritedRules(parent.getParentRef(), ruleTypeName, visitedNodeRefs))
{
// Ensure that we don't get any rule duplication (don't use a set cos we want to preserve order)
if (allInheritedRules.contains(rule) == false)
{
allInheritedRules.add(rule);
}
}
}
if (ruleTypeName == null)
{
inheritedRules = allInheritedRules;
}
else
{
// Filter the rule list by rule type
for (Rule rule : allInheritedRules)
{
if (rule.getRuleTypes().contains(ruleTypeName) == true)
{
inheritedRules.add(rule);
}
}
}
}
if (this.nodeService.hasAspect(nodeRef, RuleModel.ASPECT_IGNORE_INHERITED_RULES) == false)
{
// Create the visited nodes set if it has not already been created
if (visitedNodeRefs == null)
{
visitedNodeRefs = new HashSet<NodeRef>();
}
// This check prevents stack over flow when we have a cyclic node graph
if (visitedNodeRefs.contains(nodeRef) == false)
{
visitedNodeRefs.add(nodeRef);
List<Rule> allInheritedRules = new ArrayList<Rule>();
List<ChildAssociationRef> parents = this.runtimeNodeService.getParentAssocs(nodeRef);
for (ChildAssociationRef parent : parents)
{
// Add the inherited rule first
for (Rule rule : getInheritedRules(parent.getParentRef(), ruleTypeName, visitedNodeRefs))
{
// Ensure that we don't get any rule duplication (don't use a set cos we want to preserve order)
if (allInheritedRules.contains(rule) == false)
{
allInheritedRules.add(rule);
}
}
List<Rule> rules = getRules(parent.getParentRef(), false);
for (Rule rule : rules)
{
// Add is we hanvn't already added and it should be applied to the children
if (rule.isAppliedToChildren() == true && allInheritedRules.contains(rule) == false)
{
allInheritedRules.add(rule);
}
}
}
if (ruleTypeName == null)
{
inheritedRules = allInheritedRules;
}
else
{
// Filter the rule list by rule type
for (Rule rule : allInheritedRules)
{
if (rule.getRuleTypes().contains(ruleTypeName) == true)
{
inheritedRules.add(rule);
}
}
}
}
}
return inheritedRules;
}
@@ -511,9 +514,6 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
// Create the rule
Rule rule = new Rule(ruleNodeRef);
// Set the owning node ref
//rule.setOwningNodeRef((NodeRef)props.get(RuleModel.PROP_OWNING_NODEREF));
// Set the title and description
rule.setTitle((String)props.get(ContentModel.PROP_TITLE));
rule.setDescription((String)props.get(ContentModel.PROP_DESCRIPTION));
@@ -538,6 +538,15 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
executeAsync = value2.booleanValue();
}
rule.setExecuteAsynchronously(executeAsync);
// Set the disabled value
boolean ruleDisabled = false;
Boolean value3 = (Boolean)props.get(RuleModel.PROP_DISABLED);
if (value3 != null)
{
ruleDisabled = value3.booleanValue();
}
rule.setRuleDisabled(ruleDisabled);
// Get the action node reference
List<ChildAssociationRef> actions = this.nodeService.getChildAssocs(ruleNodeRef, RuleModel.ASSOC_ACTION, RuleModel.ASSOC_ACTION);
@@ -597,6 +606,7 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_RULE_TYPE, (Serializable)rule.getRuleTypes());
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_APPLY_TO_CHILDREN, rule.isAppliedToChildren());
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_EXECUTE_ASYNC, rule.getExecuteAsynchronously());
this.nodeService.setProperty(ruleNodeRef, RuleModel.PROP_DISABLED, rule.getRuleDisabled());
// Save the rule's action
saveAction(ruleNodeRef, rule);
@@ -607,6 +617,12 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
}
}
/**
* Save the action related to the rule.
*
* @param ruleNodeRef the node reference representing the rule
* @param rule the rule
*/
private void saveAction(NodeRef ruleNodeRef, Rule rule)
{
// Get the action definition from the rule
@@ -708,18 +724,18 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
public void addRulePendingExecution(NodeRef actionableNodeRef, NodeRef actionedUponNodeRef, Rule rule, boolean executeAtEnd)
{
// First check to see if the node has been disabled
if (this.rulesDisabled.get() == null &&
if (this.isEnabled() == true &&
this.disabledNodeRefs.contains(this.getOwningNodeRef(rule)) == false &&
this.disabledRules.contains(rule) == false)
{
PendingRuleData pendingRuleData = new PendingRuleData(actionableNodeRef, actionedUponNodeRef, rule, executeAtEnd);
Set<PendingRuleData> pendingRules =
(Set<PendingRuleData>) AlfrescoTransactionSupport.getResource(KEY_RULES_PENDING);
List<PendingRuleData> pendingRules =
(List<PendingRuleData>) AlfrescoTransactionSupport.getResource(KEY_RULES_PENDING);
if (pendingRules == null)
{
// bind pending rules to the current transaction
pendingRules = new HashSet<PendingRuleData>();
pendingRules = new ArrayList<PendingRuleData>();
AlfrescoTransactionSupport.bindResource(KEY_RULES_PENDING, pendingRules);
// bind the rule transaction listener
AlfrescoTransactionSupport.bindListener(this.ruleTransactionListener);
@@ -730,8 +746,11 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
}
}
// Prevent the same rule being executed more than once in the same transaction
pendingRules.add(pendingRuleData);
// Prevent the same rule being executed more than once in the same transaction
if (pendingRules.contains(pendingRuleData) == false)
{
pendingRules.add(pendingRuleData);
}
}
else
{
@@ -773,8 +792,8 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
private void executePendingRulesImpl(List<PendingRuleData> executeAtEndRules)
{
// get the transaction-local rules to execute
Set<PendingRuleData> pendingRules =
(Set<PendingRuleData>) AlfrescoTransactionSupport.getResource(KEY_RULES_PENDING);
List<PendingRuleData> pendingRules =
(List<PendingRuleData>) AlfrescoTransactionSupport.getResource(KEY_RULES_PENDING);
// only execute if there are rules present
if (pendingRules != null && !pendingRules.isEmpty())
{
@@ -815,29 +834,41 @@ public class RuleServiceImpl implements RuleService, RuntimeRuleService
if (executedRules == null || canExecuteRule(executedRules, actionedUponNodeRef, rule) == true)
{
Action action = rule.getAction();
if (action == null)
{
throw new RuleServiceException("Attempting to execute a rule that does not have a rule specified.");
}
// Evaluate the condition
if (this.actionService.evaluateAction(action, actionedUponNodeRef) == true)
{
// Add the rule to the executed rule list
// (do this before this is executed to prevent rules being added to the pending list)
executedRules.add(new ExecutedRuleData(actionedUponNodeRef, rule));
if (logger.isDebugEnabled() == true)
{
logger.debug(" ... Adding rule (" + rule.getTitle() + ") and nodeRef (" + actionedUponNodeRef.getId() + ") to executed list");
}
// Execute the rule
boolean executeAsync = rule.getExecuteAsynchronously();
this.actionService.executeAction(action, actionedUponNodeRef, true, executeAsync);
}
executeRule(rule, actionedUponNodeRef, executedRules);
}
}
/**
* @see org.alfresco.repo.rule.RuntimeRuleService#executeRule(org.alfresco.service.cmr.rule.Rule, org.alfresco.service.cmr.repository.NodeRef, java.util.Set)
*/
public void executeRule(Rule rule, NodeRef actionedUponNodeRef, Set<ExecutedRuleData> executedRules)
{
// Get the action associated with the rule
Action action = rule.getAction();
if (action == null)
{
throw new RuleServiceException("Attempting to execute a rule that does not have a rule specified.");
}
// Evaluate the condition
if (this.actionService.evaluateAction(action, actionedUponNodeRef) == true)
{
if (executedRules != null)
{
// Add the rule to the executed rule list
// (do this before this is executed to prevent rules being added to the pending list)
executedRules.add(new ExecutedRuleData(actionedUponNodeRef, rule));
if (logger.isDebugEnabled() == true)
{
logger.debug(" ... Adding rule (" + rule.getTitle() + ") and nodeRef (" + actionedUponNodeRef.getId() + ") to executed list");
}
}
// Execute the rule
boolean executeAsync = rule.getExecuteAsynchronously();
this.actionService.executeAction(action, actionedUponNodeRef, true, executeAsync);
}
}
/**
* Determines whether the rule can be executed