- Action/Rule decoupling work

- Updated web services, SDK and web client where appropraite
- Patch added to migrate existing rules
- Entire rule service can now be disabled programmatically
- Rule service is now disabled during the patching process
- StoreEnum and languageEnum types removed from web service interfaces
- Multiple rule types now supported in the repo (but not in the UI)
- Removed owning node ref from action and rule .. now calculated from methods on the rule service

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3464 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Roy Wetherall
2006-08-07 15:53:45 +00:00
parent df21ad9f8b
commit df7f1062df
33 changed files with 964 additions and 555 deletions

View File

@@ -40,6 +40,9 @@ public class ActionImpl extends ParameterizedItemImpl
*/
private static final long serialVersionUID = 3258135760426186548L;
/** The node reference for the action */
private NodeRef nodeRef;
/**
* The title
*/
@@ -90,11 +93,6 @@ public class ActionImpl extends ParameterizedItemImpl
*/
private String runAsUserName;
/**
* The owning node reference
*/
private NodeRef owningNodeRef;
/**
* The chain of actions that have lead to this action
*/
@@ -108,30 +106,32 @@ public class ActionImpl extends ParameterizedItemImpl
/**
* Constructor
*
* @param nodeRef the action node reference (null if not saved)
* @param id the action id
* @param actionDefinitionName the name of the action definition
*/
public ActionImpl(String id, String actionDefinitionName, NodeRef owningNodeRef)
public ActionImpl(NodeRef nodeRef, String id, String actionDefinitionName)
{
this(id, actionDefinitionName, owningNodeRef, null);
this(nodeRef, id, actionDefinitionName, null);
}
/**
* Constructor
*
* @param nodeRef the action node reference (null if not saved)
* @param id the action id
* @param actionDefinitionName the action definition name
* @param parameterValues the parameter values
*/
public ActionImpl(
NodeRef nodeRef,
String id,
String actionDefinitionName,
NodeRef owningNodeRef,
Map<String, Serializable> parameterValues)
{
super(id, parameterValues);
this.nodeRef = nodeRef;
this.actionDefinitionName = actionDefinitionName;
this.owningNodeRef = owningNodeRef;
}
/**
@@ -165,19 +165,6 @@ public class ActionImpl extends ParameterizedItemImpl
{
this.description = description;
}
/**
* @see org.alfresco.service.cmr.action.Action#getOwningNodeRef()
*/
public NodeRef getOwningNodeRef()
{
return this.owningNodeRef;
}
public void setOwningNodeRef(NodeRef owningNodeRef)
{
this.owningNodeRef = owningNodeRef;
}
/**
* @see org.alfresco.service.cmr.action.Action#getExecuteAsychronously()
@@ -392,4 +379,22 @@ public class ActionImpl extends ParameterizedItemImpl
{
this.runAsUserName = runAsUserName;
}
/**
* @see org.alfresco.service.cmr.action.Action#getNodeRef()
*/
public NodeRef getNodeRef()
{
return this.nodeRef;
}
/**
* Set the node reference
*
* @param nodeRef the node reference
*/
public void setNodeRef(NodeRef nodeRef)
{
this.nodeRef = nodeRef;
}
}

View File

@@ -41,9 +41,9 @@ public class ActionImplTest extends BaseParameterizedItemImplTest
protected ParameterizedItemImpl create()
{
return new ActionImpl(
null,
ID,
NAME,
null,
this.paramValues);
}
@@ -65,7 +65,7 @@ public class ActionImplTest extends BaseParameterizedItemImplTest
action.setTitle("title");
action.setDescription("description");
action.setExecuteAsynchronously(true);
Action compensatingAction = new ActionImpl(GUID.generate(), "actionDefintionName", null);
Action compensatingAction = new ActionImpl(null, GUID.generate(), "actionDefintionName", null);
action.setCompensatingAction(compensatingAction);
// Check the values have been set

View File

@@ -309,7 +309,7 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
*/
public Action createAction(String name)
{
return new ActionImpl(GUID.generate(),name, null);
return new ActionImpl(null, GUID.generate(),name, null);
}
/**
@@ -327,7 +327,7 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
*/
public CompositeAction createCompositeAction()
{
return new CompositeActionImpl(GUID.generate(), null);
return new CompositeActionImpl(null, GUID.generate());
}
/**
@@ -594,42 +594,51 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
// Apply the actionable aspect
this.nodeService.addAspect(nodeRef, ActionModel.ASPECT_ACTIONS, null);
}
Map<QName, Serializable> props = new HashMap<QName, Serializable>(2);
props.put(ActionModel.PROP_DEFINITION_NAME, action.getActionDefinitionName());
props.put(ContentModel.PROP_NODE_UUID, action.getId());
QName actionType = ActionModel.TYPE_ACTION;
if(action instanceof CompositeAction)
{
actionType = ActionModel.TYPE_COMPOSITE_ACTION;
}
// Create the action node
actionNodeRef = this.nodeService.createNode(
getSavedActionFolderRef(nodeRef),
ContentModel.ASSOC_CONTAINS,
ASSOC_NAME_ACTIONS,
actionType,
props).getChildRef();
// Update the created details
((ActionImpl)action).setCreator((String)this.nodeService.getProperty(actionNodeRef, ContentModel.PROP_CREATOR));
((ActionImpl)action).setCreatedDate((Date)this.nodeService.getProperty(actionNodeRef, ContentModel.PROP_CREATED));
// Create the action nod reference
actionNodeRef = createActionNodeRef(action,
getSavedActionFolderRef(nodeRef),
ContentModel.ASSOC_CONTAINS,
ASSOC_NAME_ACTIONS);
}
saveActionImpl(nodeRef, actionNodeRef, action);
saveActionImpl(actionNodeRef, action);
}
public NodeRef createActionNodeRef(Action action, NodeRef parentNodeRef, QName assocTypeName, QName assocName)
{
Map<QName, Serializable> props = new HashMap<QName, Serializable>(2);
props.put(ActionModel.PROP_DEFINITION_NAME, action.getActionDefinitionName());
props.put(ContentModel.PROP_NODE_UUID, action.getId());
QName actionType = ActionModel.TYPE_ACTION;
if(action instanceof CompositeAction)
{
actionType = ActionModel.TYPE_COMPOSITE_ACTION;
}
// Create the action node
NodeRef actionNodeRef = this.nodeService.createNode(
parentNodeRef,
assocTypeName,
assocName,
actionType,
props).getChildRef();
// Update the created details and the node reference
((ActionImpl)action).setCreator((String)this.nodeService.getProperty(actionNodeRef, ContentModel.PROP_CREATOR));
((ActionImpl)action).setCreatedDate((Date)this.nodeService.getProperty(actionNodeRef, ContentModel.PROP_CREATED));
((ActionImpl)action).setNodeRef(actionNodeRef);
return actionNodeRef;
}
/**
* @see org.alfresco.repo.action.RuntimeActionService#saveActionImpl(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.action.Action)
*/
public void saveActionImpl(NodeRef owningNodeRef, NodeRef actionNodeRef, Action action)
public void saveActionImpl(NodeRef actionNodeRef, Action action)
{
// Set the owning node ref
((ActionImpl)action).setOwningNodeRef(owningNodeRef);
// Save action properties
// Save action properties
saveActionProperties(actionNodeRef, action);
// Update the parameters of the action
@@ -671,18 +680,20 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
{
if (compensatingAction != null)
{
Map<QName, Serializable> props2 = new HashMap<QName, Serializable>(2);
props2.put(ActionModel.PROP_DEFINITION_NAME, compensatingAction.getActionDefinitionName());
props2.put(ContentModel.PROP_NODE_UUID, compensatingAction.getId());
//Map<QName, Serializable> props2 = new HashMap<QName, Serializable>(2);
//props2.put(ActionModel.PROP_DEFINITION_NAME, compensatingAction.getActionDefinitionName());
//props2.put(ContentModel.PROP_NODE_UUID, compensatingAction.getId());
NodeRef compensatingActionNodeRef = this.nodeService.createNode(
actionNodeRef,
ActionModel.ASSOC_COMPENSATING_ACTION,
ActionModel.ASSOC_COMPENSATING_ACTION,
ActionModel.TYPE_ACTION,
props2).getChildRef();
saveActionImpl(compensatingAction.getOwningNodeRef(), compensatingActionNodeRef, compensatingAction);
//NodeRef compensatingActionNodeRef = this.nodeService.createNode(
/// actionNodeRef,
// ActionModel.ASSOC_COMPENSATING_ACTION,
// ActionModel.ASSOC_COMPENSATING_ACTION,
// ActionModel.TYPE_ACTION,
// props2).getChildRef();
// Create the compensating node reference
NodeRef compensatingActionNodeRef = createActionNodeRef(compensatingAction, actionNodeRef, ActionModel.ASSOC_COMPENSATING_ACTION, ActionModel.ASSOC_COMPENSATING_ACTION);
saveActionImpl(compensatingActionNodeRef, compensatingAction);
}
}
else
@@ -694,7 +705,7 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
}
else
{
saveActionImpl(compensatingAction.getOwningNodeRef(), assoc.getChildRef(), compensatingAction);
saveActionImpl(assoc.getChildRef(), compensatingAction);
}
}
}
@@ -730,7 +741,7 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
{
// Update the action
Action action = idToAction.get(actionNodeRef.getId());
saveActionImpl(action.getOwningNodeRef(), actionNodeRef, action);
saveActionImpl(actionNodeRef, action);
orderedIds.remove(actionNodeRef.getId());
}
@@ -752,7 +763,7 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
ActionModel.TYPE_ACTION,
props).getChildRef();
saveActionImpl(action.getOwningNodeRef(), actionNodeRef, action);
saveActionImpl(actionNodeRef, action);
}
}
@@ -889,7 +900,7 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
for (ChildAssociationRef action : actions)
{
NodeRef actionNodeRef = action.getChildRef();
result.add(createAction(nodeRef, actionNodeRef));
result.add(createAction(actionNodeRef));
}
}
@@ -902,7 +913,7 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
* @param actionNodeRef the action node reference
* @return the action
*/
private Action createAction(NodeRef owningNodeRef, NodeRef actionNodeRef)
public Action createAction(NodeRef actionNodeRef)
{
Action result = null;
@@ -912,13 +923,13 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
if (ActionModel.TYPE_COMPOSITE_ACTION.equals(actionType) == true)
{
// Create a composite action
result = new CompositeActionImpl(actionNodeRef.getId(), owningNodeRef);
result = new CompositeActionImpl(actionNodeRef, actionNodeRef.getId());
populateCompositeAction(actionNodeRef, (CompositeAction)result);
}
else
{
// Create an action
result = new ActionImpl(actionNodeRef.getId(), (String)properties.get(ActionModel.PROP_DEFINITION_NAME), owningNodeRef);
result = new ActionImpl(actionNodeRef, actionNodeRef.getId(), (String)properties.get(ActionModel.PROP_DEFINITION_NAME));
populateAction(actionNodeRef, result);
}
@@ -978,7 +989,7 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
List<ChildAssociationRef> assocs = this.nodeService.getChildAssocs(actionNodeRef, RegexQNamePattern.MATCH_ALL, ActionModel.ASSOC_COMPENSATING_ACTION);
if (assocs.size() != 0)
{
Action compensatingAction = createAction(action.getOwningNodeRef(), assocs.get(0).getChildRef());
Action compensatingAction = createAction(assocs.get(0).getChildRef());
action.setCompensatingAction(compensatingAction);
}
}
@@ -1039,7 +1050,7 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
for (ChildAssociationRef action : actions)
{
NodeRef actionNodeRef = action.getChildRef();
compositeAction.addAction(createAction(compositeAction.getOwningNodeRef(), actionNodeRef));
compositeAction.addAction(createAction(actionNodeRef));
}
}
@@ -1056,7 +1067,7 @@ public class ActionServiceImpl implements ActionService, RuntimeActionService, A
NodeRef actionNodeRef = getActionNodeRefFromId(nodeRef, actionId);
if (actionNodeRef != null)
{
result = createAction(nodeRef, actionNodeRef);
result = createAction(actionNodeRef);
}
}

View File

@@ -388,19 +388,19 @@ public class ActionServiceImplTest extends BaseAlfrescoSpringTest
action.setExecuteAsynchronously(true);
// Check the owning node ref
assertNull(action.getOwningNodeRef());
//assertNull(action.getOwningNodeRef());
// Save the action
this.actionService.saveAction(this.nodeRef, action);
// Check the owning node ref
assertEquals(this.nodeRef, action.getOwningNodeRef());
//assertEquals(this.nodeRef, action.getOwningNodeRef());
// Get the action
Action savedAction = this.actionService.getAction(this.nodeRef, actionId);
// Check the owning node ref
assertEquals(this.nodeRef, savedAction.getOwningNodeRef());;
//assertEquals(this.nodeRef, savedAction.getOwningNodeRef());;
}
/**

View File

@@ -46,9 +46,9 @@ public class CompositeActionImpl extends ActionImpl implements CompositeAction
*
* @param id the action id
*/
public CompositeActionImpl(String id, NodeRef owningNodeRef)
public CompositeActionImpl(NodeRef nodeRef, String id)
{
super(id, CompositeActionExecuter.NAME, owningNodeRef);
super(nodeRef, id, CompositeActionExecuter.NAME);
}
/**

View File

@@ -37,11 +37,11 @@ public class CompositeActionImplTest extends ActionImplTest
public void testActions()
{
Action action1 = new ActionImpl(ACTION1_ID, ACTION1_NAME, null);
Action action2 = new ActionImpl(ACTION2_ID, ACTION2_NAME, null);
Action action3 = new ActionImpl(ACTION3_ID, ACTION3_NAME, null);
Action action1 = new ActionImpl(null, ACTION1_ID, ACTION1_NAME, null);
Action action2 = new ActionImpl(null, ACTION2_ID, ACTION2_NAME, null);
Action action3 = new ActionImpl(null, ACTION3_ID, ACTION3_NAME, null);
CompositeAction compositeAction = new CompositeActionImpl(ID, null);
CompositeAction compositeAction = new CompositeActionImpl(null, ID);
// Check has no action
assertFalse(compositeAction.hasActions());

View File

@@ -23,21 +23,38 @@ import org.alfresco.repo.action.ActionServiceImpl.PendingAction;
import org.alfresco.repo.action.evaluator.ActionConditionEvaluator;
import org.alfresco.repo.action.executer.ActionExecuter;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.CompositeAction;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
/**
* @author Roy Wetherall
*/
public interface RuntimeActionService
{
/**
* Get the asynchronous action queue.
*
* @return the asynchronous action queue
*/
AsynchronousActionExecutionQueue getAsynchronousActionExecutionQueue();
/**
* Register an action condition evaluator
*
* @param actionConditionEvaluator action condition evaluator
*/
void registerActionConditionEvaluator(ActionConditionEvaluator actionConditionEvaluator);
/**
* Register an action executer
*
* @param actionExecuter action executer
*/
void registerActionExecuter(ActionExecuter actionExecuter);
void populateCompositeAction(NodeRef compositeNodeRef, CompositeAction compositeAction);
Action createAction(NodeRef actionNodeRef);
NodeRef createActionNodeRef(Action action, NodeRef parentNodeRef, QName assocTypeName, QName assocName);
/**
* Save action, used internally to store the details of an action on the aciton node.
@@ -45,7 +62,7 @@ public interface RuntimeActionService
* @param actionNodeRef the action node reference
* @param action the action
*/
void saveActionImpl(NodeRef owningNodeRef, NodeRef actionNodeRef, Action action);
void saveActionImpl(NodeRef actionNodeRef, Action action);
/**
*
@@ -60,7 +77,18 @@ public interface RuntimeActionService
boolean executedAsynchronously,
Set<String> actionChain);
/**
* Execute an action directly
*
* @param action the action
* @param actionedUponNodeRef the actioned upon node reference
*/
public void directActionExecution(Action action, NodeRef actionedUponNodeRef);
/**
* Gets a list of the actions that are pending post transaction
*
* @return list of pending actions
*/
public List<PendingAction> getPostTransactionPendingActions();
}

