All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.yaoqiang.bpmn.engine.runtime.Execution Maven / Gradle / Ivy

There is a newer version: 2.2.18
Show newest version
package org.yaoqiang.bpmn.engine.runtime;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

import org.yaoqiang.bpmn.engine.operation.ExecutionOperation;
import org.yaoqiang.bpmn.model.elements.core.common.FlowNode;
import org.yaoqiang.bpmn.model.elements.core.common.SequenceFlow;

/**
 * Execution
 * 
 * @author Shi Yaoqiang([email protected])
 */
public class Execution {
	
	private static Logger log = Logger.getLogger(Execution.class.getName());

	protected FlowNode startingFlowNode;

	protected FlowNode flowNode;

	protected SequenceFlow sequenceFlow;

	protected Execution parent;

	protected List executions = new ArrayList();;

	protected boolean isActive = true;

	protected boolean isConcurrent = false;

	protected boolean isEnded = false;

	public Execution() {
	}

	public Execution(FlowNode flowNode) {
		startingFlowNode = flowNode;
		setFlowNode(flowNode);
	}

	public Execution createExecution() {
		Execution execution = newExecution();
		executions.add(execution);
		execution.setParent(this);
		execution.setFlowNode(getFlowNode());
		execution.setSequenceFlow(getSequenceFlow());
		return execution;
	}

	protected Execution newExecution() {
		return new Execution();
	}

	public void start() {
		performOperation(ExecutionOperation.PROCESS_START);
	}

	public void end() {
		isActive = false;
		isEnded = true;
		performOperation(ExecutionOperation.FLOW_NODE_END);
	}

	public void remove() {
		if (parent != null) {
			parent.executions.remove(this);
		}
	}

	public void performOperation(ExecutionOperation executionOperation) {
		log.fine("ExecutionOperation: " + executionOperation.getClass().getSimpleName() + " on " + this);
		executionOperation.execute(this);
	}

	public void executeFlowNode(FlowNode flowNode) {
		setFlowNode(flowNode);
		performOperation(ExecutionOperation.FLOW_NODE_START);
	}

	public void takeAll(List sequenceFlows, List recyclableExecutions) {
		sequenceFlows = new ArrayList(sequenceFlows);
		recyclableExecutions = (recyclableExecutions != null ? new ArrayList(recyclableExecutions) : new ArrayList());

		Execution concurrentRoot = (isConcurrent ? getParent() : this);
		List concurrentActiveExecutions = new ArrayList();
		for (Execution execution : concurrentRoot.getExecutions()) {
			if (execution.isActive()) {
				concurrentActiveExecutions.add(execution);
			}
		}

		if ((sequenceFlows.size() == 1) && (concurrentActiveExecutions.isEmpty())) {

			for (Execution prunedExecution : recyclableExecutions) {
				if (!prunedExecution.isEnded()) {
					prunedExecution.remove();
				}
			}

			concurrentRoot.setActive(true);
			concurrentRoot.setFlowNode(flowNode);
			concurrentRoot.setConcurrent(false);
			concurrentRoot.take(sequenceFlows.get(0));

		} else {

			Set outgoingExecutions = new HashSet();

			recyclableExecutions.remove(concurrentRoot);

			while (!sequenceFlows.isEmpty()) {
				SequenceFlow outgoingSequenceFlow = sequenceFlows.remove(0);

				Execution outgoingExecution = null;
				if (recyclableExecutions.isEmpty()) {
					outgoingExecution = concurrentRoot.createExecution();
				} else {
					outgoingExecution = recyclableExecutions.remove(0);
				}

				outgoingExecution.setActive(true);
				outgoingExecution.setConcurrent(true);
				outgoingExecution.setSequenceFlow(outgoingSequenceFlow);
				outgoingExecutions.add(outgoingExecution);
			}

			for (Execution prunedExecution : recyclableExecutions) {
				prunedExecution.end();
			}

			for (Execution outgoingExecution : outgoingExecutions) {
				outgoingExecution.take();
			}
		}
	}

	public void take(SequenceFlow sequenceFlow) {
		setSequenceFlow(sequenceFlow);
		performOperation(ExecutionOperation.SEQUENCE_FLOW_DESTROY_SCOPE);
	}

	public void take() {
		take(getSequenceFlow());
	}

	public List findInactiveConcurrentExecutions(FlowNode flowNode) {
		List inactiveConcurrentExecutionsInActivity = new ArrayList();
		List otherConcurrentExecutions = new ArrayList();
		if (isConcurrent()) {
			List concurrentExecutions = getParent().getExecutions();
			for (Execution concurrentExecution : concurrentExecutions) {
				if (concurrentExecution.getFlowNode() == flowNode) {
					inactiveConcurrentExecutionsInActivity.add(concurrentExecution);
				} else {
					otherConcurrentExecutions.add(concurrentExecution);
				}
			}
		} else {
			if (!isActive()) {
				inactiveConcurrentExecutionsInActivity.add(this);
			} else {
				otherConcurrentExecutions.add(this);
			}
		}
		return inactiveConcurrentExecutionsInActivity;
	}

	public FlowNode getStartingFlowNode() {
		return startingFlowNode;
	}

	public void setStartingFlowNode(FlowNode startingFlowNode) {
		this.startingFlowNode = startingFlowNode;
	}

	public void disposeStartingFlowNode() {
		startingFlowNode = null;
	}

	public FlowNode getFlowNode() {
		return flowNode;
	}

	public void setFlowNode(FlowNode flowNode) {
		this.flowNode = flowNode;
	}

	public SequenceFlow getSequenceFlow() {
		return sequenceFlow;
	}

	public void setSequenceFlow(SequenceFlow sequenceFlow) {
		this.sequenceFlow = sequenceFlow;
	}

	public Execution getParent() {
		return parent;
	}

	public void setParent(Execution parent) {
		this.parent = parent;
	}

	public List getExecutions() {
		return executions;
	}

	public boolean isProcessInstance() {
		return parent == null;
	}

	public void inactivate() {
		this.isActive = false;
	}

	public boolean isActive() {
		return isActive;
	}

	public void setActive(boolean isActive) {
		this.isActive = isActive;
	}

	public boolean isEnded() {
		return isEnded;
	}

	public void setEnded(boolean isEnded) {
		this.isEnded = isEnded;
	}

	public boolean isConcurrent() {
		return isConcurrent;
	}

	public void setConcurrent(boolean isConcurrent) {
		this.isConcurrent = isConcurrent;
	}

	public String toString() {
		if (isProcessInstance()) {
			return "ProcessInstance[" + getToStringIdentity() + "]";
		} else {
			return (isConcurrent ? "Concurrent" : "") + "Execution[" + getToStringIdentity() + "]";
		}
	}

	protected String getToStringIdentity() {
		return Integer.toString(System.identityHashCode(this));
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy