#java #workflow #alfresco #activiti
Вопрос:
У меня есть версия сообщества Alfresco, версия 5.2, с реализованным пользовательским рабочим процессом. Таков сценарий:
пользователь загружает документ в платформу и выбирает другого пользователя в качестве автора документа. Затем он запускает этот рабочий процесс с пользовательской логикой, как если бы его начал автор документа.
Я добился этого, переназначив инициатор рабочего процесса с помощью прослушивателя выполнения, сразу после запуска ScriptExecutionListener, но я получил всплывающее сообщение об ошибке, ничего не регистрируется в консоли или браузере.
Вот мое определение рабочего процесса
<?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>
...
а вот мой класс Java
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?
I also posted the question on Alfresco forum, original link
Thanks