View File

@@ -100,7 +100,7 @@ public class AddFeaturesActionExecuterTest extends BaseSpringTest
assertFalse(this.nodeService.hasAspect(this.nodeRef, ContentModel.ASPECT_CLASSIFIABLE));
// Execute the action
ActionImpl action = new ActionImpl(ID, AddFeaturesActionExecuter.NAME, null);
ActionImpl action = new ActionImpl(null, ID, AddFeaturesActionExecuter.NAME, null);
action.setParameterValue(AddFeaturesActionExecuter.PARAM_ASPECT_NAME, ContentModel.ASPECT_CLASSIFIABLE);
this.executer.execute(action, this.nodeRef);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005 Jesper Steen M<>ller
* Copyright (C) 2005 Jesper Steen M<>ller
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
@@ -37,7 +37,7 @@ import org.alfresco.util.GUID;
* Test of the ActionExecuter for extracting metadata. Note: This test makes
* assumptions about the PDF test data for PdfBoxExtracter.
*
* @author Jesper Steen M<>ller
* @author Jesper Steen M<>ller
*/
public class ContentMetadataExtracterTest extends BaseSpringTest
{
@@ -102,7 +102,7 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
this.nodeService.setProperties(this.nodeRef, props);
// Execute the action
ActionImpl action = new ActionImpl(ID, SetPropertyValueActionExecuter.NAME, null);
ActionImpl action = new ActionImpl(null, ID, SetPropertyValueActionExecuter.NAME, null);
this.executer.execute(action, this.nodeRef);
@@ -130,7 +130,7 @@ public class ContentMetadataExtracterTest extends BaseSpringTest
this.nodeService.setProperties(this.nodeRef, props);
// Execute the action
ActionImpl action = new ActionImpl(ID, SetPropertyValueActionExecuter.NAME, null);
ActionImpl action = new ActionImpl(null, ID, SetPropertyValueActionExecuter.NAME, null);
this.executer.execute(action, this.nodeRef);

View File

@@ -133,8 +133,11 @@ public class ExecuteAllRulesActionExecuter extends ActionExecuterAbstractBase
{
for (Rule rule : rules)
{
// Apply the rule to the child node
this.actionService.executeAction(rule, child);
Action action = rule.getAction();
if (action != null)
{
this.actionService.executeAction(action, child);
}
}
}
}

View File

@@ -105,15 +105,18 @@ public class ExecuteAllRulesActionExecuterTest extends BaseSpringTest
ContentModel.TYPE_CONTENT).getChildRef();
// Add a couple of rules to the folder
Rule rule1 = this.ruleService.createRule(RuleType.INBOUND);
Rule rule1 = new Rule();
rule1.setRuleType(RuleType.INBOUND);
Action action1 = this.actionService.createAction(AddFeaturesActionExecuter.NAME);
action1.setParameterValue(AddFeaturesActionExecuter.PARAM_ASPECT_NAME, ContentModel.ASPECT_VERSIONABLE);
rule1.addAction(action1);
rule1.setAction(action1);
this.ruleService.saveRule(folder, rule1);
Rule rule2 = this.ruleService.createRule(RuleType.INBOUND);
Rule rule2 = new Rule();
rule2.setRuleType(RuleType.INBOUND);
Action action2 = this.actionService.createAction(AddFeaturesActionExecuter.NAME);
action2.setParameterValue(AddFeaturesActionExecuter.PARAM_ASPECT_NAME, ContentModel.ASPECT_CLASSIFIABLE);
rule2.addAction(action2);
rule2.setAction(action2);
this.ruleService.saveRule(folder, rule2);
// Check the the docs don't have the aspects yet
@@ -125,7 +128,7 @@ public class ExecuteAllRulesActionExecuterTest extends BaseSpringTest
assertTrue(this.nodeService.exists(folder));
// Execute the action
ActionImpl action = new ActionImpl(ID, ExecuteAllRulesActionExecuter.NAME, null);
ActionImpl action = new ActionImpl(null, ID, ExecuteAllRulesActionExecuter.NAME, null);
this.executer.execute(action, folder);
assertTrue(this.nodeService.hasAspect(doc1, ContentModel.ASPECT_VERSIONABLE));

View File

@@ -101,7 +101,7 @@ public class RemoveFeaturesActionExecuterTest extends BaseSpringTest
assertTrue(this.nodeService.hasAspect(this.nodeRef, ContentModel.ASPECT_CLASSIFIABLE));
// Execute the action
ActionImpl action = new ActionImpl(ID, RemoveFeaturesActionExecuter.NAME, null);
ActionImpl action = new ActionImpl(null, ID, RemoveFeaturesActionExecuter.NAME, null);
action.setParameterValue(RemoveFeaturesActionExecuter.PARAM_ASPECT_NAME, ContentModel.ASPECT_CLASSIFIABLE);
this.executer.execute(action, this.nodeRef);
@@ -109,7 +109,7 @@ public class RemoveFeaturesActionExecuterTest extends BaseSpringTest
assertFalse(this.nodeService.hasAspect(this.nodeRef, ContentModel.ASPECT_CLASSIFIABLE));
// Now try and remove an aspect that is not present
ActionImpl action2 = new ActionImpl(ID, RemoveFeaturesActionExecuter.NAME, null);
ActionImpl action2 = new ActionImpl(null, ID, RemoveFeaturesActionExecuter.NAME, null);
action2.setParameterValue(RemoveFeaturesActionExecuter.PARAM_ASPECT_NAME, ContentModel.ASPECT_VERSIONABLE);
this.executer.execute(action2, this.nodeRef);
}

View File

@@ -79,7 +79,7 @@ public class ScriptActionExecutor extends ActionExecuterAbstractBase
if (nodeService.exists(actionedUponNodeRef))
{
NodeRef scriptRef = (NodeRef)action.getParameterValue(PARAM_SCRIPTREF);
NodeRef spaceRef = (NodeRef)action.getOwningNodeRef();
NodeRef spaceRef = this.serviceRegistry.getRuleService().getOwningNodeRef(action);
if (nodeService.exists(scriptRef))
{

View File

@@ -74,7 +74,7 @@ public class SetPropertyValueActionExecuterTest extends BaseSpringTest
public void testExecution()
{
// Execute the action
ActionImpl action = new ActionImpl(ID, SetPropertyValueActionExecuter.NAME, null);
ActionImpl action = new ActionImpl(null, ID, SetPropertyValueActionExecuter.NAME, null);
action.setParameterValue(SetPropertyValueActionExecuter.PARAM_PROPERTY, ContentModel.PROP_NAME);
action.setParameterValue(SetPropertyValueActionExecuter.PARAM_VALUE, TEST_VALUE);
this.executer.execute(action, this.nodeRef);

View File

@@ -73,7 +73,7 @@ public class SpecialiseTypeActionExecuterTest extends BaseAlfrescoSpringTest
assertEquals(ContentModel.TYPE_CONTENT, this.nodeService.getType(this.nodeRef));
// Execute the action
ActionImpl action = new ActionImpl(ID, SpecialiseTypeActionExecuter.NAME, null);
ActionImpl action = new ActionImpl(null, ID, SpecialiseTypeActionExecuter.NAME, null);
action.setParameterValue(SpecialiseTypeActionExecuter.PARAM_TYPE_NAME, ContentModel.TYPE_FOLDER);
this.executer.execute(action, this.nodeRef);