mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
- 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:
@@ -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
|
||||
|
Reference in New Issue
Block a user