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

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