org.activiti.engine.impl.bpmn.helper.ScopeUtil Maven / Gradle / Ivy
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.activiti.engine.impl.bpmn.helper;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.persistence.entity.*;
import org.activiti.engine.impl.util.CollectionUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
*/
public class ScopeUtil {
/**
* we create a separate execution for each compensation handler invocation.
*/
public static void throwCompensationEvent(List eventSubscriptions, DelegateExecution execution, boolean async) {
ExecutionEntityManager executionEntityManager = Context.getCommandContext().getExecutionEntityManager();
// first spawn the compensating executions
for (EventSubscriptionEntity eventSubscription : eventSubscriptions) {
ExecutionEntity compensatingExecution = null;
// check whether compensating execution is already created (which is the case when compensating an embedded subprocess,
// where the compensating execution is created when leaving the subprocess and holds snapshot data).
if (eventSubscription.getConfiguration() != null) {
compensatingExecution = executionEntityManager.findById(eventSubscription.getConfiguration());
compensatingExecution.setParent(compensatingExecution.getProcessInstance());
compensatingExecution.setEventScope(false);
} else {
compensatingExecution = executionEntityManager.createChildExecution((ExecutionEntity) execution);
eventSubscription.setConfiguration(compensatingExecution.getId());
}
}
// signal compensation events in reverse order of their 'created' timestamp
Collections.sort(eventSubscriptions, new Comparator() {
public int compare(EventSubscriptionEntity o1, EventSubscriptionEntity o2) {
return o2.getCreated().compareTo(o1.getCreated());
}
});
for (CompensateEventSubscriptionEntity compensateEventSubscriptionEntity : eventSubscriptions) {
Context.getCommandContext().getEventSubscriptionEntityManager().eventReceived(compensateEventSubscriptionEntity, null, async);
}
}
/**
* Creates a new event scope execution and moves existing event subscriptions to this new execution
*/
public static void createCopyOfSubProcessExecutionForCompensation(ExecutionEntity subProcessExecution) {
EventSubscriptionEntityManager eventSubscriptionEntityManager = Context.getCommandContext().getEventSubscriptionEntityManager();
List eventSubscriptions = eventSubscriptionEntityManager.findEventSubscriptionsByExecutionAndType(subProcessExecution.getId(), "compensate");
List compensateEventSubscriptions = new ArrayList();
for (EventSubscriptionEntity event : eventSubscriptions) {
if (event instanceof CompensateEventSubscriptionEntity) {
compensateEventSubscriptions.add((CompensateEventSubscriptionEntity) event);
}
}
if (CollectionUtil.isNotEmpty(compensateEventSubscriptions)) {
ExecutionEntity processInstanceExecutionEntity = subProcessExecution.getProcessInstance();
ExecutionEntity eventScopeExecution = Context.getCommandContext().getExecutionEntityManager().createChildExecution(processInstanceExecutionEntity);
eventScopeExecution.setActive(false);
eventScopeExecution.setEventScope(true);
eventScopeExecution.setCurrentFlowElement(subProcessExecution.getCurrentFlowElement());
// copy local variables to eventScopeExecution by value. This way,
// the eventScopeExecution references a 'snapshot' of the local variables
new SubProcessVariableSnapshotter().setVariablesSnapshots(subProcessExecution, eventScopeExecution);
// set event subscriptions to the event scope execution:
for (CompensateEventSubscriptionEntity eventSubscriptionEntity : compensateEventSubscriptions) {
eventSubscriptionEntityManager.delete(eventSubscriptionEntity);
CompensateEventSubscriptionEntity newSubscription = eventSubscriptionEntityManager.insertCompensationEvent(
eventScopeExecution, eventSubscriptionEntity.getActivityId());
newSubscription.setConfiguration(eventSubscriptionEntity.getConfiguration());
newSubscription.setCreated(eventSubscriptionEntity.getCreated());
}
CompensateEventSubscriptionEntity eventSubscription = eventSubscriptionEntityManager.insertCompensationEvent(
processInstanceExecutionEntity, eventScopeExecution.getCurrentFlowElement().getId());
eventSubscription.setConfiguration(eventScopeExecution.getId());
}
}
}