mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-02 17:35:18 +00:00
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@2851 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
1279 lines
44 KiB
Java
1279 lines
44 KiB
Java
/*
|
|
* Copyright (C) 2005 Alfresco, Inc.
|
|
*
|
|
* Licensed under the Mozilla Public License version 1.1
|
|
* with a permitted attribution clause. You may obtain a
|
|
* copy of the License at
|
|
*
|
|
* http://www.alfresco.org/legal/license.txt
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
* either express or implied. See the License for the specific
|
|
* language governing permissions and limitations under the
|
|
* License.
|
|
*/
|
|
package org.alfresco.repo.action;
|
|
|
|
import java.io.Serializable;
|
|
import java.util.ArrayList;
|
|
import java.util.Date;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
import org.alfresco.model.ContentModel;
|
|
import org.alfresco.repo.action.evaluator.ActionConditionEvaluator;
|
|
import org.alfresco.repo.action.executer.ActionExecuter;
|
|
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
|
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
|
import org.alfresco.service.cmr.action.Action;
|
|
import org.alfresco.service.cmr.action.ActionCondition;
|
|
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.ActionServiceException;
|
|
import org.alfresco.service.cmr.action.CompositeAction;
|
|
import org.alfresco.service.cmr.action.ParameterizedItem;
|
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
|
import org.alfresco.service.cmr.repository.NodeRef;
|
|
import org.alfresco.service.cmr.repository.NodeService;
|
|
import org.alfresco.service.cmr.search.SearchService;
|
|
import org.alfresco.service.namespace.DynamicNamespacePrefixResolver;
|
|
import org.alfresco.service.namespace.NamespaceService;
|
|
import org.alfresco.service.namespace.QName;
|
|
import org.alfresco.service.namespace.RegexQNamePattern;
|
|
import org.alfresco.util.GUID;
|
|
import org.apache.commons.logging.Log;
|
|
import org.apache.commons.logging.LogFactory;
|
|
import org.springframework.beans.BeansException;
|
|
import org.springframework.context.ApplicationContext;
|
|
import org.springframework.context.ApplicationContextAware;
|
|
|
|
/**
|
|
* Action service implementation
|
|
*
|
|
* @author Roy Wetherall
|
|
*/
|
|
public class ActionServiceImpl implements ActionService, RuntimeActionService, ApplicationContextAware
|
|
{
|
|
/**
|
|
* Transaction resource name
|
|
*/
|
|
private static final String POST_TRANSACTION_PENDING_ACTIONS = "postTransactionPendingActions";
|
|
|
|
/**
|
|
* Error message
|
|
*/
|
|
private static final String ERR_FAIL = "The action failed to execute due to an error.";
|
|
|
|
/** Action assoc name */
|
|
private static final QName ASSOC_NAME_ACTIONS = QName.createQName(ActionModel.ACTION_MODEL_URI, "actions");
|
|
|
|
/**
|
|
* The logger
|
|
*/
|
|
private static Log logger = LogFactory.getLog(ActionServiceImpl.class);
|
|
|
|
/**
|
|
* Thread local containing the current action chain
|
|
*/
|
|
ThreadLocal<Set<String>> currentActionChain = new ThreadLocal<Set<String>>();
|
|
|
|
/**
|
|
* The application context
|
|
*/
|
|
private ApplicationContext applicationContext;
|
|
|
|
/**
|
|
* The node service
|
|
*/
|
|
private NodeService nodeService;
|
|
|
|
/**
|
|
* The search service
|
|
*/
|
|
private SearchService searchService;
|
|
|
|
/** The dictionary service */
|
|
private DictionaryService dictionaryService;
|
|
|
|
/** The authentication component */
|
|
private AuthenticationComponent authenticationComponent;
|
|
|
|
/**
|
|
* The asynchronous action execution queue
|
|
*/
|
|
private AsynchronousActionExecutionQueue asynchronousActionExecutionQueue;
|
|
|
|
/**
|
|
* Action transaction listener
|
|
*/
|
|
private ActionTransactionListener transactionListener = new ActionTransactionListener(this);
|
|
|
|
/**
|
|
* All the condition definitions currently registered
|
|
*/
|
|
private Map<String, ActionConditionDefinition> conditionDefinitions = new HashMap<String, ActionConditionDefinition>();
|
|
|
|
/**
|
|
* All the action definitions currently registered
|
|
*/
|
|
private Map<String, ActionDefinition> actionDefinitions = new HashMap<String, ActionDefinition>();
|
|
|
|
/**
|
|
* Set the application context
|
|
*
|
|
* @param applicationContext the application context
|
|
*/
|
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
|
|
{
|
|
this.applicationContext = applicationContext;
|
|
}
|
|
|
|
/**
|
|
* Set the node service
|
|
*
|
|
* @param nodeService the node service
|
|
*/
|
|
public void setNodeService(NodeService nodeService)
|
|
{
|
|
this.nodeService = nodeService;
|
|
}
|
|
|
|
/**
|
|
* Set the search service
|
|
*
|
|
* @param searchService the search service
|
|
*/
|
|
public void setSearchService(SearchService searchService)
|
|
{
|
|
this.searchService = searchService;
|
|
}
|
|
|
|
/**
|
|
* Set the authentication component
|
|
*
|
|
* @param authenticationComponent the authentication component
|
|
*/
|
|
public void setAuthenticationComponent(AuthenticationComponent authenticationComponent)
|
|
{
|
|
this.authenticationComponent = authenticationComponent;
|
|
}
|
|
|
|
/**
|
|
* Set the dictionary service
|
|
*
|
|
* @param dictionaryService the dictionary service
|
|
*/
|
|
public void setDictionaryService(DictionaryService dictionaryService)
|
|
{
|
|
this.dictionaryService = dictionaryService;
|
|
}
|
|
|
|
/**
|
|
* Set the asynchronous action execution queue
|
|
*
|
|
* @param asynchronousActionExecutionQueue the asynchronous action execution queue
|
|
*/
|
|
public void setAsynchronousActionExecutionQueue(
|
|
AsynchronousActionExecutionQueue asynchronousActionExecutionQueue)
|
|
{
|
|
this.asynchronousActionExecutionQueue = asynchronousActionExecutionQueue;
|
|
}
|
|
|
|
/**
|
|
* Get the asychronous action execution queue
|
|
*
|
|
* @return the asynchronous action execution queue
|
|
*/
|
|
public AsynchronousActionExecutionQueue getAsynchronousActionExecutionQueue()
|
|
{
|
|
return asynchronousActionExecutionQueue;
|
|
}
|
|
|
|
/**
|
|
* Gets the saved action folder reference
|
|
*
|
|
* @param nodeRef the node reference
|
|
* @return the node reference
|
|
*/
|
|
private NodeRef getSavedActionFolderRef(NodeRef nodeRef)
|
|
{
|
|
List<ChildAssociationRef> assocs = this.nodeService.getChildAssocs(
|
|
nodeRef,
|
|
RegexQNamePattern.MATCH_ALL,
|
|
ActionModel.ASSOC_ACTION_FOLDER);
|
|
if (assocs.size() != 1)
|
|
{
|
|
throw new ActionServiceException("Unable to retrieve the saved action folder reference.");
|
|
}
|
|
|
|
return assocs.get(0).getChildRef();
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#getActionDefinition(java.lang.String)
|
|
*/
|
|
public ActionDefinition getActionDefinition(String name)
|
|
{
|
|
return this.actionDefinitions.get(name);
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#getActionDefinitions()
|
|
*/
|
|
public List<ActionDefinition> getActionDefinitions()
|
|
{
|
|
return new ArrayList<ActionDefinition>(this.actionDefinitions.values());
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#getActionDefinitions(org.alfresco.service.cmr.repository.NodeRef)
|
|
*/
|
|
public List<ActionDefinition> getActionDefinitions(NodeRef nodeRef)
|
|
{
|
|
if (nodeRef == null)
|
|
{
|
|
return getActionDefinitions();
|
|
}
|
|
else
|
|
{
|
|
// TODO for now we will only filter by type, we will introduce filtering by aspect later
|
|
QName nodeType = this.nodeService.getType(nodeRef);
|
|
List<ActionDefinition> result = new ArrayList<ActionDefinition>();
|
|
for (ActionDefinition actionDefinition : getActionDefinitions())
|
|
{
|
|
List<QName> appliciableTypes = actionDefinition.getApplicableTypes();
|
|
if (appliciableTypes != null && appliciableTypes.isEmpty() == false)
|
|
{
|
|
for (QName applicableType : actionDefinition.getApplicableTypes())
|
|
{
|
|
if (this.dictionaryService.isSubClass(nodeType, applicableType))
|
|
{
|
|
result.add(actionDefinition);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.add(actionDefinition);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#getActionConditionDefinition(java.lang.String)
|
|
*/
|
|
public ActionConditionDefinition getActionConditionDefinition(String name)
|
|
{
|
|
return this.conditionDefinitions.get(name);
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#getActionConditionDefinitions()
|
|
*/
|
|
public List<ActionConditionDefinition> getActionConditionDefinitions()
|
|
{
|
|
return new ArrayList<ActionConditionDefinition>(this.conditionDefinitions.values());
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#createActionCondition(java.lang.String)
|
|
*/
|
|
public ActionCondition createActionCondition(String name)
|
|
{
|
|
return new ActionConditionImpl(GUID.generate(), name);
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#createActionCondition(java.lang.String, java.util.Map)
|
|
*/
|
|
public ActionCondition createActionCondition(String name, Map<String, Serializable> params)
|
|
{
|
|
ActionCondition condition = createActionCondition(name);
|
|
condition.setParameterValues(params);
|
|
return condition;
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#createAction()
|
|
*/
|
|
public Action createAction(String name)
|
|
{
|
|
return new ActionImpl(GUID.generate(),name, null);
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#createAction(java.lang.String, java.util.Map)
|
|
*/
|
|
public Action createAction(String name, Map<String, Serializable> params)
|
|
{
|
|
Action action = createAction(name);
|
|
action.setParameterValues(params);
|
|
return action;
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#createCompositeAction()
|
|
*/
|
|
public CompositeAction createCompositeAction()
|
|
{
|
|
return new CompositeActionImpl(GUID.generate(), null);
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#evaluateAction(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
|
|
*/
|
|
public boolean evaluateAction(Action action, NodeRef actionedUponNodeRef)
|
|
{
|
|
boolean result = true;
|
|
|
|
if (action.hasActionConditions() == true)
|
|
{
|
|
List<ActionCondition> actionConditions = action.getActionConditions();
|
|
for (ActionCondition condition : actionConditions)
|
|
{
|
|
result = result && evaluateActionCondition(condition, actionedUponNodeRef);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#evaluateActionCondition(org.alfresco.service.cmr.action.ActionCondition, org.alfresco.service.cmr.repository.NodeRef)
|
|
*/
|
|
public boolean evaluateActionCondition(ActionCondition condition, NodeRef actionedUponNodeRef)
|
|
{
|
|
boolean result = false;
|
|
|
|
// Evaluate the condition
|
|
ActionConditionEvaluator evaluator = (ActionConditionEvaluator)this.applicationContext.getBean(condition.getActionConditionDefinitionName());
|
|
result = evaluator.evaluate(condition, actionedUponNodeRef);
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#executeAction(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef, boolean)
|
|
*/
|
|
public void executeAction(Action action, NodeRef actionedUponNodeRef, boolean checkConditions)
|
|
{
|
|
executeAction(action, actionedUponNodeRef, checkConditions, action.getExecuteAsychronously());
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#executeAction(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef, boolean)
|
|
*/
|
|
public void executeAction(Action action, NodeRef actionedUponNodeRef, boolean checkConditions, boolean executeAsychronously)
|
|
{
|
|
Set<String> actionChain = this.currentActionChain.get();
|
|
|
|
if (executeAsychronously == false)
|
|
{
|
|
executeActionImpl(action, actionedUponNodeRef, checkConditions, false, actionChain);
|
|
}
|
|
else
|
|
{
|
|
// Add to the post transaction pending action list
|
|
addPostTransactionPendingAction(action, actionedUponNodeRef, checkConditions, actionChain);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.repo.action.RuntimeActionService#executeActionImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef, boolean, org.alfresco.service.cmr.repository.NodeRef)
|
|
*/
|
|
public void executeActionImpl(
|
|
Action action,
|
|
NodeRef actionedUponNodeRef,
|
|
boolean checkConditions,
|
|
boolean executedAsynchronously,
|
|
Set<String> actionChain)
|
|
{
|
|
if (logger.isDebugEnabled() == true)
|
|
{
|
|
StringBuilder builder = new StringBuilder("Exceute action impl action chain = ");
|
|
if (actionChain == null)
|
|
{
|
|
builder.append("null");
|
|
}
|
|
else
|
|
{
|
|
for (String value : actionChain)
|
|
{
|
|
builder.append(value).append(" ");
|
|
}
|
|
}
|
|
logger.debug(builder.toString());
|
|
logger.debug("Current action = " + action.getId());
|
|
}
|
|
|
|
// get the current user early in case the process fails and we are unable to do it later
|
|
String currentUserName = this.authenticationComponent.getCurrentUserName();
|
|
|
|
if (actionChain == null || actionChain.contains(action.getId()) == false)
|
|
{
|
|
if (logger.isDebugEnabled() == true)
|
|
{
|
|
logger.debug("Doing executeActionImpl");
|
|
}
|
|
|
|
try
|
|
{
|
|
Set<String> origActionChain = null;
|
|
|
|
if (actionChain == null)
|
|
{
|
|
actionChain = new HashSet<String>();
|
|
}
|
|
else
|
|
{
|
|
origActionChain = new HashSet<String>(actionChain);
|
|
}
|
|
actionChain.add(action.getId());
|
|
this.currentActionChain.set(actionChain);
|
|
|
|
if (logger.isDebugEnabled() == true)
|
|
{
|
|
logger.debug("Adding " + action.getId() + " to action chain.");
|
|
}
|
|
|
|
try
|
|
{
|
|
// Check and execute now
|
|
if (checkConditions == false || evaluateAction(action, actionedUponNodeRef) == true)
|
|
{
|
|
// Execute the action
|
|
directActionExecution(action, actionedUponNodeRef);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
if (origActionChain == null)
|
|
{
|
|
this.currentActionChain.remove();
|
|
}
|
|
else
|
|
{
|
|
this.currentActionChain.set(origActionChain);
|
|
}
|
|
|
|
if (logger.isDebugEnabled() == true)
|
|
{
|
|
logger.debug("Resetting the action chain.");
|
|
}
|
|
}
|
|
}
|
|
catch (Throwable exception)
|
|
{
|
|
// Log the exception
|
|
logger.error(
|
|
"An error was encountered whilst executing the action '" + action.getActionDefinitionName() + "'.",
|
|
exception);
|
|
|
|
if (executedAsynchronously == true)
|
|
{
|
|
// If one is specified, queue the compensating action ready for execution
|
|
Action compensatingAction = action.getCompensatingAction();
|
|
if (compensatingAction != null)
|
|
{
|
|
// Set the current user
|
|
((ActionImpl)compensatingAction).setRunAsUser(currentUserName);
|
|
|
|
// Queue the compensating action ready for execution
|
|
this.asynchronousActionExecutionQueue.executeAction(this, compensatingAction, actionedUponNodeRef, false, null);
|
|
}
|
|
}
|
|
|
|
// Rethrow the exception
|
|
if (exception instanceof RuntimeException)
|
|
{
|
|
throw (RuntimeException)exception;
|
|
}
|
|
else
|
|
{
|
|
throw new ActionServiceException(ERR_FAIL, exception);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.repo.action.RuntimeActionService#directActionExecution(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef)
|
|
*/
|
|
public void directActionExecution(Action action, NodeRef actionedUponNodeRef)
|
|
{
|
|
// Debug output
|
|
if (logger.isDebugEnabled() == true)
|
|
{
|
|
logger.debug("The action is being executed as the user: " + this.authenticationComponent.getCurrentUserName());
|
|
}
|
|
|
|
// Get the action executer and execute
|
|
ActionExecuter executer = (ActionExecuter)this.applicationContext.getBean(action.getActionDefinitionName());
|
|
executer.execute(action, actionedUponNodeRef);
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#executeAction(org.alfresco.service.cmr.action.Action, NodeRef)
|
|
*/
|
|
public void executeAction(Action action, NodeRef actionedUponNodeRef)
|
|
{
|
|
executeAction(action, actionedUponNodeRef, true);
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.repo.action.RuntimeActionService#registerActionConditionEvaluator(org.alfresco.repo.action.evaluator.ActionConditionEvaluator)
|
|
*/
|
|
public void registerActionConditionEvaluator(ActionConditionEvaluator actionConditionEvaluator)
|
|
{
|
|
ActionConditionDefinition cond = actionConditionEvaluator.getActionConditionDefintion();
|
|
this.conditionDefinitions.put(cond.getName(), cond);
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.repo.action.RuntimeActionService#registerActionExecuter(org.alfresco.repo.action.executer.ActionExecuter)
|
|
*/
|
|
public void registerActionExecuter(ActionExecuter actionExecuter)
|
|
{
|
|
ActionDefinition action = actionExecuter.getActionDefinition();
|
|
this.actionDefinitions.put(action.getName(), action);
|
|
}
|
|
|
|
/**
|
|
* Gets the action node ref from the action id
|
|
*
|
|
* @param nodeRef the node reference
|
|
* @param actionId the acition id
|
|
* @return the action node reference
|
|
*/
|
|
private NodeRef getActionNodeRefFromId(NodeRef nodeRef, String actionId)
|
|
{
|
|
NodeRef result = null;
|
|
|
|
if (this.nodeService.hasAspect(nodeRef, ActionModel.ASPECT_ACTIONS) == true)
|
|
{
|
|
DynamicNamespacePrefixResolver namespacePrefixResolver = new DynamicNamespacePrefixResolver();
|
|
namespacePrefixResolver.registerNamespace(NamespaceService.SYSTEM_MODEL_PREFIX, NamespaceService.SYSTEM_MODEL_1_0_URI);
|
|
|
|
List<NodeRef> nodeRefs = searchService.selectNodes(
|
|
getSavedActionFolderRef(nodeRef),
|
|
"*[@sys:" + ContentModel.PROP_NODE_UUID.getLocalName() + "='" + actionId + "']",
|
|
null,
|
|
namespacePrefixResolver,
|
|
false);
|
|
if (nodeRefs.size() != 0)
|
|
{
|
|
result = nodeRefs.get(0);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#saveAction(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.action.Action)
|
|
*/
|
|
public void saveAction(NodeRef nodeRef, Action action)
|
|
{
|
|
NodeRef actionNodeRef = getActionNodeRefFromId(nodeRef, action.getId());
|
|
if (actionNodeRef == null)
|
|
{
|
|
if (this.nodeService.hasAspect(nodeRef, ActionModel.ASPECT_ACTIONS) == false)
|
|
{
|
|
// 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));
|
|
}
|
|
|
|
saveActionImpl(nodeRef, actionNodeRef, action);
|
|
}
|
|
|
|
/**
|
|
* @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)
|
|
{
|
|
// Set the owning node ref
|
|
((ActionImpl)action).setOwningNodeRef(owningNodeRef);
|
|
|
|
// Save action properties
|
|
saveActionProperties(actionNodeRef, action);
|
|
|
|
// Update the parameters of the action
|
|
saveParameters(actionNodeRef, action);
|
|
|
|
// Update the conditions of the action
|
|
saveConditions(actionNodeRef, action);
|
|
|
|
if (action instanceof CompositeAction)
|
|
{
|
|
// Update composite action
|
|
saveActions(actionNodeRef, (CompositeAction)action);
|
|
}
|
|
|
|
// Update the modified details
|
|
((ActionImpl)action).setModifier((String)this.nodeService.getProperty(actionNodeRef, ContentModel.PROP_MODIFIER));
|
|
((ActionImpl)action).setModifiedDate((Date)this.nodeService.getProperty(actionNodeRef, ContentModel.PROP_MODIFIED));
|
|
}
|
|
|
|
/**
|
|
* Save the action property values
|
|
*
|
|
* @param actionNodeRef the action node reference
|
|
* @param action the action
|
|
*/
|
|
private void saveActionProperties(NodeRef actionNodeRef, Action action)
|
|
{
|
|
// Update the action property values
|
|
Map<QName, Serializable> props = this.nodeService.getProperties(actionNodeRef);
|
|
props.put(ActionModel.PROP_ACTION_TITLE, action.getTitle());
|
|
props.put(ActionModel.PROP_ACTION_DESCRIPTION, action.getDescription());
|
|
props.put(ActionModel.PROP_EXECUTE_ASYNCHRONOUSLY, action.getExecuteAsychronously());
|
|
this.nodeService.setProperties(actionNodeRef, props);
|
|
|
|
// Update the compensating action (model should enforce the singularity of this association)
|
|
Action compensatingAction = action.getCompensatingAction();
|
|
List<ChildAssociationRef> assocs = this.nodeService.getChildAssocs(actionNodeRef, RegexQNamePattern.MATCH_ALL, ActionModel.ASSOC_COMPENSATING_ACTION);
|
|
if (assocs.size() == 0)
|
|
{
|
|
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());
|
|
|
|
NodeRef compensatingActionNodeRef = this.nodeService.createNode(
|
|
actionNodeRef,
|
|
ActionModel.ASSOC_COMPENSATING_ACTION,
|
|
ActionModel.ASSOC_COMPENSATING_ACTION,
|
|
ActionModel.TYPE_ACTION,
|
|
props2).getChildRef();
|
|
|
|
saveActionImpl(compensatingAction.getOwningNodeRef(), compensatingActionNodeRef, compensatingAction);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ChildAssociationRef assoc = assocs.get(0);
|
|
if (compensatingAction == null)
|
|
{
|
|
this.nodeService.removeChild(actionNodeRef, assoc.getChildRef());
|
|
}
|
|
else
|
|
{
|
|
saveActionImpl(compensatingAction.getOwningNodeRef(), assoc.getChildRef(), compensatingAction);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save the actions of a composite action
|
|
*
|
|
* @param compositeActionNodeRef the node reference of the coposite action
|
|
* @param compositeAction the composite action
|
|
*/
|
|
private void saveActions(NodeRef compositeActionNodeRef, CompositeAction compositeAction)
|
|
{
|
|
// TODO Need a way of sorting the order of the actions
|
|
|
|
Map<String, Action> idToAction = new HashMap<String, Action>();
|
|
List<String> orderedIds = new ArrayList<String>();
|
|
for (Action action : compositeAction.getActions())
|
|
{
|
|
idToAction.put(action.getId(), action);
|
|
orderedIds.add(action.getId());
|
|
}
|
|
|
|
List<ChildAssociationRef> actionRefs = this.nodeService.getChildAssocs(compositeActionNodeRef, RegexQNamePattern.MATCH_ALL, ActionModel.ASSOC_ACTIONS);
|
|
for (ChildAssociationRef actionRef : actionRefs)
|
|
{
|
|
NodeRef actionNodeRef = actionRef.getChildRef();
|
|
if (idToAction.containsKey(actionNodeRef.getId()) == false)
|
|
{
|
|
// Delete the action
|
|
this.nodeService.removeChild(compositeActionNodeRef, actionNodeRef);
|
|
}
|
|
else
|
|
{
|
|
// Update the action
|
|
Action action = idToAction.get(actionNodeRef.getId());
|
|
saveActionImpl(action.getOwningNodeRef(), actionNodeRef, action);
|
|
orderedIds.remove(actionNodeRef.getId());
|
|
}
|
|
|
|
}
|
|
|
|
// Create the actions remaining
|
|
for (String actionId : orderedIds)
|
|
{
|
|
Action action = idToAction.get(actionId);
|
|
|
|
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());
|
|
|
|
NodeRef actionNodeRef = this.nodeService.createNode(
|
|
compositeActionNodeRef,
|
|
ActionModel.ASSOC_ACTIONS,
|
|
ActionModel.ASSOC_ACTIONS,
|
|
ActionModel.TYPE_ACTION,
|
|
props).getChildRef();
|
|
|
|
saveActionImpl(action.getOwningNodeRef(), actionNodeRef, action);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Saves the conditions associated with an action
|
|
*
|
|
* @param actionNodeRef the action node reference
|
|
* @param action the action
|
|
*/
|
|
private void saveConditions(NodeRef actionNodeRef, Action action)
|
|
{
|
|
// TODO Need a way of sorting out the order of the conditions
|
|
|
|
Map<String, ActionCondition> idToCondition = new HashMap<String, ActionCondition>();
|
|
List<String> orderedIds = new ArrayList<String>();
|
|
for (ActionCondition actionCondition : action.getActionConditions())
|
|
{
|
|
idToCondition.put(actionCondition.getId(), actionCondition);
|
|
orderedIds.add(actionCondition.getId());
|
|
}
|
|
|
|
List<ChildAssociationRef> conditionRefs = this.nodeService.getChildAssocs(actionNodeRef, RegexQNamePattern.MATCH_ALL, ActionModel.ASSOC_CONDITIONS);
|
|
for (ChildAssociationRef conditionRef : conditionRefs)
|
|
{
|
|
NodeRef conditionNodeRef = conditionRef.getChildRef();
|
|
if (idToCondition.containsKey(conditionNodeRef.getId()) == false)
|
|
{
|
|
// Delete the condition
|
|
this.nodeService.removeChild(actionNodeRef, conditionNodeRef);
|
|
}
|
|
else
|
|
{
|
|
saveConditionProperties(conditionNodeRef, idToCondition.get(conditionNodeRef.getId()));
|
|
|
|
// Update the conditions parameters
|
|
saveParameters(conditionNodeRef, idToCondition.get(conditionNodeRef.getId()));
|
|
orderedIds.remove(conditionNodeRef.getId());
|
|
}
|
|
|
|
}
|
|
|
|
// Create the conditions remaining
|
|
for (String nextId : orderedIds)
|
|
{
|
|
ActionCondition actionCondition = idToCondition.get(nextId);
|
|
Map<QName, Serializable> props = new HashMap<QName, Serializable>(2);
|
|
props.put(ActionModel.PROP_DEFINITION_NAME, actionCondition.getActionConditionDefinitionName());
|
|
props.put(ContentModel.PROP_NODE_UUID, actionCondition.getId());
|
|
|
|
NodeRef conditionNodeRef = this.nodeService.createNode(
|
|
actionNodeRef,
|
|
ActionModel.ASSOC_CONDITIONS,
|
|
ActionModel.ASSOC_CONDITIONS,
|
|
ActionModel.TYPE_ACTION_CONDITION,
|
|
props).getChildRef();
|
|
|
|
saveConditionProperties(conditionNodeRef, actionCondition);
|
|
saveParameters(conditionNodeRef, actionCondition);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save the condition properties
|
|
*
|
|
* @param conditionNodeRef
|
|
* @param condition
|
|
*/
|
|
private void saveConditionProperties(NodeRef conditionNodeRef, ActionCondition condition)
|
|
{
|
|
this.nodeService.setProperty(conditionNodeRef, ActionModel.PROP_CONDITION_INVERT, condition.getInvertCondition());
|
|
|
|
}
|
|
|
|
/**
|
|
* Saves the parameters associated with an action or condition
|
|
*
|
|
* @param parameterizedNodeRef the parameterized item node reference
|
|
* @param item the parameterized item
|
|
*/
|
|
private void saveParameters(NodeRef parameterizedNodeRef, ParameterizedItem item)
|
|
{
|
|
Map<String, Serializable> parameterMap = new HashMap<String, Serializable>();
|
|
parameterMap.putAll(item.getParameterValues());
|
|
|
|
List<ChildAssociationRef> parameters = this.nodeService.getChildAssocs(parameterizedNodeRef, RegexQNamePattern.MATCH_ALL, ActionModel.ASSOC_PARAMETERS);
|
|
for (ChildAssociationRef ref : parameters)
|
|
{
|
|
NodeRef paramNodeRef = ref.getChildRef();
|
|
Map<QName, Serializable> nodeRefParameterMap = this.nodeService.getProperties(paramNodeRef);
|
|
String paramName = (String)nodeRefParameterMap.get(ActionModel.PROP_PARAMETER_NAME);
|
|
if (parameterMap.containsKey(paramName) == false)
|
|
{
|
|
// Delete parameter from node ref
|
|
this.nodeService.removeChild(parameterizedNodeRef, paramNodeRef);
|
|
}
|
|
else
|
|
{
|
|
// Update the parameter value
|
|
nodeRefParameterMap.put(ActionModel.PROP_PARAMETER_VALUE, parameterMap.get(paramName));
|
|
this.nodeService.setProperties(paramNodeRef, nodeRefParameterMap);
|
|
parameterMap.remove(paramName);
|
|
}
|
|
}
|
|
|
|
// Add any remaing parameters
|
|
for (Map.Entry<String, Serializable> entry : parameterMap.entrySet())
|
|
{
|
|
Map<QName, Serializable> nodeRefProperties = new HashMap<QName, Serializable>(2);
|
|
nodeRefProperties.put(ActionModel.PROP_PARAMETER_NAME, entry.getKey());
|
|
nodeRefProperties.put(ActionModel.PROP_PARAMETER_VALUE, entry.getValue());
|
|
|
|
this.nodeService.createNode(
|
|
parameterizedNodeRef,
|
|
ActionModel.ASSOC_PARAMETERS,
|
|
ActionModel.ASSOC_PARAMETERS,
|
|
ActionModel.TYPE_ACTION_PARAMETER,
|
|
nodeRefProperties);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#getActions(org.alfresco.service.cmr.repository.NodeRef)
|
|
*/
|
|
public List<Action> getActions(NodeRef nodeRef)
|
|
{
|
|
List<Action> result = new ArrayList<Action>();
|
|
|
|
if (this.nodeService.exists(nodeRef) == true &&
|
|
this.nodeService.hasAspect(nodeRef, ActionModel.ASPECT_ACTIONS) == true)
|
|
{
|
|
List<ChildAssociationRef> actions = this.nodeService.getChildAssocs(
|
|
getSavedActionFolderRef(nodeRef),
|
|
RegexQNamePattern.MATCH_ALL, ASSOC_NAME_ACTIONS);
|
|
for (ChildAssociationRef action : actions)
|
|
{
|
|
NodeRef actionNodeRef = action.getChildRef();
|
|
result.add(createAction(nodeRef, actionNodeRef));
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Create an action from the action node reference
|
|
*
|
|
* @param actionNodeRef the action node reference
|
|
* @return the action
|
|
*/
|
|
private Action createAction(NodeRef owningNodeRef, NodeRef actionNodeRef)
|
|
{
|
|
Action result = null;
|
|
|
|
Map<QName, Serializable> properties = this.nodeService.getProperties(actionNodeRef);
|
|
|
|
QName actionType = this.nodeService.getType(actionNodeRef);
|
|
if (ActionModel.TYPE_COMPOSITE_ACTION.equals(actionType) == true)
|
|
{
|
|
// Create a composite action
|
|
result = new CompositeActionImpl(actionNodeRef.getId(), owningNodeRef);
|
|
populateCompositeAction(actionNodeRef, (CompositeAction)result);
|
|
}
|
|
else
|
|
{
|
|
// Create an action
|
|
result = new ActionImpl(actionNodeRef.getId(), (String)properties.get(ActionModel.PROP_DEFINITION_NAME), owningNodeRef);
|
|
populateAction(actionNodeRef, result);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Populate the details of the action from the node reference
|
|
*
|
|
* @param actionNodeRef the action node reference
|
|
* @param action the action
|
|
*/
|
|
private void populateAction(NodeRef actionNodeRef, Action action)
|
|
{
|
|
// Populate the action properties
|
|
populateActionProperties(actionNodeRef, action);
|
|
|
|
// Set the parameters
|
|
populateParameters(actionNodeRef, action);
|
|
|
|
// Set the conditions
|
|
List<ChildAssociationRef> conditions = this.nodeService.getChildAssocs(actionNodeRef, RegexQNamePattern.MATCH_ALL, ActionModel.ASSOC_CONDITIONS);
|
|
for (ChildAssociationRef condition : conditions)
|
|
{
|
|
NodeRef conditionNodeRef = condition.getChildRef();
|
|
action.addActionCondition(createActionCondition(conditionNodeRef));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Populates the action properties from the node reference
|
|
*
|
|
* @param actionNodeRef the action node reference
|
|
* @param action the action
|
|
*/
|
|
private void populateActionProperties(NodeRef actionNodeRef, Action action)
|
|
{
|
|
Map<QName, Serializable> props = this.nodeService.getProperties(actionNodeRef);
|
|
|
|
action.setTitle((String)props.get(ActionModel.PROP_ACTION_TITLE));
|
|
action.setDescription((String)props.get(ActionModel.PROP_ACTION_DESCRIPTION));
|
|
|
|
boolean value = false;
|
|
Boolean executeAsynchronously = (Boolean)props.get(ActionModel.PROP_EXECUTE_ASYNCHRONOUSLY);
|
|
if (executeAsynchronously != null)
|
|
{
|
|
value = executeAsynchronously.booleanValue();
|
|
}
|
|
action.setExecuteAsynchronously(value);
|
|
|
|
((ActionImpl)action).setCreator((String)props.get(ContentModel.PROP_CREATOR));
|
|
((ActionImpl)action).setCreatedDate((Date)props.get(ContentModel.PROP_CREATED));
|
|
((ActionImpl)action).setModifier((String)props.get(ContentModel.PROP_MODIFIER));
|
|
((ActionImpl)action).setModifiedDate((Date)props.get(ContentModel.PROP_MODIFIED));
|
|
|
|
// Get the compensating action
|
|
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.setCompensatingAction(compensatingAction);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Populate the parameteres of a parameterized item from the parameterized item node reference
|
|
*
|
|
* @param parameterizedItemNodeRef the parameterized item node reference
|
|
* @param parameterizedItem the parameterized item
|
|
*/
|
|
private void populateParameters(NodeRef parameterizedItemNodeRef, ParameterizedItem parameterizedItem)
|
|
{
|
|
List<ChildAssociationRef> parameters = this.nodeService.getChildAssocs(parameterizedItemNodeRef, RegexQNamePattern.MATCH_ALL, ActionModel.ASSOC_PARAMETERS);
|
|
for (ChildAssociationRef parameter : parameters)
|
|
{
|
|
NodeRef parameterNodeRef = parameter.getChildRef();
|
|
Map<QName, Serializable> properties = this.nodeService.getProperties(parameterNodeRef);
|
|
parameterizedItem.setParameterValue(
|
|
(String)properties.get(ActionModel.PROP_PARAMETER_NAME),
|
|
properties.get(ActionModel.PROP_PARAMETER_VALUE));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates an action condition from an action condition node reference
|
|
*
|
|
* @param conditionNodeRef the condition node reference
|
|
* @return the action condition
|
|
*/
|
|
private ActionCondition createActionCondition(NodeRef conditionNodeRef)
|
|
{
|
|
Map<QName, Serializable> properties = this.nodeService.getProperties(conditionNodeRef);
|
|
ActionCondition condition = new ActionConditionImpl(conditionNodeRef.getId(), (String)properties.get(ActionModel.PROP_DEFINITION_NAME));
|
|
|
|
boolean value = false;
|
|
Boolean invert = (Boolean)this.nodeService.getProperty(conditionNodeRef, ActionModel.PROP_CONDITION_INVERT);
|
|
if (invert != null)
|
|
{
|
|
value = invert.booleanValue();
|
|
}
|
|
condition.setInvertCondition(value);
|
|
|
|
populateParameters(conditionNodeRef, condition);
|
|
return condition;
|
|
}
|
|
|
|
/**
|
|
* Populates a composite action from a composite action node reference
|
|
*
|
|
* @param compositeNodeRef the composite action node reference
|
|
* @param compositeAction the composite action
|
|
*/
|
|
public void populateCompositeAction(NodeRef compositeNodeRef, CompositeAction compositeAction)
|
|
{
|
|
populateAction(compositeNodeRef, compositeAction);
|
|
|
|
List<ChildAssociationRef> actions = this.nodeService.getChildAssocs(compositeNodeRef, RegexQNamePattern.MATCH_ALL, ActionModel.ASSOC_ACTIONS);
|
|
for (ChildAssociationRef action : actions)
|
|
{
|
|
NodeRef actionNodeRef = action.getChildRef();
|
|
compositeAction.addAction(createAction(compositeAction.getOwningNodeRef(), actionNodeRef));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#getAction(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
|
|
*/
|
|
public Action getAction(NodeRef nodeRef, String actionId)
|
|
{
|
|
Action result = null;
|
|
|
|
if (this.nodeService.exists(nodeRef) == true &&
|
|
this.nodeService.hasAspect(nodeRef, ActionModel.ASPECT_ACTIONS) == true)
|
|
{
|
|
NodeRef actionNodeRef = getActionNodeRefFromId(nodeRef, actionId);
|
|
if (actionNodeRef != null)
|
|
{
|
|
result = createAction(nodeRef, actionNodeRef);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#removeAction(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.action.Action)
|
|
*/
|
|
public void removeAction(NodeRef nodeRef, Action action)
|
|
{
|
|
if (this.nodeService.exists(nodeRef) == true &&
|
|
this.nodeService.hasAspect(nodeRef, ActionModel.ASPECT_ACTIONS) == true)
|
|
{
|
|
NodeRef actionNodeRef = getActionNodeRefFromId(nodeRef, action.getId());
|
|
if (actionNodeRef != null)
|
|
{
|
|
this.nodeService.removeChild(getSavedActionFolderRef(nodeRef), actionNodeRef);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.service.cmr.action.ActionService#removeAllActions(org.alfresco.service.cmr.repository.NodeRef)
|
|
*/
|
|
public void removeAllActions(NodeRef nodeRef)
|
|
{
|
|
if (this.nodeService.exists(nodeRef) == true &&
|
|
this.nodeService.hasAspect(nodeRef, ActionModel.ASPECT_ACTIONS) == true)
|
|
{
|
|
List<ChildAssociationRef> actions = new ArrayList<ChildAssociationRef>(this.nodeService.getChildAssocs(getSavedActionFolderRef(nodeRef), RegexQNamePattern.MATCH_ALL, ASSOC_NAME_ACTIONS));
|
|
for (ChildAssociationRef action : actions)
|
|
{
|
|
this.nodeService.removeChild(getSavedActionFolderRef(nodeRef), action.getChildRef());
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add a pending action to the list to be queued for execution once the transaction is completed.
|
|
*
|
|
* @param action the action
|
|
* @param actionedUponNodeRef the actioned upon node reference
|
|
* @param checkConditions indicates whether to check the conditions before execution
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
private void addPostTransactionPendingAction(
|
|
Action action,
|
|
NodeRef actionedUponNodeRef,
|
|
boolean checkConditions,
|
|
Set<String> actionChain)
|
|
{
|
|
if (logger.isDebugEnabled() == true)
|
|
{
|
|
StringBuilder builder = new StringBuilder("addPostTransactionPendingAction action chain = ");
|
|
if (actionChain == null)
|
|
{
|
|
builder.append("null");
|
|
}
|
|
else
|
|
{
|
|
for (String value : actionChain)
|
|
{
|
|
builder.append(value).append(" ");
|
|
}
|
|
}
|
|
logger.debug(builder.toString());
|
|
logger.debug("Current action = " + action.getId());
|
|
}
|
|
|
|
// Don't continue if the action is already in the action chain
|
|
if (actionChain == null || actionChain.contains(action.getId()) == false)
|
|
{
|
|
if (logger.isDebugEnabled() == true)
|
|
{
|
|
logger.debug("Doing addPostTransactionPendingAction");
|
|
}
|
|
|
|
// Set the run as user to the current user
|
|
if (logger.isDebugEnabled() == true)
|
|
{
|
|
logger.debug("The current user is: " + this.authenticationComponent.getCurrentUserName());
|
|
}
|
|
((ActionImpl)action).setRunAsUser(this.authenticationComponent.getCurrentUserName());
|
|
|
|
// Ensure that the transaction listener is bound to the transaction
|
|
AlfrescoTransactionSupport.bindListener(this.transactionListener);
|
|
|
|
// Add the pending action to the transaction resource
|
|
List<PendingAction> pendingActions = (List<PendingAction>)AlfrescoTransactionSupport.getResource(POST_TRANSACTION_PENDING_ACTIONS);
|
|
if (pendingActions == null)
|
|
{
|
|
pendingActions = new ArrayList<PendingAction>();
|
|
AlfrescoTransactionSupport.bindResource(POST_TRANSACTION_PENDING_ACTIONS, pendingActions);
|
|
}
|
|
|
|
// Check that action has only been added to the list once
|
|
PendingAction pendingAction = new PendingAction(action, actionedUponNodeRef, checkConditions, actionChain);
|
|
if (pendingActions.contains(pendingAction) == false)
|
|
{
|
|
pendingActions.add(pendingAction);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @see org.alfresco.repo.action.RuntimeActionService#getPostTransactionPendingActions()
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
public List<PendingAction> getPostTransactionPendingActions()
|
|
{
|
|
return (List<PendingAction>)AlfrescoTransactionSupport.getResource(POST_TRANSACTION_PENDING_ACTIONS);
|
|
}
|
|
|
|
/**
|
|
* Pending action details class
|
|
*/
|
|
public class PendingAction
|
|
{
|
|
/**
|
|
* The action
|
|
*/
|
|
private Action action;
|
|
|
|
/**
|
|
* The actioned upon node reference
|
|
*/
|
|
private NodeRef actionedUponNodeRef;
|
|
|
|
/**
|
|
* Indicates whether the conditions should be checked before the action is executed
|
|
*/
|
|
private boolean checkConditions;
|
|
|
|
private Set<String> actionChain;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param action the action
|
|
* @param actionedUponNodeRef the actioned upon node reference
|
|
* @param checkConditions indicated whether the conditions need to be checked
|
|
*/
|
|
public PendingAction(Action action, NodeRef actionedUponNodeRef, boolean checkConditions, Set<String> actionChain)
|
|
{
|
|
this.action = action;
|
|
this.actionedUponNodeRef = actionedUponNodeRef;
|
|
this.checkConditions = checkConditions;
|
|
this.actionChain = actionChain;
|
|
}
|
|
|
|
/**
|
|
* Get the action
|
|
*
|
|
* @return the action
|
|
*/
|
|
public Action getAction()
|
|
{
|
|
return action;
|
|
}
|
|
|
|
/**
|
|
* Get the actioned upon node reference
|
|
*
|
|
* @return the actioned upon node reference
|
|
*/
|
|
public NodeRef getActionedUponNodeRef()
|
|
{
|
|
return actionedUponNodeRef;
|
|
}
|
|
|
|
/**
|
|
* Get the check conditions value
|
|
*
|
|
* @return indicates whether the condition should be checked
|
|
*/
|
|
public boolean getCheckConditions()
|
|
{
|
|
return this.checkConditions;
|
|
}
|
|
|
|
public Set<String> getActionChain()
|
|
{
|
|
return this.actionChain;
|
|
}
|
|
|
|
/**
|
|
* @see java.lang.Object#hashCode()
|
|
*/
|
|
@Override
|
|
public int hashCode()
|
|
{
|
|
int hashCode = 37 * this.actionedUponNodeRef.hashCode();
|
|
hashCode += 37 * this.action.hashCode();
|
|
return hashCode;
|
|
}
|
|
|
|
/**
|
|
* @see java.lang.Object#equals(java.lang.Object)
|
|
*/
|
|
@Override
|
|
public boolean equals(Object obj)
|
|
{
|
|
if (this == obj)
|
|
{
|
|
return true;
|
|
}
|
|
if (obj instanceof PendingAction)
|
|
{
|
|
PendingAction that = (PendingAction) obj;
|
|
return (this.action.equals(that.action) && this.actionedUponNodeRef.equals(that.actionedUponNodeRef));
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|