Hello to everyone,
I have an Alfresco Community edition, version 5.2, with a custom workflow implemented. This is the scenario:
a user loads a document into the platform and choose another user to be the document's author. Then he starts this workflow with the custom logic, as if the document's author would have started it.
I achieved this reassigning the workflow initiator with an execution listener, just after the start ScriptExecutionListener, but I got this error message popop, nothing is logged to console or browser.
Here is my workflow definition
<?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://alfresco.org"> <process id="myWorkflow" name="Parallel Review And Approve Document Activiti Process" isExecutable="true"> <extensionElements> <activiti:executionListener event="start" class="org.alfresco.repo.workflow.activiti.listener.ScriptExecutionListener"> <activiti:field name="script"> <activiti:string><![CDATA[// custom logic ]]></activiti:string> </activiti:field> </activiti:executionListener> </extensionElements> <startEvent id="StartEvent" activiti:formKey="mywf:submitParallelReviewTask"> <extensionElements> <activiti:executionListener event="start" class="com.activiti.extension.bean.SetAuthorAsWFInitiator"></activiti:executionListener> </extensionElements> </startEvent> ...
and here is my Java class
package com.activiti.extension.bean; import java.util.List; import java.util.Map; import org.activiti.engine.delegate.DelegateExecution; import org.activiti.engine.delegate.ExecutionListener; import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.activiti.engine.impl.context.Context; import org.activiti.engine.impl.interceptor.Command; import org.activiti.engine.impl.interceptor.CommandContext; import org.alfresco.model.ContentModel; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.workflow.activiti.ActivitiConstants; import org.alfresco.repo.workflow.activiti.ActivitiScriptNode; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * * <p> * Execution Listener to change workflow initiator. * </p> * <p> * Changes the inititator and initiatorhome variables as the WF initiator would have been the document's author. * </p> * <p> * Also, it changes the value of the start_user_id column of act_hi_procinst table * </p> * */ public class SetAuthorAsWFInitiator implements ExecutionListener { private static final Log logger = LogFactory.getLog(SetAuthorAsWFInitiator.class); private static final long serialVersionUID = 1095132995665073418L; private static final String INITIATOR = "initiator"; private static final String INITIATOR_HOME = "initiatorhome"; @Override public void notify(DelegateExecution execution) throws Exception { AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>() { @Override public Object doWork() throws Exception { ProcessEngineConfigurationImpl processEngineConfiguration = Context.getProcessEngineConfiguration(); Map<Object, Object> registeredBeans = processEngineConfiguration.getBeans(); ServiceRegistry serviceRegistry = (ServiceRegistry) registeredBeans.get(ActivitiConstants.SERVICE_REGISTRY_BEAN_KEY); NodeService nodeService = serviceRegistry.getNodeService(); ActivitiScriptNode bpm_package = (ActivitiScriptNode) execution.getVariable("bpm_package"); List<ChildAssociationRef> childAssocs = nodeService.getChildAssocs(bpm_package.getNodeRef()); NodeRef documentNode = childAssocs.get(0).getChildRef(); logger.debug("documentNode: " + documentNode); List<AssociationRef> authorAssoc = nodeService.getTargetAssocs(documentNode, Constants.AUTHOR_ASSOC); NodeRef authorNodeRef = authorAssoc.get(0).getTargetRef(); NodeRef authorHomeFolderNodeRef = (NodeRef) nodeService.getProperty(authorNodeRef, ContentModel.PROP_HOMEFOLDER); logger.debug("creatorNodeRef: " + authorNodeRef); ActivitiScriptNode initiator = (ActivitiScriptNode) execution.getVariable(INITIATOR); ActivitiScriptNode authorInitiator = new ActivitiScriptNode(authorNodeRef, serviceRegistry); ActivitiScriptNode authorInitiatorHome = new ActivitiScriptNode(authorHomeFolderNodeRef, serviceRegistry); logger.debug("initiator: " + initiator); logger.debug("newInitiator: " + authorInitiator); if (!initiator.equals(authorInitiator)) { execution.setVariable(INITIATOR, authorInitiator); execution.setVariable(INITIATOR_HOME, authorInitiatorHome); logger.info("WF Initiator (" + initiator.getNodeRef() + ") has been reassigned to author: " + authorNodeRef); processEngineConfiguration.getCommandExecutor().execute(new Command<Object>() { public Object execute(CommandContext commandContext) { commandContext .getHistoricProcessInstanceEntityManager() .findHistoricProcessInstance(execution.getProcessInstanceId()) .setStartUserId((String) nodeService.getProperty(authorNodeRef, ContentModel.PROP_USERNAME)); return commandContext; } }); logger.debug("WF Initiator on table act_hi_procinst has been changed to author: " + authorInitiator); } return null; } }, AuthenticationUtil.getAdminUserName()); } }
What am I missing?
why if I start the workflow within the API instead of using the default form processor the workflow is started and the initiator switched correctly?
Thanks
Ask for and offer help to other Alfresco Content Services Users and members of the Alfresco team.
Related links:
By using this site, you are agreeing to allow us to collect and use cookies as outlined in Alfresco’s Cookie Statement and Terms of Use (and you have a legitimate interest in Alfresco and our products, authorizing us to contact you in such methods). If you are not ok with these terms, please do not use this website.