
org.ow2.bonita.pvm.activity.ActivityExecution Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.ow2.bonita.pvm.activity;
import org.ow2.bonita.env.Environment;
import org.ow2.bonita.pvm.Execution;
import org.ow2.bonita.pvm.client.ClientProcessDefinition;
import org.ow2.bonita.pvm.client.ClientProcessInstance;
import org.ow2.bonita.pvm.model.Node;
import org.ow2.bonita.pvm.model.ObservableElement;
import org.ow2.bonita.pvm.model.OpenExecution;
import org.ow2.bonita.pvm.model.Transition;
import org.ow2.bonita.pvm.processlog.ProcessLog;
import org.ow2.bonita.pvm.session.PvmDbSession;
import org.ow2.bonita.util.BonitaRuntimeException;
/**
* view upon an {@link Execution path of execution} exposed to {@link Activity}
* implementations.
*
* @author Tom Baeyens
*/
public interface ActivityExecution extends OpenExecution {
// wait state behaviour /////////////////////////////////////////////////////
/**
* makes this execution wait in the current node until an external trigger is
* given with one of the {@link #signal()} methods.
*/
void waitForSignal();
// taking a transition //////////////////////////////////////////////////////
/**
* takes the default transition.
*
*
* This method can only be called from inside {@link ExternalActivity}
* implementations and in rare occasions also from outside of the execution
* (from an external client while the process is in a wait state). For
* external clients, it is more normal to use the {@link #signal()} method as
* in that case, it's the current node (hence the process language)that will
* decide how to interpret the signal.
*
*
* @throws BonitaRuntimeException
* in case there is no default transition in the current node or in
* case this method is called from inside an {@link Activity}
*/
void takeDefaultTransition();
/**
* takes the outgoing transition with the given name.
*
*
* This method can only be called from inside {@link ExternalActivity}
* implementations and in rare occasions also from outside of the execution
* (from an external client while the process is in a wait state). For
* external clients, it is more normal to use the {@link #signal(String)}
* method as in that case, it's the current node (hence the process
* language)that will decide how to interpret the signal.
*
*
*
* Transitions will be looked up recursively starting from the
* {@link #getNode() current node} and then up the {@link Node#getParent()
* node-parent-hierarchy}
*
*
* @param transitionName
* is the name of the transition to take. A null value will match the
* first unnamed transition.
*
* @throws BonitaRuntimeException
* in case no such transition is found in {@link #getNode() the
* current node} or in case this method is called from inside an
* {@link Activity}.
*/
void take(String transitionName);
/**
* takes the given outgoing transition.
*
*
* This method can only be called from inside {@link ExternalActivity}
* implementations and in rare occasions also from outside of the execution
* (from an external client while the process is in a wait state). For
* external clients, it is more normal to use the {@link #signal(String)}
* method as in that case, it's the current node (hence the process
* language)that will decide how to interpret the signal.
*
*
*
* CAUTION: It's up to the client to make sure that this transition makes
* sense as there is no check whether the given transition is an outgoing
* transition of the current node. The motivation for that is that in case of
* superstates, that check can become too 'expensive'.
*
*/
void take(Transition transition);
/**
* let's the given execution take the transition.
*
* @throws BonitaRuntimeException
* if the execution is not part of this process instance.
*/
void take(Transition transition, Execution execution);
// execute a child node /////////////////////////////////////////////////////
/**
* executes the given nested node.
*
*
* The nodeName is looked up in the current node's nested nodes.
*
*
*
* This method can only be called from inside {@link ExternalActivity}
* implementations and in rare occasions also from outside of the execution
* (from an external client while the process is in a wait state). For
* external clients, it is more normal to use the {@link #signal(String)}
* method as in that case, it's the current node (hence the process
* language)that will decide how to interpret the signal.
*
*/
void execute(String nodeName);
/**
* executes the given node.
*
*
* This method can only be called from inside {@link ExternalActivity}
* implementations and in rare occasions also from outside of the execution
* (from an external client while the process is in a wait state). For
* external clients, it is more normal to use the {@link #signal(String)}
* method as in that case, it's the current node (hence the process
* language)that will decide how to interpret the signal.
*
*/
void execute(Node node);
// reposition the execution in another node /////////////////////////////////
/** position this execution in the destination node. */
void move(Node destination);
/** position the given execution in the destination node */
void move(Node destination, Execution execution);
// managing the parent-child relation ///////////////////////////////////////
/**
* creates a child execution. See {@link #createExecution(Execution, String)}
* for more information.
*/
Execution createExecution();
/**
* creates a child execution with the given name. See
* {@link #createExecution(Execution, String)} for more information.
*/
Execution createExecution(String name);
/**
* creates a new child execution under the given parent. See
* {@link #createExecution(Execution, String)} for more information.
*
* @throws BonitaRuntimeException
* if the given parent is not in this execution's process instance.
*/
Execution createExecution(Execution parent);
/**
* creates a new child execution under the given parent with the given name.
* Only leaf executions can be active. So creating the first child execution
* will {@link Execution#STATE_INACTIVE inactivate} the parent execution
* automatically.
*
* @throws BonitaRuntimeException
* if the given parent is not in this execution's process instance.
*/
Execution createExecution(String name, Execution parent);
/**
* removes the child execution from this execution. Removing the last child
* execution of a parent will cause the parent's state to become
* {@link Execution#STATE_ACTIVE active}.
*/
void removeExecution(Execution child);
/**
* removes the child execution from the given parent. Removing the last child
* execution of a parent will cause the parent's state to become
* {@link Execution#STATE_ACTIVE active}.
*/
void removeExecution(Execution child, Execution parent);
// create sub process execution /////////////////////////////////////////////
/**
* creates a sub process related to this path of execution. ProcessDefinitions
* can be obtained from the {@link PvmDbSession} in the {@link Environment}.
*/
ClientProcessInstance createSubProcessInstance(
ClientProcessDefinition processDefinition);
/**
* creates a sub process related to this path of execution. ProcessDefinitions
* can be obtained from the {@link PvmDbSession} in the {@link Environment}.
*/
ClientProcessInstance createSubProcessInstance(
ClientProcessDefinition processDefinition, String key);
/**
* creates and begins a sub process related to this path of execution.
* ProcessDefinitions can be obtained from the {@link PvmDbSession} in the
* {@link Environment}.
*/
ClientProcessInstance beginSubProcessInstance(
ClientProcessDefinition processDefinition);
/**
* creates and begins a sub process related to this path of execution.
* ProcessDefinitions can be obtained from the {@link PvmDbSession} in the
* {@link Environment}.
*/
ClientProcessInstance beginSubProcessInstance(
ClientProcessDefinition processDefinition, String key);
// ending an execution //////////////////////////////////////////////////////
/**
* ends this execution and all of its child executions.
*
*
* The execution will be removed from it's parent. Potentially this can cause
* a parent execution to start executing in case this is the last concurrent
* execution for which the parent is waiting.
*
*
*
* This method should not be called in {@link Activity}s. It can be called
* from outside the process execution and in {@link ExternalActivity}s.
*
*/
void end();
/**
* ends this execution and assigns the state {@link #STATE_CANCELLED}.
*
* @see #end(String)
*/
void cancel();
/**
* ends this execution and all it's child executions with a user defined
* status.
*
*
* It is not recommended to use any of {@link #STATE_ACTIVE the defined
* statuses} as that may case unpredictable side effects.
*
*
*
* The execution will be removed from it's parent.
*
*/
void end(String state);
// firing events ////////////////////////////////////////////////////////////
/**
* fires the event on the given eventSource and then propagates the event up
* to the eventSource's parent chain. All the actions will see the given
* eventSource in {@link #getEventSource()}, event if the events are
* registered to parent's of the given eventSource.
*/
void fire(String eventName, ObservableElement eventSource);
// logs /////////////////////////////////////////////////////////////////////
/** adds a log to this execution. */
void addLog(ProcessLog processLog);
// extra state information methods //////////////////////////////////////////
/**
* the current transition indicating the position in the process definition
* graph. Can be null in case this execution is not taking a transition.
*/
Transition getTransition();
// extensions //////////////////////////////////////////////////////////////
/**
* way to access process language extensions in the execution without having
* to cast. Casting can be problematic for persistence.
*/
T getExtension(Class extensionClass);
/**
* setter for the priority. The default priority is 0, which means NORMAL.
* Other recognized named priorities are HIGHEST (2), HIGH (1), LOW (-1) and
* LOWEST (-2). For the rest, the user can set any other priority integer
* value, but then, the UI will have to display it as an integer and not the
* named value.
*/
void setPriority(int priority);
// previous methods /////////////////////////////////////////////////////////
// TODO evaluate the previous methods
// these methods are kind of performance optimisations. a sequence and
// some other specific control flow implementations can be optimised if they
// have access to the previous node or transition.
// Those activities could also be implemented by letting the activities store
// the contextual information in process variables or some other execution
// context. But with the previous properties as done now, these control flow
// nodes can be implemented without storing an extra record. It's only a
// property
// that is only updated when the node configuration indicates that it's
// needed.
// (see also Node.isPreviousNeeded())
/**
* returns the previously executed node only if
* {@link Node#isPreviousNeeded()} is set to true.
*/
Node getPreviousNode();
/**
* returns the previously taken transition only if
* {@link Node#isPreviousNeeded()} is set to true.
*/
Transition getPreviousTransition();
}