
org.bonitasoft.engine.execution.StateBehaviors Maven / Gradle / Ivy
/**
* Copyright (C) 2015 Bonitasoft S.A.
* Bonitasoft, 32 rue Gustave Eiffel - 38000 Grenoble
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation
* version 2.1 of the License.
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301, USA.
**/
package org.bonitasoft.engine.execution;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import org.bonitasoft.engine.actor.mapping.ActorMappingService;
import org.bonitasoft.engine.actor.mapping.SActorNotFoundException;
import org.bonitasoft.engine.actor.mapping.model.SActor;
import org.bonitasoft.engine.bpm.connector.ConnectorEvent;
import org.bonitasoft.engine.bpm.connector.ConnectorState;
import org.bonitasoft.engine.bpm.model.impl.BPMInstancesCreator;
import org.bonitasoft.engine.bpm.process.ProcessInstanceState;
import org.bonitasoft.engine.builder.BuilderFactory;
import org.bonitasoft.engine.classloader.ClassLoaderService;
import org.bonitasoft.engine.classloader.SClassLoaderException;
import org.bonitasoft.engine.commons.exceptions.SBonitaException;
import org.bonitasoft.engine.core.connector.ConnectorInstanceService;
import org.bonitasoft.engine.core.connector.exception.SConnectorInstanceModificationException;
import org.bonitasoft.engine.core.connector.exception.SConnectorInstanceReadException;
import org.bonitasoft.engine.core.expression.control.api.ExpressionResolverService;
import org.bonitasoft.engine.core.expression.control.model.SExpressionContext;
import org.bonitasoft.engine.core.filter.FilterResult;
import org.bonitasoft.engine.core.filter.UserFilterService;
import org.bonitasoft.engine.core.filter.exception.SUserFilterExecutionException;
import org.bonitasoft.engine.core.operation.OperationService;
import org.bonitasoft.engine.core.operation.exception.SOperationExecutionException;
import org.bonitasoft.engine.core.operation.model.SOperation;
import org.bonitasoft.engine.core.process.comment.api.SCommentAddException;
import org.bonitasoft.engine.core.process.comment.api.SCommentService;
import org.bonitasoft.engine.core.process.comment.api.SystemCommentType;
import org.bonitasoft.engine.core.process.definition.ProcessDefinitionService;
import org.bonitasoft.engine.core.process.definition.exception.SProcessDefinitionNotFoundException;
import org.bonitasoft.engine.core.process.definition.model.SActivityDefinition;
import org.bonitasoft.engine.core.process.definition.model.SBusinessDataDefinition;
import org.bonitasoft.engine.core.process.definition.model.SCallActivityDefinition;
import org.bonitasoft.engine.core.process.definition.model.SConnectorDefinition;
import org.bonitasoft.engine.core.process.definition.model.SFlowElementContainerDefinition;
import org.bonitasoft.engine.core.process.definition.model.SFlowNodeDefinition;
import org.bonitasoft.engine.core.process.definition.model.SFlowNodeType;
import org.bonitasoft.engine.core.process.definition.model.SHumanTaskDefinition;
import org.bonitasoft.engine.core.process.definition.model.SLoopCharacteristics;
import org.bonitasoft.engine.core.process.definition.model.SMultiInstanceLoopCharacteristics;
import org.bonitasoft.engine.core.process.definition.model.SProcessDefinition;
import org.bonitasoft.engine.core.process.definition.model.SReceiveTaskDefinition;
import org.bonitasoft.engine.core.process.definition.model.SSendTaskDefinition;
import org.bonitasoft.engine.core.process.definition.model.SUserFilterDefinition;
import org.bonitasoft.engine.core.process.definition.model.event.SBoundaryEventDefinition;
import org.bonitasoft.engine.core.process.definition.model.event.SCatchEventDefinition;
import org.bonitasoft.engine.core.process.definition.model.event.SIntermediateCatchEventDefinition;
import org.bonitasoft.engine.core.process.definition.model.event.SThrowEventDefinition;
import org.bonitasoft.engine.core.process.instance.api.ActivityInstanceService;
import org.bonitasoft.engine.core.process.instance.api.RefBusinessDataService;
import org.bonitasoft.engine.core.process.instance.api.event.EventInstanceService;
import org.bonitasoft.engine.core.process.instance.api.exceptions.SActivityCreationException;
import org.bonitasoft.engine.core.process.instance.api.exceptions.SActivityExecutionException;
import org.bonitasoft.engine.core.process.instance.api.exceptions.SActivityModificationException;
import org.bonitasoft.engine.core.process.instance.api.exceptions.SActivityStateExecutionException;
import org.bonitasoft.engine.core.process.instance.api.exceptions.SContractViolationException;
import org.bonitasoft.engine.core.process.instance.api.exceptions.SFlowNodeNotFoundException;
import org.bonitasoft.engine.core.process.instance.api.exceptions.SFlowNodeReadException;
import org.bonitasoft.engine.core.process.instance.api.exceptions.SProcessInstanceCreationException;
import org.bonitasoft.engine.core.process.instance.api.exceptions.business.data.SRefBusinessDataInstanceModificationException;
import org.bonitasoft.engine.core.process.instance.api.exceptions.business.data.SRefBusinessDataInstanceNotFoundException;
import org.bonitasoft.engine.core.process.instance.model.SActivityInstance;
import org.bonitasoft.engine.core.process.instance.model.SCallActivityInstance;
import org.bonitasoft.engine.core.process.instance.model.SConnectorInstance;
import org.bonitasoft.engine.core.process.instance.model.SFlowElementsContainerType;
import org.bonitasoft.engine.core.process.instance.model.SFlowNodeInstance;
import org.bonitasoft.engine.core.process.instance.model.SHumanTaskInstance;
import org.bonitasoft.engine.core.process.instance.model.SMultiInstanceActivityInstance;
import org.bonitasoft.engine.core.process.instance.model.SPendingActivityMapping;
import org.bonitasoft.engine.core.process.instance.model.SProcessInstance;
import org.bonitasoft.engine.core.process.instance.model.SReceiveTaskInstance;
import org.bonitasoft.engine.core.process.instance.model.SSendTaskInstance;
import org.bonitasoft.engine.core.process.instance.model.SStateCategory;
import org.bonitasoft.engine.core.process.instance.model.builder.SMultiInstanceActivityInstanceBuilderFactory;
import org.bonitasoft.engine.core.process.instance.model.builder.event.SBoundaryEventInstanceBuilderFactory;
import org.bonitasoft.engine.core.process.instance.model.business.data.SFlowNodeSimpleRefBusinessDataInstance;
import org.bonitasoft.engine.core.process.instance.model.business.data.SMultiRefBusinessDataInstance;
import org.bonitasoft.engine.core.process.instance.model.business.data.SRefBusinessDataInstance;
import org.bonitasoft.engine.core.process.instance.model.event.SBoundaryEventInstance;
import org.bonitasoft.engine.core.process.instance.model.event.SCatchEventInstance;
import org.bonitasoft.engine.core.process.instance.model.event.SIntermediateCatchEventInstance;
import org.bonitasoft.engine.core.process.instance.model.event.SThrowEventInstance;
import org.bonitasoft.engine.data.instance.api.DataInstanceContainer;
import org.bonitasoft.engine.data.instance.api.DataInstanceService;
import org.bonitasoft.engine.data.instance.api.ParentContainerResolver;
import org.bonitasoft.engine.data.instance.exception.SDataInstanceException;
import org.bonitasoft.engine.data.instance.model.SDataInstance;
import org.bonitasoft.engine.dependency.model.ScopeType;
import org.bonitasoft.engine.exception.BonitaRuntimeException;
import org.bonitasoft.engine.execution.event.EventsHandler;
import org.bonitasoft.engine.execution.work.BPMWorkFactory;
import org.bonitasoft.engine.expression.exception.SExpressionDependencyMissingException;
import org.bonitasoft.engine.expression.exception.SExpressionEvaluationException;
import org.bonitasoft.engine.expression.exception.SExpressionException;
import org.bonitasoft.engine.expression.exception.SExpressionTypeUnknownException;
import org.bonitasoft.engine.expression.exception.SInvalidExpressionException;
import org.bonitasoft.engine.expression.model.SExpression;
import org.bonitasoft.engine.identity.IdentityService;
import org.bonitasoft.engine.identity.SUserNotFoundException;
import org.bonitasoft.engine.identity.model.SUser;
import org.bonitasoft.engine.persistence.QueryOptions;
import org.bonitasoft.engine.persistence.SBonitaReadException;
import org.bonitasoft.engine.recorder.model.EntityUpdateDescriptor;
import org.bonitasoft.engine.transaction.BonitaTransactionSynchronization;
import org.bonitasoft.engine.transaction.TransactionState;
import org.bonitasoft.engine.transaction.UserTransactionService;
import org.bonitasoft.engine.work.SWorkRegisterException;
import org.bonitasoft.engine.work.WorkService;
/**
* @author Baptiste Mesta
* @author Matthieu Chaffotte
* @author Celine Souchet
*/
public class StateBehaviors {
private static final int BATCH_SIZE = 20;
protected final ParentContainerResolver parentContainerResolver;
private final BPMInstancesCreator bpmInstancesCreator;
private final EventsHandler eventsHandler;
private final ActivityInstanceService activityInstanceService;
private final UserFilterService userFilterService;
private final ClassLoaderService classLoaderService;
private final ActorMappingService actorMappingService;
private final ExpressionResolverService expressionResolverService;
private final ProcessDefinitionService processDefinitionService;
private final DataInstanceService dataInstanceService;
private final OperationService operationService;
private final WorkService workService;
private final ContainerRegistry containerRegistry;
private final EventInstanceService eventInstanceService;
private final ConnectorInstanceService connectorInstanceService;
private final SCommentService commentService;
private final IdentityService identityService;
private final WaitingEventsInterrupter waitingEventsInterrupter;
private final RefBusinessDataService refBusinessDataService;
private ProcessExecutor processExecutor;
private final BPMWorkFactory workFactory;
private ProcessInstanceInterruptor processInstanceInterruptor;
private final UserTransactionService userTransactionService;
public StateBehaviors(final BPMInstancesCreator bpmInstancesCreator, final EventsHandler eventsHandler,
final ActivityInstanceService activityInstanceService, final UserFilterService userFilterService, final ClassLoaderService classLoaderService,
final ActorMappingService actorMappingService, final ConnectorInstanceService connectorInstanceService,
final ExpressionResolverService expressionResolverService, final ProcessDefinitionService processDefinitionService,
final DataInstanceService dataInstanceService, final OperationService operationService, final WorkService workService,
final ContainerRegistry containerRegistry, final EventInstanceService eventInstanceService, final SCommentService commentService,
final IdentityService identityService, final ParentContainerResolver parentContainerResolver,
final WaitingEventsInterrupter waitingEventsInterrupter, final RefBusinessDataService refBusinessDataService, BPMWorkFactory workFactory,
UserTransactionService userTransactionService, ProcessInstanceInterruptor processInstanceInterruptor) {
super();
this.bpmInstancesCreator = bpmInstancesCreator;
this.eventsHandler = eventsHandler;
this.activityInstanceService = activityInstanceService;
this.userFilterService = userFilterService;
this.classLoaderService = classLoaderService;
this.actorMappingService = actorMappingService;
this.connectorInstanceService = connectorInstanceService;
this.expressionResolverService = expressionResolverService;
this.processDefinitionService = processDefinitionService;
this.dataInstanceService = dataInstanceService;
this.operationService = operationService;
this.workService = workService;
this.containerRegistry = containerRegistry;
this.eventInstanceService = eventInstanceService;
this.commentService = commentService;
this.identityService = identityService;
this.parentContainerResolver = parentContainerResolver;
this.refBusinessDataService = refBusinessDataService;
this.waitingEventsInterrupter = waitingEventsInterrupter;
this.workFactory = workFactory;
this.processInstanceInterruptor = processInstanceInterruptor;
this.userTransactionService = userTransactionService;
}
public void setProcessExecutor(final ProcessExecutor processExecutor) {
this.processExecutor = processExecutor;
}
public DataInstanceContainer getParentContainerType(final SFlowNodeInstance flowNodeInstance) {
DataInstanceContainer parentContainerType;
if (flowNodeInstance.getLogicalGroup(2) <= 0) {
parentContainerType = DataInstanceContainer.PROCESS_INSTANCE;
} else {
parentContainerType = DataInstanceContainer.ACTIVITY_INSTANCE;
}
return parentContainerType;
}
public DataInstanceService getDataInstanceService() {
return dataInstanceService;
}
public void mapDataOutputOfMultiInstance(final SProcessDefinition processDefinition, final SFlowNodeInstance flowNodeInstance)
throws SActivityStateExecutionException {
if (flowNodeInstance instanceof SActivityInstance && !SFlowNodeType.MULTI_INSTANCE_ACTIVITY.equals(flowNodeInstance.getType())) {
final SFlowElementContainerDefinition processContainer = processDefinition.getProcessContainer();
final SActivityDefinition activityDefinition = (SActivityDefinition) processContainer.getFlowNode(flowNodeInstance.getFlowNodeDefinitionId());
if (activityDefinition != null) {// can be null if the activity was added in runtime
try {
final SLoopCharacteristics loopCharacteristics = activityDefinition.getLoopCharacteristics();
if (loopCharacteristics instanceof SMultiInstanceLoopCharacteristics
&& ((SMultiInstanceLoopCharacteristics) loopCharacteristics).getDataOutputItemRef() != null) {
final SMultiInstanceLoopCharacteristics miLoop = (SMultiInstanceLoopCharacteristics) loopCharacteristics;
final SBusinessDataDefinition businessData = processContainer.getBusinessDataDefinition(miLoop.getLoopDataOutputRef());
if (businessData == null) {
mapDataOutputOfMultiInstance(flowNodeInstance, miLoop);
} else {
MapMultiInstanceBusinessDataOutput(flowNodeInstance, miLoop);
}
}
} catch (final SBonitaException sbe) {
throw new SActivityStateExecutionException(sbe);
}
}
}
}
private void MapMultiInstanceBusinessDataOutput(final SFlowNodeInstance flowNodeInstance, final SMultiInstanceLoopCharacteristics miLoop)
throws SRefBusinessDataInstanceNotFoundException, SBonitaReadException, SRefBusinessDataInstanceModificationException {
final SRefBusinessDataInstance outputMIRef = refBusinessDataService.getFlowNodeRefBusinessDataInstance(
miLoop.getDataOutputItemRef(), flowNodeInstance.getId());
final SRefBusinessDataInstance outputMILoopRef = refBusinessDataService.getRefBusinessDataInstance(
miLoop.getLoopDataOutputRef(), flowNodeInstance.getParentProcessInstanceId());
final SMultiRefBusinessDataInstance multiRefBusinessDataInstance = (SMultiRefBusinessDataInstance) outputMILoopRef;
List dataIds = multiRefBusinessDataInstance.getDataIds();
if (dataIds == null) {
dataIds = new ArrayList<>();
}
final Long dataId = ((SFlowNodeSimpleRefBusinessDataInstance) outputMIRef).getDataId();
dataIds.add(dataId);
refBusinessDataService.updateRefBusinessDataInstance(multiRefBusinessDataInstance, dataIds);
}
@SuppressWarnings("unchecked")
public void mapDataOutputOfMultiInstance(final SFlowNodeInstance flowNodeInstance, final SMultiInstanceLoopCharacteristics miLoop)
throws SBonitaException {
final SDataInstance outputData = dataInstanceService.getDataInstance(miLoop.getDataOutputItemRef(), flowNodeInstance.getId(),
DataInstanceContainer.ACTIVITY_INSTANCE.name(), parentContainerResolver);
final SDataInstance loopData = dataInstanceService.getDataInstance(miLoop.getLoopDataOutputRef(), flowNodeInstance.getId(),
DataInstanceContainer.ACTIVITY_INSTANCE.name(), parentContainerResolver);
if (outputData != null && loopData != null) {
final Serializable value = loopData.getValue();
final int index = flowNodeInstance.getLoopCounter();
if (value instanceof List>) {
((List) value).set(index, outputData.getValue());
} else {
throw new SActivityExecutionException("unable to map the ouput of the multi instanciated activity "
+ flowNodeInstance.getName() + " the output loop data named " + loopData.getName() + " is not a list but "
+ loopData.getClassName());
}
final EntityUpdateDescriptor entityUpdateDescriptor = new EntityUpdateDescriptor();
entityUpdateDescriptor.addField("value", value);
dataInstanceService.updateDataInstance(loopData, entityUpdateDescriptor);
}
}
public void mapActors(final SFlowNodeInstance flowNodeInstance, final SFlowElementContainerDefinition processContainer)
throws SActivityStateExecutionException {
if (SFlowNodeType.USER_TASK.equals(flowNodeInstance.getType()) || SFlowNodeType.MANUAL_TASK.equals(flowNodeInstance.getType())) {
try {
final SHumanTaskDefinition humanTaskDefinition = (SHumanTaskDefinition) processContainer
.getFlowNode(flowNodeInstance.getFlowNodeDefinitionId());
if (humanTaskDefinition != null) {
final String actorName = humanTaskDefinition.getActorName();
final long processDefinitionId = flowNodeInstance.getLogicalGroup(0);
final SUserFilterDefinition sUserFilterDefinition = humanTaskDefinition.getSUserFilterDefinition();
if (sUserFilterDefinition != null) {
mapUsingUserFilters(flowNodeInstance, humanTaskDefinition, actorName, processDefinitionId, sUserFilterDefinition);
} else {
mapUsingActors(flowNodeInstance, actorName, processDefinitionId);
}
}
} catch (final SActivityStateExecutionException e) {
throw e;
} catch (final Exception e) {
throw new SActivityStateExecutionException(e);
}
}
}
private void mapUsingActors(final SFlowNodeInstance flowNodeInstance, final String actorName, final long processDefinitionId)
throws SActorNotFoundException, SActivityCreationException {
final SActor actor = actorMappingService.getActor(actorName, processDefinitionId);
final SPendingActivityMapping mapping = SPendingActivityMapping.builder().activityId(flowNodeInstance.getId()).actorId(actor.getId()).build();
activityInstanceService.addPendingActivityMappings(mapping);
}
void mapUsingUserFilters(final SFlowNodeInstance flowNodeInstance, final SHumanTaskDefinition humanTaskDefinition, final String actorName,
final long processDefinitionId, final SUserFilterDefinition sUserFilterDefinition) throws SClassLoaderException, SUserFilterExecutionException,
SActivityStateExecutionException, SActivityCreationException, SFlowNodeNotFoundException, SFlowNodeReadException,
SActivityModificationException {
final ClassLoader processClassloader = classLoaderService.getLocalClassLoader(ScopeType.PROCESS.name(), processDefinitionId);
final SExpressionContext expressionContext = new SExpressionContext(flowNodeInstance.getId(), DataInstanceContainer.ACTIVITY_INSTANCE.name(),
flowNodeInstance.getLogicalGroup(0));
final FilterResult result = userFilterService.executeFilter(processDefinitionId, sUserFilterDefinition, sUserFilterDefinition.getInputs(),
processClassloader, expressionContext, actorName);
final List userIds = result.getResult();
if (userIds == null || userIds.isEmpty() || userIds.contains(0L) || userIds.contains(-1L)) {
throw new SActivityStateExecutionException("no user id returned by the user filter " + sUserFilterDefinition + " on activity "
+ humanTaskDefinition.getName());
}
for (final Long userId : new TreeSet<>(userIds)) {
final SPendingActivityMapping mapping = SPendingActivityMapping.builder().activityId(flowNodeInstance.getId()).userId(userId).build();
activityInstanceService.addPendingActivityMappings(mapping);
}
if (userIds.size() == 1 && result.shouldAutoAssignTaskIfSingleResult()) {
final Long userId = userIds.get(0);
activityInstanceService.assignHumanTask(flowNodeInstance.getId(), userId);
//system comment is added after the evaluation of the display name
}
}
public void registerWaitingEvent(final SProcessDefinition processDefinition, final SFlowNodeInstance flowNodeInstance)
throws SActivityStateExecutionException {
// handle catch event
if (flowNodeInstance instanceof SIntermediateCatchEventInstance) {
final SCatchEventInstance intermediateCatchEventInstance = (SCatchEventInstance) flowNodeInstance;
// handleEventTriggerInstances(processDefinition, intermediateCatchEventInstance);
final SFlowElementContainerDefinition processContainer = processDefinition.getProcessContainer();
final SIntermediateCatchEventDefinition intermediateCatchEventDefinition = (SIntermediateCatchEventDefinition) processContainer
.getFlowNode(intermediateCatchEventInstance.getFlowNodeDefinitionId());
try {
eventsHandler.handleCatchEvent(processDefinition, intermediateCatchEventDefinition, intermediateCatchEventInstance);
} catch (final SBonitaException e) {
throw new SActivityStateExecutionException("unable to handle catch event " + flowNodeInstance, e);
}
} else if (flowNodeInstance instanceof SReceiveTaskInstance) {
final SReceiveTaskInstance receiveTaskInstance = (SReceiveTaskInstance) flowNodeInstance;
final SFlowElementContainerDefinition processContainer = processDefinition.getProcessContainer();
final SReceiveTaskDefinition receiveTaskIDefinition = (SReceiveTaskDefinition) processContainer.getFlowNode(receiveTaskInstance
.getFlowNodeDefinitionId());
try {
eventsHandler.handleCatchMessage(processDefinition, receiveTaskIDefinition, receiveTaskInstance);
} catch (final SBonitaException e) {
throw new SActivityStateExecutionException("unable to handle catch event " + flowNodeInstance, e);
}
}
}
public void handleBoundaryEvent(final SProcessDefinition processDefinition, final SBoundaryEventInstance boundaryInstance)
throws SActivityStateExecutionException {
final long activityInstanceId = boundaryInstance.getActivityInstanceId();
// FIXME: add activity name in SBoundaryEventInstance to avoid the getActivityInstance below
try {
final SActivityInstance activityInstance = activityInstanceService.getActivityInstance(activityInstanceId);
final SActivityDefinition activityDefinition = (SActivityDefinition) processDefinition.getProcessContainer().getFlowNode(
activityInstance.getFlowNodeDefinitionId());
final SBoundaryEventDefinition boundaryEventDefinition = activityDefinition.getBoundaryEventDefinition(boundaryInstance.getName());
eventsHandler.handleCatchEvent(processDefinition, boundaryEventDefinition, boundaryInstance);
} catch (final SBonitaException e) {
throw new SActivityStateExecutionException("unable to handle catch event " + boundaryInstance, e);
}
}
public void createData(final SProcessDefinition processDefinition, final SFlowNodeInstance flowNodeInstance) throws SActivityStateExecutionException {
if (flowNodeInstance instanceof SActivityInstance) {
bpmInstancesCreator.createDataInstances(processDefinition, flowNodeInstance);
}
}
public void handleCallActivity(final SProcessDefinition processDefinition, final SFlowNodeInstance flowNodeInstance)
throws SActivityStateExecutionException {
if (isCallActivity(flowNodeInstance)) {
final SFlowElementContainerDefinition processContainer = processDefinition.getProcessContainer();
try {
final SCallActivityDefinition callActivity = (SCallActivityDefinition) processContainer.getFlowNode(flowNodeInstance.getFlowNodeDefinitionId());
if (callActivity == null) {
final StringBuilder stb = new StringBuilder("unable to find call activity definition with name '");
stb.append(flowNodeInstance.getName());
stb.append("' in process definition '");
stb.append(processDefinition.getId());
stb.append("'");
throw new SActivityStateExecutionException(stb.toString());
}
final SExpressionContext expressionContext = new SExpressionContext(flowNodeInstance.getId(), DataInstanceContainer.ACTIVITY_INSTANCE.name(),
processDefinition.getId());
final String callableElement = (String) expressionResolverService.evaluate(callActivity.getCallableElement(), expressionContext);
String callableElementVersion = null;
if (callActivity.getCallableElementVersion() != null) {
callableElementVersion = (String) expressionResolverService.evaluate(callActivity.getCallableElementVersion(), expressionContext);
}
final long targetProcessDefinitionId = getTargetProcessDefinitionId(callableElement, callableElementVersion);
SProcessInstance sProcessInstance = instantiateProcess(processDefinition, callActivity, flowNodeInstance, targetProcessDefinitionId);
final SCallActivityInstance callActivityInstance = (SCallActivityInstance) flowNodeInstance;
// update token count
if (sProcessInstance.getStateId() != ProcessInstanceState.COMPLETED.getId()) {
activityInstanceService.setTokenCount(callActivityInstance, callActivityInstance.getTokenCount() + 1);
} else {
// This need to be done "later" we register a work to execute this call activity because it is in fact finish
// we can't do it right now because its state is not yet changed and the work would fail.
userTransactionService.registerBonitaSynchronization(new BonitaTransactionSynchronization() {
@Override
public void beforeCommit() {
//the called process is finished, next step is stable so we trigger execution of this flownode
try {
workService.registerWork(workFactory.createExecuteFlowNodeWorkDescriptor(flowNodeInstance));
} catch (SWorkRegisterException e) {
throw new BonitaRuntimeException(e);
}
}
@Override
public void afterCompletion(TransactionState txState) {
}
});
}
} catch (final SBonitaException e) {
throw new SActivityStateExecutionException(e);
}
}
}
private long getTargetProcessDefinitionId(final String callableElement, final String callableElementVersion) throws SBonitaReadException,
SProcessDefinitionNotFoundException {
if (callableElementVersion != null) {
return processDefinitionService.getProcessDefinitionId(callableElement, callableElementVersion);
}
return processDefinitionService.getLatestProcessDefinitionId(callableElement);
}
private boolean isCallActivity(final SFlowNodeInstance flowNodeInstance) {
return SFlowNodeType.CALL_ACTIVITY.equals(flowNodeInstance.getType());
}
protected SProcessInstance instantiateProcess(final SProcessDefinition callerProcessDefinition, final SCallActivityDefinition callActivityDefinition,
final SFlowNodeInstance callActivityInstance, final long targetProcessDefinitionId) throws SProcessInstanceCreationException,
SContractViolationException, SExpressionException {
final long callerProcessDefinitionId = callerProcessDefinition.getId();
final long callerId = callActivityInstance.getId();
final List operationList = callActivityDefinition.getDataInputOperations();
final SExpressionContext context = new SExpressionContext(callerId, DataInstanceContainer.ACTIVITY_INSTANCE.name(), callerProcessDefinitionId);
final Map processInputs = getEvaluatedInputExpressions(callActivityDefinition.getProcessStartContractInputs(), context);
return processExecutor
.start(targetProcessDefinitionId, -1, 0, 0, context, operationList, callerId, -1, processInputs);
}
protected Map getEvaluatedInputExpressions(Map contractInputs, SExpressionContext context)
throws SExpressionTypeUnknownException, SExpressionDependencyMissingException, SExpressionEvaluationException, SInvalidExpressionException {
List expressions = new ArrayList<>(contractInputs.size());
expressions.addAll(contractInputs.values());
final List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy