
org.ow2.bonita.runtime.InternalInstance Maven / Gradle / Ivy
package org.ow2.bonita.runtime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.ow2.bonita.definition.InternalProcess;
import org.ow2.bonita.facade.runtime.InstanceState;
import org.ow2.bonita.facade.uuid.ProcessDefinitionUUID;
import org.ow2.bonita.facade.uuid.ProcessInstanceUUID;
import org.ow2.bonita.pvm.Execution;
import org.ow2.bonita.pvm.model.Transition;
import org.ow2.bonita.services.Repository;
import org.ow2.bonita.services.handlers.FinishedInstanceHandler;
import org.ow2.bonita.util.EnvTool;
import org.ow2.bonita.util.Misc;
public class InternalInstance {
protected InstanceState instanceState;
//processInstanceLevel
protected ProcessInstanceUUID uuid;
protected long dbid;
protected ProcessDefinitionUUID processUUID;
protected InternalExecution rootExecution;
protected InternalExecution executionToSignal;
protected Set childInstances;
protected InternalInstance parentInstance;
protected Map transitionStates = new HashMap();
public enum TransitionState {
/**
* Transition is ready to be taken
*/
READY,
/**
* An execution has taken this transition.
* However, the destination node has not been executed
* (e.g. node execution is asynchronous)
*/
TAKEN,
/**
* An execution has taken this transition
* and the destination node has been executed.
*/
ARRIVED,
/**
* This transition cannot be taken.
* This has been aborted by the system (e.g. by a join XOR)
*/
ABORTED
}
protected InternalInstance() { }
public InternalInstance(final InternalProcess process) {
this.processUUID = process.getUUID();
final long instanceNb = EnvTool.getRepository().getNextProcessInstanceNb(processUUID);
this.uuid = new ProcessInstanceUUID(processUUID, new Long(instanceNb).toString());
this.rootExecution = new InternalExecution();
this.rootExecution.instance = this;
// TODO: process is set in startExecution too, see how we can remove this.
// (process is needed to assign instance name from the instance repository)
this.rootExecution.setProcessDefinition(process);
final Repository repository = EnvTool.getRepository();
repository.storeInstance(this);
this.rootExecution.setName(this.uuid.toString());
}
public void setInstanceState(final InstanceState state) {
this.instanceState = state;
}
public boolean isInstanceState(final InstanceState state) {
return this.instanceState.equals(state);
}
public TransitionState getTransitionState(final Transition transition) {
if (!transitionStates.containsKey(transition.getDbid())) {
transitionStates.put(transition.getDbid(), TransitionState.READY.toString());
}
return TransitionState.valueOf(transitionStates.get(transition.getDbid()));
}
public void setTransitionState(final Transition transition, final TransitionState state) {
transitionStates.put(transition.getDbid(), state.toString());
}
public InternalExecution getRootExecution() {
return this.rootExecution;
}
public InstanceState getInstanceState() {
return this.instanceState;
}
public ProcessInstanceUUID getUUID() {
return this.uuid;
}
public long getDbid() {
return this.dbid;
}
public ProcessDefinitionUUID getProcessDefinitionUUID() {
return this.processUUID;
}
/**
* @param execution
*/
public void setExecutionToSignal(final InternalExecution execution) {
this.executionToSignal = execution;
if (execution != null) {
// executionToSignal is set to null when the subflow is ended.
// not setting it to null can create a bug, because the executionTosignal
// is removed from the db, but still referenced in the subflow instance.
//
// When executionToSignal is set to null,
// the parent process instance has to be kept.
// (to delete the subflow instance with the main instance)
this.parentInstance = execution.getInstance();
this.parentInstance.addChildInstance(this);
}
}
public InternalExecution getExecutionToSignal() {
return this.executionToSignal;
}
private void addChildInstance(final InternalInstance instance) {
if (this.childInstances == null) {
this.childInstances = new HashSet();
}
this.childInstances.add(instance);
}
@Override
public String toString() {
String value = "Instance " + this.uuid + "(state:" + this.instanceState;
if (this.parentInstance != null) {
value += ", child of " + this.parentInstance;
}
value += ")";
return value;
}
public Set getChildInstances() {
if (this.childInstances == null) {
return null;
}
return Collections.unmodifiableSet(this.childInstances);
}
public InternalInstance getParentInstance() {
return this.parentInstance;
}
public List getExecOnNode(final String nodeName) {
return this.getExecOnNode(this.getRootExecution(), nodeName);
}
private List getExecOnNode(
final InternalExecution exec,
final String nodeName) {
Misc.checkArgsNotNull(exec, nodeName);
final List res = new ArrayList();
if (exec.getExecutions() == null || exec.getExecutions().isEmpty()) {
if (exec.getNode() != null && exec.getNode().getName().equals(nodeName)) {
res.add(exec);
}
}
if (exec.getExecutions() != null) {
for (final Execution child : exec.getExecutions()) {
res.addAll(this.getExecOnNode((InternalExecution) child, nodeName));
}
}
return res;
}
public void cancel() {
// cancel execution
this.getRootExecution().cancel();
// record cancel
EnvTool.getRecorder().recordInstanceCancelled(this.getUUID(), EnvTool.getUserId());
// execute finished instance handler
if (this.getParentInstance() == null) {
this.finish();
}
}
public void finish() {
final FinishedInstanceHandler handler = EnvTool.getFinishedInstanceHandler();
handler.handleFinishedInstance(this.getUUID());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy