public override void Trigger(IExecutionEntity execution, string triggerName, object triggerData, bool throwError = true) { IExecutionEntity executionEntity = execution; BoundaryEvent boundaryEvent = (BoundaryEvent)execution.CurrentFlowElement; if (boundaryEvent.CancelActivity) { string eventName; if (signal != null) { eventName = signal.Name; } else { eventName = signalEventDefinition.SignalRef; } IEventSubscriptionEntityManager eventSubscriptionEntityManager = Context.CommandContext.EventSubscriptionEntityManager; IList <IEventSubscriptionEntity> eventSubscriptions = executionEntity.EventSubscriptions; foreach (IEventSubscriptionEntity eventSubscription in eventSubscriptions) { if (eventSubscription.EventType == SignalEventSubscriptionEntityFields.EVENT_TYPE && eventSubscription.EventName.Equals(eventName)) { eventSubscriptionEntityManager.Delete(eventSubscription); } } } base.Trigger(executionEntity, triggerName, triggerData, throwError); }
public override BaseFlowNode Build() { var result = new BoundaryEvent(); FeedCatchEvt(result); return(result); }
protected internal override BaseElement ConvertXMLToElement(XMLStreamReader xtr, BpmnModel model) { BoundaryEvent boundaryEvent = new BoundaryEvent(); BpmnXMLUtil.AddXMLLocation(boundaryEvent, xtr); if (!string.IsNullOrWhiteSpace(xtr.GetAttributeValue(BpmnXMLConstants.ATTRIBUTE_BOUNDARY_CANCELACTIVITY))) { string cancelActivity = xtr.GetAttributeValue(BpmnXMLConstants.ATTRIBUTE_BOUNDARY_CANCELACTIVITY); if (BpmnXMLConstants.ATTRIBUTE_VALUE_FALSE.Equals(cancelActivity, StringComparison.CurrentCultureIgnoreCase)) { boundaryEvent.CancelActivity = false; } } boundaryEvent.AttachedToRefId = xtr.GetAttributeValue(BpmnXMLConstants.ATTRIBUTE_BOUNDARY_ATTACHEDTOREF); ParseChildElements(XMLElementName, boundaryEvent, model, xtr); // Explicitly set cancel activity to false for error boundary events if (boundaryEvent.EventDefinitions.Count == 1) { EventDefinition eventDef = boundaryEvent.EventDefinitions[0]; if (eventDef is ErrorEventDefinition) { boundaryEvent.CancelActivity = false; } } return(boundaryEvent); }
public override void Execute(IExecutionEntity execution) { IExecutionEntity executionEntity = execution; BoundaryEvent boundaryEvent = (BoundaryEvent)execution.CurrentFlowElement; Process process = ProcessDefinitionUtil.GetProcess(execution.ProcessDefinitionId); if (process == null) { throw new ActivitiException("Process model (id = " + execution.Id + ") could not be found"); } Activity compensationActivity = null; IList <Association> associations = process.FindAssociationsWithSourceRefRecursive(boundaryEvent.Id); foreach (Association association in associations) { FlowElement targetElement = process.GetFlowElement(association.TargetRef, true); if (targetElement is Activity activity) { if (activity.ForCompensation) { compensationActivity = activity; break; } } } if (compensationActivity == null) { throw new ActivitiException("Compensation activity could not be found (or it is missing 'isForCompensation=\"true\"'"); } // find SubProcess or Process instance execution IExecutionEntity scopeExecution = null; IExecutionEntity parentExecution = executionEntity.Parent; while (scopeExecution == null && parentExecution != null) { if (parentExecution.CurrentFlowElement is SubProcess) { scopeExecution = parentExecution; } else if (parentExecution.ProcessInstanceType) { scopeExecution = parentExecution; } else { parentExecution = parentExecution.Parent; } } if (scopeExecution == null) { throw new ActivitiException("Could not find a scope execution for compensation boundary event " + boundaryEvent.Id); } Context.CommandContext.EventSubscriptionEntityManager.InsertCompensationEvent(scopeExecution, compensationActivity.Id); }
public override object Clone() { var result = new BoundaryEvent(); FeedCatchEvent(result); result.AttachedToRef = AttachedToRef; return(result); }
public override void Trigger(IExecutionEntity execution, string triggerName, object triggerData, bool throwError = true) { BoundaryEvent boundaryEvent = (BoundaryEvent)execution.CurrentFlowElement; ICommandContext commandContext = Context.CommandContext; IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager; IExecutionEntity subProcessExecution = null; // TODO: this can be optimized. A full search in the all executions shouldn't be needed IList <IExecutionEntity> processInstanceExecutions = executionEntityManager.FindChildExecutionsByProcessInstanceId(execution.ProcessInstanceId); foreach (IExecutionEntity childExecution in processInstanceExecutions) { if (childExecution.CurrentFlowElement != null && childExecution.CurrentFlowElement.Id.Equals(boundaryEvent.AttachedToRefId)) { subProcessExecution = childExecution; break; } } if (subProcessExecution == null) { throw new ActivitiException("No execution found for sub process of boundary cancel event " + boundaryEvent.Id); } IEventSubscriptionEntityManager eventSubscriptionEntityManager = commandContext.EventSubscriptionEntityManager; IList <ICompensateEventSubscriptionEntity> eventSubscriptions = eventSubscriptionEntityManager.FindCompensateEventSubscriptionsByExecutionId(subProcessExecution.ParentId); if (eventSubscriptions.Count == 0) { Leave(execution); } else { Leave(execution); string deleteReason = History.DeleteReasonFields.BOUNDARY_EVENT_INTERRUPTING + "(" + boundaryEvent.Id + ")"; // cancel boundary is always sync ScopeUtil.ThrowCompensationEvent(eventSubscriptions, execution, false); executionEntityManager.DeleteExecutionAndRelatedData(subProcessExecution, deleteReason, false); if (subProcessExecution.CurrentFlowElement is Activity activity) { if (activity.LoopCharacteristics != null) { IExecutionEntity miExecution = subProcessExecution.Parent; IList <IExecutionEntity> miChildExecutions = executionEntityManager.FindChildExecutionsByParentExecutionId(miExecution.Id); foreach (IExecutionEntity miChildExecution in miChildExecutions) { if (subProcessExecution.Id.Equals(miChildExecution.Id) == false && activity.Id.Equals(miChildExecution.CurrentActivityId)) { executionEntityManager.DeleteExecutionAndRelatedData(miChildExecution, deleteReason, false); } } } } } }
public virtual BoundaryEventBuilder boundaryEvent(string id) { BoundaryEvent boundaryEvent = createSibling(typeof(BoundaryEvent), id); boundaryEvent.AttachedTo = element; BpmnShape boundaryEventBpmnShape = createBpmnShape(boundaryEvent); BoundaryEventCoordinates = boundaryEventBpmnShape; return(boundaryEvent.builder()); }
protected internal virtual double calculateXCoordinate(Bounds boundaryEventBounds) { BpmnShape attachedToElement = findBpmnShape(element); double x = 0; if (attachedToElement != null) { Bounds attachedToBounds = attachedToElement.Bounds; ICollection <BoundaryEvent> boundaryEvents = element.ParentElement.getChildElementsByType(typeof(BoundaryEvent)); ICollection <BoundaryEvent> attachedBoundaryEvents = new List <BoundaryEvent>(); IEnumerator <BoundaryEvent> iterator = boundaryEvents.GetEnumerator(); while (iterator.MoveNext()) { BoundaryEvent tmp = iterator.Current; if (tmp.AttachedTo.Equals(element)) { attachedBoundaryEvents.Add(tmp); } } double attachedToX = attachedToBounds.getX().Value; double attachedToWidth = attachedToBounds.getWidth().Value; double boundaryWidth = boundaryEventBounds.getWidth().Value; switch (attachedBoundaryEvents.Count) { case 2: { x = attachedToX + attachedToWidth / 2 + boundaryWidth / 2; break; } case 3: { x = attachedToX + attachedToWidth / 2 - 1.5 * boundaryWidth; break; } default: { x = attachedToX + attachedToWidth / 2 - boundaryWidth / 2; break; } } } return(x); }
protected internal override void WriteAdditionalAttributes(BaseElement element, BpmnModel model, XMLStreamWriter xtw) { BoundaryEvent boundaryEvent = (BoundaryEvent)element; if (boundaryEvent.AttachedToRef != null) { WriteDefaultAttribute(BpmnXMLConstants.ATTRIBUTE_BOUNDARY_ATTACHEDTOREF, boundaryEvent.AttachedToRef.Id, xtw); } if (boundaryEvent.EventDefinitions.Count == 1) { EventDefinition eventDef = boundaryEvent.EventDefinitions[0]; if (eventDef is ErrorEventDefinition == false) { WriteDefaultAttribute(BpmnXMLConstants.ATTRIBUTE_BOUNDARY_CANCELACTIVITY, boundaryEvent.CancelActivity ? "true" : "false", xtw); } } }
public override void Trigger(IExecutionEntity execution, string triggerName, object triggerData, bool throwError = true) { BoundaryEvent boundaryEvent = (BoundaryEvent)execution.CurrentFlowElement; if (boundaryEvent.CancelActivity) { IEventSubscriptionEntityManager eventSubscriptionEntityManager = Context.CommandContext.EventSubscriptionEntityManager; IList <IEventSubscriptionEntity> eventSubscriptions = execution.EventSubscriptions; foreach (IEventSubscriptionEntity eventSubscription in eventSubscriptions) { if (eventSubscription.EventType == CompensateEventSubscriptionEntityFields.EVENT_TYPE && eventSubscription.ActivityId.Equals(compensateEventDefinition.ActivityRef)) { eventSubscriptionEntityManager.Delete(eventSubscription); } } } base.Trigger(execution, triggerName, triggerData, throwError); }
private void addServiceTaskCompensationHandler(BpmnModelInstance modelInstance, string boundaryEventId, string compensationHandlerId) { BoundaryEvent boundaryEvent = modelInstance.getModelElementById(boundaryEventId); BaseElement scope = (BaseElement)boundaryEvent.ParentElement; ServiceTask compensationHandler = modelInstance.newInstance(typeof(ServiceTask)); compensationHandler.Id = compensationHandlerId; compensationHandler.ForCompensation = true; //JAVA TO C# CONVERTER WARNING: The .NET Type.FullName property will not always yield results identical to the Java Class.getName method: compensationHandler.CamundaClass = typeof(IncreaseCurrentTimeServiceTask).FullName; scope.addChildElement(compensationHandler); Association association = modelInstance.newInstance(typeof(Association)); association.AssociationDirection = AssociationDirection.One; association.Source = boundaryEvent; association.Target = compensationHandler; scope.addChildElement(association); }
public virtual B compensationStart() { if (element is BoundaryEvent) { BoundaryEvent boundaryEvent = (BoundaryEvent)element; foreach (EventDefinition eventDefinition in boundaryEvent.EventDefinitions) { if (eventDefinition is CompensateEventDefinition) { // if the boundary event contains a compensate event definition then // save the boundary event to later return to it and start a compensation compensateBoundaryEvent = boundaryEvent; compensationStarted = true; return(myself); } } } throw new BpmnModelException("Compensation can only be started on a boundary event with a compensation event definition"); }
protected internal override void ExecuteValidation(BpmnModel bpmnModel, Process process, IList <ValidationError> errors) { IList <BoundaryEvent> boundaryEvents = process.FindFlowElementsOfType <BoundaryEvent>(); // Only one boundary event of type 'cancel' can be attached to the same // element, so we store the count temporarily here Dictionary <string, int> cancelBoundaryEventsCounts = new Dictionary <string, int>(); // Only one boundary event of type 'compensate' can be attached to the // same element, so we store the count temporarily here Dictionary <string, int> compensateBoundaryEventsCounts = new Dictionary <string, int>(); for (int i = 0; i < boundaryEvents.Count; i++) { BoundaryEvent boundaryEvent = boundaryEvents[i]; if (boundaryEvent.EventDefinitions != null && boundaryEvent.EventDefinitions.Count > 0) { EventDefinition eventDefinition = boundaryEvent.EventDefinitions[0]; if (!(eventDefinition is TimerEventDefinition) && !(eventDefinition is ErrorEventDefinition) && !(eventDefinition is SignalEventDefinition) && !(eventDefinition is CancelEventDefinition) && !(eventDefinition is MessageEventDefinition) && !(eventDefinition is CompensateEventDefinition)) { AddError(errors, ProblemsConstants.BOUNDARY_EVENT_INVALID_EVENT_DEFINITION, process, boundaryEvent, ProcessValidatorResource.BOUNDARY_EVENT_INVALID_EVENT_DEFINITION); } if (eventDefinition is CancelEventDefinition) { FlowElement attachedToFlowElement = bpmnModel.GetFlowElement(boundaryEvent.AttachedToRefId); if (!(attachedToFlowElement is Transaction)) { AddError(errors, ProblemsConstants.BOUNDARY_EVENT_CANCEL_ONLY_ON_TRANSACTION, process, boundaryEvent, ProcessValidatorResource.BOUNDARY_EVENT_CANCEL_ONLY_ON_TRANSACTION); } else { if (!cancelBoundaryEventsCounts.ContainsKey(attachedToFlowElement.Id)) { cancelBoundaryEventsCounts[attachedToFlowElement.Id] = 0; } cancelBoundaryEventsCounts[attachedToFlowElement.Id] = cancelBoundaryEventsCounts[attachedToFlowElement.Id] + 1; } } else if (eventDefinition is CompensateEventDefinition) { if (!compensateBoundaryEventsCounts.ContainsKey(boundaryEvent.AttachedToRefId)) { compensateBoundaryEventsCounts[boundaryEvent.AttachedToRefId] = 0; } compensateBoundaryEventsCounts[boundaryEvent.AttachedToRefId] = compensateBoundaryEventsCounts[boundaryEvent.AttachedToRefId] + 1; } else if (eventDefinition is MessageEventDefinition) { // Check if other message boundary events with same message // id for (int j = 0; j < boundaryEvents.Count; j++) { if (j != i) { BoundaryEvent otherBoundaryEvent = boundaryEvents[j]; if (otherBoundaryEvent.AttachedToRefId is object && otherBoundaryEvent.AttachedToRefId.Equals(boundaryEvent.AttachedToRefId)) { if (otherBoundaryEvent.EventDefinitions != null && otherBoundaryEvent.EventDefinitions.Count > 0) { EventDefinition otherEventDefinition = otherBoundaryEvent.EventDefinitions[0]; if (otherEventDefinition is MessageEventDefinition) { MessageEventDefinition currentMessageEventDefinition = (MessageEventDefinition)eventDefinition; MessageEventDefinition otherMessageEventDefinition = (MessageEventDefinition)otherEventDefinition; if (otherMessageEventDefinition.MessageRef is object && otherMessageEventDefinition.MessageRef.Equals(currentMessageEventDefinition.MessageRef)) { AddError(errors, ProblemsConstants.MESSAGE_EVENT_MULTIPLE_ON_BOUNDARY_SAME_MESSAGE_ID, process, boundaryEvent, ProcessValidatorResource.MESSAGE_EVENT_MULTIPLE_ON_BOUNDARY_SAME_MESSAGE_ID); } } } } } } } } else { AddError(errors, ProblemsConstants.BOUNDARY_EVENT_NO_EVENT_DEFINITION, process, boundaryEvent, "Event definition is missing from boundary event"); } } foreach (string elementId in cancelBoundaryEventsCounts.Keys) { if (cancelBoundaryEventsCounts[elementId] > 1) { AddError(errors, ProblemsConstants.BOUNDARY_EVENT_MULTIPLE_CANCEL_ON_TRANSACTION, process, bpmnModel.GetFlowElement(elementId), "multiple boundary events with cancelEventDefinition not supported on same transaction subprocess."); } } foreach (string elementId in compensateBoundaryEventsCounts.Keys) { if (compensateBoundaryEventsCounts[elementId] > 1) { AddError(errors, ProblemsConstants.COMPENSATE_EVENT_MULTIPLE_ON_BOUNDARY, process, bpmnModel.GetFlowElement(elementId), "Multiple boundary events of type 'compensate' is invalid"); } } }
public virtual BoundaryMessageEventActivityBehavior CreateBoundaryMessageEventActivityBehavior(BoundaryEvent boundaryEvent, MessageEventDefinition messageEventDefinition, bool interrupting) { return(new BoundaryMessageEventActivityBehavior(messageEventDefinition, interrupting)); }
public virtual BoundarySignalEventActivityBehavior CreateBoundarySignalEventActivityBehavior(BoundaryEvent boundaryEvent, SignalEventDefinition signalEventDefinition, Signal signal, bool interrupting) { return(new BoundarySignalEventActivityBehavior(signalEventDefinition, signal, interrupting)); }
public virtual BoundaryTimerEventActivityBehavior CreateBoundaryTimerEventActivityBehavior(BoundaryEvent boundaryEvent, TimerEventDefinition timerEventDefinition, bool interrupting) { return(new BoundaryTimerEventActivityBehavior(timerEventDefinition, interrupting)); }
public virtual BoundaryCompensateEventActivityBehavior CreateBoundaryCompensateEventActivityBehavior(BoundaryEvent boundaryEvent, CompensateEventDefinition compensateEventDefinition, bool interrupting) { return(new BoundaryCompensateEventActivityBehavior(compensateEventDefinition, interrupting)); }
// Boundary Events public virtual BoundaryEventActivityBehavior CreateBoundaryEventActivityBehavior(BoundaryEvent boundaryEvent, bool interrupting) { return(new BoundaryEventActivityBehavior(interrupting)); }
protected internal override void WriteAdditionalChildElements(BaseElement element, BpmnModel model, XMLStreamWriter xtw) { BoundaryEvent boundaryEvent = (BoundaryEvent)element; WriteEventDefinitions(boundaryEvent, boundaryEvent.EventDefinitions, model, xtw); }
protected internal AbstractBoundaryEventBuilder(BpmnModelInstance modelInstance, BoundaryEvent element, Type selfType) : base(modelInstance, element, selfType) { }
protected internal virtual void DispatchExecutionTimeOut(IJobEntity timerEntity, IExecutionEntity execution, IList <string> processedElements, ICommandContext commandContext) { FlowElement currentElement = execution.CurrentFlowElement; if (currentElement is BoundaryEvent) { BoundaryEvent boundaryEvent = (BoundaryEvent)execution.CurrentFlowElement; if (boundaryEvent.CancelActivity && boundaryEvent.AttachedToRef != null) { if (!processedElements.Contains(boundaryEvent.Id)) { processedElements.Add(boundaryEvent.Id); IExecutionEntity parentExecution = execution.Parent; DispatchExecutionTimeOut(timerEntity, parentExecution, processedElements, commandContext); } } } else { // flow nodes if (execution.CurrentFlowElement is FlowNode) { processedElements.Add(execution.CurrentActivityId); DispatchActivityTimeOut(timerEntity, (FlowNode)execution.CurrentFlowElement, execution, commandContext); if (execution.CurrentFlowElement is UserTask && !execution.IsMultiInstanceRoot) { IList <ITaskEntity> tasks = execution.Tasks; if (tasks.Count > 0) { tasks[0].Canceled = true; } } } // subprocesses if (execution.CurrentFlowElement is SubProcess) { foreach (IExecutionEntity subExecution in execution.Executions) { if (!processedElements.Contains(subExecution.CurrentActivityId)) { DispatchExecutionTimeOut(timerEntity, subExecution, processedElements, commandContext); } } // call activities } else if (execution.CurrentFlowElement is CallActivity) { IExecutionEntity subProcessInstance = commandContext.ExecutionEntityManager.FindSubProcessInstanceBySuperExecutionId(execution.Id); if (subProcessInstance != null) { IList <IExecutionEntity> childExecutions = subProcessInstance.Executions; foreach (IExecutionEntity subExecution in childExecutions) { if (!processedElements.Contains(subExecution.CurrentActivityId)) { DispatchExecutionTimeOut(timerEntity, subExecution, processedElements, commandContext); } } } } } }
public override void Execute(IExecutionEntity execution) { IExecutionEntity executionEntity = execution; ICommandContext commandContext = Context.CommandContext; IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager; // find cancel boundary event: IExecutionEntity parentScopeExecution = null; IExecutionEntity currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(executionEntity.ParentId); while (currentlyExaminedExecution != null && parentScopeExecution == null) { if (currentlyExaminedExecution.CurrentFlowElement is SubProcess) { parentScopeExecution = currentlyExaminedExecution; SubProcess subProcess = (SubProcess)currentlyExaminedExecution.CurrentFlowElement; if (subProcess.LoopCharacteristics != null) { IExecutionEntity miExecution = parentScopeExecution.Parent; FlowElement miElement = miExecution.CurrentFlowElement; if (miElement != null && miElement.Id.Equals(subProcess.Id)) { parentScopeExecution = miExecution; } } } else { currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(currentlyExaminedExecution.ParentId); } } if (parentScopeExecution == null) { throw new ActivitiException("No sub process execution found for cancel end event " + executionEntity.CurrentActivityId); } { SubProcess subProcess = (SubProcess)parentScopeExecution.CurrentFlowElement; BoundaryEvent cancelBoundaryEvent = null; if (CollectionUtil.IsNotEmpty(subProcess.BoundaryEvents)) { foreach (BoundaryEvent boundaryEvent in subProcess.BoundaryEvents) { if (CollectionUtil.IsNotEmpty(boundaryEvent.EventDefinitions) && boundaryEvent.EventDefinitions[0] is CancelEventDefinition) { cancelBoundaryEvent = boundaryEvent; break; } } } if (cancelBoundaryEvent == null) { throw new ActivitiException("Could not find cancel boundary event for cancel end event " + executionEntity.CurrentActivityId); } IExecutionEntity newParentScopeExecution = null; currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(parentScopeExecution.ParentId); while (currentlyExaminedExecution != null && newParentScopeExecution == null) { if (currentlyExaminedExecution.IsScope) { newParentScopeExecution = currentlyExaminedExecution; } else { currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(currentlyExaminedExecution.ParentId); } } ScopeUtil.CreateCopyOfSubProcessExecutionForCompensation(parentScopeExecution); if (subProcess.LoopCharacteristics != null) { IList <IExecutionEntity> multiInstanceExecutions = parentScopeExecution.Executions; IList <IExecutionEntity> executionsToDelete = new List <IExecutionEntity>(); foreach (IExecutionEntity multiInstanceExecution in multiInstanceExecutions) { if (!multiInstanceExecution.Id.Equals(parentScopeExecution.Id)) { ScopeUtil.CreateCopyOfSubProcessExecutionForCompensation(multiInstanceExecution); // end all executions in the scope of the transaction executionsToDelete.Add(multiInstanceExecution); DeleteChildExecutions(multiInstanceExecution, executionEntity, commandContext, History.DeleteReasonFields.TRANSACTION_CANCELED); } } foreach (IExecutionEntity executionEntityToDelete in executionsToDelete) { DeleteChildExecutions(executionEntityToDelete, executionEntity, commandContext, History.DeleteReasonFields.TRANSACTION_CANCELED); } } // The current activity is finished (and will not be ended in the deleteChildExecutions) commandContext.HistoryManager.RecordActivityEnd(executionEntity, null); // set new parent for boundary event execution executionEntity.Parent = newParentScopeExecution ?? throw new ActivitiException("Programmatic error: no parent scope execution found for boundary event " + cancelBoundaryEvent.Id); executionEntity.CurrentFlowElement = cancelBoundaryEvent; // end all executions in the scope of the transaction DeleteChildExecutions(parentScopeExecution, executionEntity, commandContext, History.DeleteReasonFields.TRANSACTION_CANCELED); commandContext.HistoryManager.RecordActivityEnd(parentScopeExecution, History.DeleteReasonFields.TRANSACTION_CANCELED); Context.Agenda.PlanTriggerExecutionOperation(executionEntity); } }