use of org.camunda.bpm.engine.impl.pvm.delegate.ActivityBehavior in project camunda-bpm-platform by camunda.
the class PvmAtomicOperationActivityEnd method execute.
public void execute(PvmExecutionImpl execution) {
// restore activity instance id
if (execution.getActivityInstanceId() == null) {
execution.setActivityInstanceId(execution.getParentActivityInstanceId());
}
PvmActivity activity = execution.getActivity();
Map<ScopeImpl, PvmExecutionImpl> activityExecutionMapping = execution.createActivityExecutionMapping();
PvmExecutionImpl propagatingExecution = execution;
if (execution.isScope() && activity.isScope()) {
if (!LegacyBehavior.destroySecondNonScope(execution)) {
execution.destroy();
if (!execution.isConcurrent()) {
execution.remove();
propagatingExecution = execution.getParent();
propagatingExecution.setActivity(execution.getActivity());
}
}
}
propagatingExecution = LegacyBehavior.determinePropagatingExecutionOnEnd(propagatingExecution, activityExecutionMapping);
PvmScope flowScope = activity.getFlowScope();
// 1. flow scope = Process Definition
if (flowScope == activity.getProcessDefinition()) {
// 1.1 concurrent execution => end + tryPrune()
if (propagatingExecution.isConcurrent()) {
propagatingExecution.remove();
propagatingExecution.getParent().tryPruneLastConcurrentChild();
propagatingExecution.getParent().forceUpdate();
} else {
// 1.2 Process End
propagatingExecution.setEnded(true);
if (!propagatingExecution.isPreserveScope()) {
propagatingExecution.performOperation(PROCESS_END);
}
}
} else {
// 2. flowScope != process definition
PvmActivity flowScopeActivity = (PvmActivity) flowScope;
ActivityBehavior activityBehavior = flowScopeActivity.getActivityBehavior();
if (activityBehavior instanceof CompositeActivityBehavior) {
CompositeActivityBehavior compositeActivityBehavior = (CompositeActivityBehavior) activityBehavior;
// 2.1 Concurrent execution => composite behavior.concurrentExecutionEnded()
if (propagatingExecution.isConcurrent() && !LegacyBehavior.isConcurrentScope(propagatingExecution)) {
compositeActivityBehavior.concurrentChildExecutionEnded(propagatingExecution.getParent(), propagatingExecution);
} else {
// 2.2 Scope Execution => composite behavior.complete()
propagatingExecution.setActivity(flowScopeActivity);
compositeActivityBehavior.complete(propagatingExecution);
}
} else {
// activity behavior is not composite => this is unexpected
throw new ProcessEngineException("Expected behavior of composite scope " + activity + " to be a CompositeActivityBehavior but got " + activityBehavior);
}
}
}
use of org.camunda.bpm.engine.impl.pvm.delegate.ActivityBehavior in project camunda-bpm-platform by camunda.
the class PvmAtomicOperationActivityLeave method execute.
public void execute(PvmExecutionImpl execution) {
execution.activityInstanceDone();
ActivityBehavior activityBehavior = getActivityBehavior(execution);
if (activityBehavior instanceof FlowNodeActivityBehavior) {
FlowNodeActivityBehavior behavior = (FlowNodeActivityBehavior) activityBehavior;
ActivityImpl activity = execution.getActivity();
String activityInstanceId = execution.getActivityInstanceId();
if (activityInstanceId != null) {
LOG.debugLeavesActivityInstance(execution, activityInstanceId);
}
try {
behavior.doLeave(execution);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new PvmException("couldn't leave activity <" + activity.getProperty("type") + " id=\"" + activity.getId() + "\" ...>: " + e.getMessage(), e);
}
} else {
throw new PvmException("Behavior of current activity is not an instance of " + FlowNodeActivityBehavior.class.getSimpleName() + ". Execution " + execution);
}
}
use of org.camunda.bpm.engine.impl.pvm.delegate.ActivityBehavior in project camunda-bpm-platform by camunda.
the class ActivityBehaviorUtil method getActivityBehavior.
public static ActivityBehavior getActivityBehavior(PvmExecutionImpl execution) {
String id = execution.getId();
PvmActivity activity = execution.getActivity();
ensureNotNull(PvmException.class, "Execution '" + id + "' has no current activity.", "activity", activity);
ActivityBehavior behavior = activity.getActivityBehavior();
ensureNotNull(PvmException.class, "There is no behavior specified in " + activity + " for execution '" + id + "'.", "behavior", behavior);
return behavior;
}
use of org.camunda.bpm.engine.impl.pvm.delegate.ActivityBehavior in project camunda-bpm-platform by camunda.
the class ServiceTaskDelegateExpressionActivityBehavior method performExecution.
@Override
public void performExecution(final ActivityExecution execution) throws Exception {
Callable<Void> callable = new Callable<Void>() {
@Override
public Void call() throws Exception {
// Note: we can't cache the result of the expression, because the
// execution can change: eg. delegateExpression='${mySpringBeanFactory.randomSpringBean()}'
Object delegate = expression.getValue(execution);
applyFieldDeclaration(fieldDeclarations, delegate);
if (delegate instanceof ActivityBehavior) {
Context.getProcessEngineConfiguration().getDelegateInterceptor().handleInvocation(new ActivityBehaviorInvocation((ActivityBehavior) delegate, execution));
} else if (delegate instanceof JavaDelegate) {
Context.getProcessEngineConfiguration().getDelegateInterceptor().handleInvocation(new JavaDelegateInvocation((JavaDelegate) delegate, execution));
leave(execution);
} else {
throw LOG.resolveDelegateExpressionException(expression, ActivityBehavior.class, JavaDelegate.class);
}
return null;
}
};
executeWithErrorPropagation(execution, callable);
}
use of org.camunda.bpm.engine.impl.pvm.delegate.ActivityBehavior in project camunda-bpm-platform by camunda.
the class BpmnParse method parseBoundaryEvents.
/**
* Parses the boundary events of a certain 'level' (process, subprocess or
* other scope).
*
* Note that the boundary events are not parsed during the parsing of the bpmn
* activities, since the semantics are different (boundaryEvent needs to be
* added as nested activity to the reference activity on PVM level).
*
* @param parentElement
* The 'parent' element that contains the activities (process,
* subprocess).
* @param flowScope
* The {@link ScopeImpl} to which the activities must be added.
*/
public void parseBoundaryEvents(Element parentElement, ScopeImpl flowScope) {
for (Element boundaryEventElement : parentElement.elements("boundaryEvent")) {
// The boundary event is attached to an activity, reference by the
// 'attachedToRef' attribute
String attachedToRef = boundaryEventElement.attribute("attachedToRef");
if (attachedToRef == null || attachedToRef.equals("")) {
addError("AttachedToRef is required when using a timerEventDefinition", boundaryEventElement);
}
// Representation structure-wise is a nested activity in the activity to
// which its attached
String id = boundaryEventElement.attribute("id");
LOG.parsingElement("boundary event", id);
// Depending on the sub-element definition, the correct activityBehavior
// parsing is selected
Element timerEventDefinition = boundaryEventElement.element(TIMER_EVENT_DEFINITION);
Element errorEventDefinition = boundaryEventElement.element(ERROR_EVENT_DEFINITION);
Element signalEventDefinition = boundaryEventElement.element(SIGNAL_EVENT_DEFINITION);
Element cancelEventDefinition = boundaryEventElement.element(CANCEL_EVENT_DEFINITION);
Element compensateEventDefinition = boundaryEventElement.element(COMPENSATE_EVENT_DEFINITION);
Element messageEventDefinition = boundaryEventElement.element(MESSAGE_EVENT_DEFINITION);
Element escalationEventDefinition = boundaryEventElement.element(ESCALATION_EVENT_DEFINITION);
Element conditionalEventDefinition = boundaryEventElement.element(CONDITIONAL_EVENT_DEFINITION);
// create the boundary event activity
ActivityImpl boundaryEventActivity = createActivityOnScope(boundaryEventElement, flowScope);
parseAsynchronousContinuation(boundaryEventElement, boundaryEventActivity);
ActivityImpl attachedActivity = flowScope.findActivityAtLevelOfSubprocess(attachedToRef);
if (attachedActivity == null) {
addError("Invalid reference in boundary event. Make sure that the referenced activity is defined in the same scope as the boundary event", boundaryEventElement);
}
// determine the correct event scope (the scope in which the boundary event catches events)
if (compensateEventDefinition == null) {
ActivityImpl multiInstanceScope = getMultiInstanceScope(attachedActivity);
if (multiInstanceScope != null) {
// if the boundary event is attached to a multi instance activity,
// then the scope of the boundary event is the multi instance body.
boundaryEventActivity.setEventScope(multiInstanceScope);
} else {
attachedActivity.setScope(true);
boundaryEventActivity.setEventScope(attachedActivity);
}
} else {
boundaryEventActivity.setEventScope(attachedActivity);
}
// except escalation, by default is assumed to abort the activity
String cancelActivityAttr = boundaryEventElement.attribute("cancelActivity", TRUE);
boolean isCancelActivity = Boolean.valueOf(cancelActivityAttr);
// determine start behavior
if (isCancelActivity) {
boundaryEventActivity.setActivityStartBehavior(ActivityStartBehavior.CANCEL_EVENT_SCOPE);
} else {
boundaryEventActivity.setActivityStartBehavior(ActivityStartBehavior.CONCURRENT_IN_FLOW_SCOPE);
}
// Catch event behavior is the same for most types
ActivityBehavior behavior = new BoundaryEventActivityBehavior();
if (timerEventDefinition != null) {
parseBoundaryTimerEventDefinition(timerEventDefinition, isCancelActivity, boundaryEventActivity);
} else if (errorEventDefinition != null) {
parseBoundaryErrorEventDefinition(errorEventDefinition, boundaryEventActivity);
} else if (signalEventDefinition != null) {
parseBoundarySignalEventDefinition(signalEventDefinition, isCancelActivity, boundaryEventActivity);
} else if (cancelEventDefinition != null) {
behavior = parseBoundaryCancelEventDefinition(cancelEventDefinition, boundaryEventActivity);
} else if (compensateEventDefinition != null) {
parseBoundaryCompensateEventDefinition(compensateEventDefinition, boundaryEventActivity);
} else if (messageEventDefinition != null) {
parseBoundaryMessageEventDefinition(messageEventDefinition, isCancelActivity, boundaryEventActivity);
} else if (escalationEventDefinition != null) {
if (attachedActivity.isSubProcessScope() || attachedActivity.getActivityBehavior() instanceof CallActivityBehavior) {
parseBoundaryEscalationEventDefinition(escalationEventDefinition, isCancelActivity, boundaryEventActivity);
} else {
addError("An escalation boundary event should only be attached to a subprocess or a call activity", boundaryEventElement);
}
} else if (conditionalEventDefinition != null) {
behavior = parseBoundaryConditionalEventDefinition(conditionalEventDefinition, isCancelActivity, boundaryEventActivity);
} else {
addError("Unsupported boundary event type", boundaryEventElement);
}
ensureNoIoMappingDefined(boundaryEventElement);
for (BpmnParseListener parseListener : parseListeners) {
parseListener.parseBoundaryEvent(boundaryEventElement, flowScope, boundaryEventActivity);
}
boundaryEventActivity.setActivityBehavior(behavior);
parseExecutionListenersOnScope(boundaryEventElement, boundaryEventActivity);
}
}
Aggregations