
org.ow2.bonita.definition.activity.AbstractActivity Maven / Gradle / Ivy
/**
* Copyright (C) 2007 Bull S. A. S.
* Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois
* This library 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
* version 2.1 of the License.
* This library 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
* program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301, USA.
**/
package org.ow2.bonita.definition.activity;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.ow2.bonita.definition.ActivityType;
import org.ow2.bonita.definition.ClassInfo;
import org.ow2.bonita.definition.JavaHook;
import org.ow2.bonita.definition.MultiInstantiator;
import org.ow2.bonita.definition.MultiInstantiatorDescriptor;
import org.ow2.bonita.definition.Performer;
import org.ow2.bonita.facade.exception.BonitaWrapperException;
import org.ow2.bonita.facade.exception.MultiInstantiatorInvocationException;
import org.ow2.bonita.facade.runtime.ActivityState;
import org.ow2.bonita.facade.runtime.InstanceState;
import org.ow2.bonita.pvm.Execution;
import org.ow2.bonita.pvm.activity.ActivityExecution;
import org.ow2.bonita.pvm.activity.ExternalActivity;
import org.ow2.bonita.pvm.internal.env.Authentication;
import org.ow2.bonita.pvm.internal.model.NodeImpl;
import org.ow2.bonita.pvm.internal.model.TransitionImpl;
import org.ow2.bonita.pvm.internal.model.VariableDefinitionImpl;
import org.ow2.bonita.pvm.model.Condition;
import org.ow2.bonita.pvm.model.Node;
import org.ow2.bonita.pvm.model.OpenExecution;
import org.ow2.bonita.pvm.model.Transition;
import org.ow2.bonita.runtime.ClassDataLoader;
import org.ow2.bonita.runtime.TransitionStatus;
import org.ow2.bonita.runtime.XpdlExecution;
import org.ow2.bonita.runtime.XpdlInstance;
import org.ow2.bonita.runtime.TransitionStatus.TransitionState;
import org.ow2.bonita.services.Recorder;
import org.ow2.bonita.services.info.ActivityInstanceCurrentInfo;
import org.ow2.bonita.services.util.ServiceEnvTool;
import org.ow2.bonita.util.BonitaConstants;
import org.ow2.bonita.util.BonitaRuntimeException;
import org.ow2.bonita.util.EngineEnvTool;
import org.ow2.bonita.util.Misc;
/**
* @author Marc Blachon, Guillaume Porcher, Charles Souillard, Miguel Valdes, Pierre Vigneras, Pascal Verdage
*/
/**
* Activity life cycle:
* 1- when an instance is created, activity state is {@link ActivityState#INITIAL}
* 2- when the execution arrives on the node, the activity becomes {@link ActivityState#READY}
* the activity state is recorded (before start)
* 3- if the activity is Manual, a task is created.
* - when the start task is started, the activity state is recorded (after start).
* 4- the activity becomes {@link ActivityState#EXECUTING}. The business logic is executed.
* - the activity state is recorded (before stopped)
* 5- if the activity is Manual, wait for the task to finish. (TODO: change the activity state ?)
* - when the task is finished, the activity state is recorded (after stopped).
* 6- the activity becomes {@link ActivityState#FINISHED}.
*/
public abstract class AbstractActivity implements ExternalActivity {
/**
*
*/
private static final long serialVersionUID = -2731157748250833266L;
public static enum SplitType {
AND, XOR
}
public static enum JoinType {
AND, XOR
}
/** LOG */
private static final Logger LOG = Logger.getLogger(AbstractActivity.class.getName());
protected long dbid;
protected String activityId;
protected SplitType splitType;
protected JoinType joinType;
protected ActivityType activityType;
protected List variableDefinitions;
protected Performer performer;
protected Set deadlines;
protected List javaHooks;
// multi instantiation
protected ClassInfo multiInstantiationClass;
protected String multiInstantiationVariable;
// iterations
protected List iterationDescriptors;
public static final String BODY_FINISHED = "bodyFinished";
public static final String ACT_INSTANCE_FINISHED = "instFinished";
protected AbstractActivity() {
}
protected AbstractActivity(final String activityName, final JoinType joinType,
final SplitType splitType,
final ActivityType activityType,
final Performer performer) {
Misc.checkArgsNotNull(activityType);
this.activityId = activityName;
this.joinType = joinType;
this.splitType = splitType;
this.activityType = activityType;
this.performer = performer;
if (performer != null) {
if (!ActivityType.task.equals(activityType)) {
throw new BonitaRuntimeException("Activity is automatic and a performer is specified: incorrect.");
}
} else {
if (ActivityType.task.equals(activityType)) {
throw new BonitaRuntimeException("startMode or finishMode is Manual and no performer is specified: incorrect.");
}
}
}
public void execute(final ActivityExecution execution) {
XpdlExecution xpdlExecution = (XpdlExecution) execution;
if (xpdlExecution.getNode().isExecutionAsync()) {
Authentication.setUserId(BonitaConstants.SYSTEM_USER);
}
// If instance is ended, don't execute next node.
if (xpdlExecution.getXpdlInstance().getInstanceState().equals(InstanceState.FINISHED)) {
if (AbstractActivity.LOG.isLoggable(Level.FINE)) {
AbstractActivity.LOG.fine("XPDLInstance ended : " + xpdlExecution.getXpdlInstance());
}
xpdlExecution.end();
final XpdlExecution parent = xpdlExecution.getParent();
if (parent != null) {
parent.removeExecution(xpdlExecution);
}
return;
}
// Execute node.
boolean joinOK = true;
joinOK = this.executeJoin(xpdlExecution);
if (joinOK) {
if (AbstractActivity.LOG.isLoggable(Level.FINE)) {
AbstractActivity.LOG.fine("Join for activity " + this + " is OK.");
}
if (this.joinType.equals(JoinType.XOR)) {
AbstractActivity.cancelJoinXORIncomingTransitions(xpdlExecution);
}
if (AbstractActivity.LOG.isLoggable(Level.FINE)) {
AbstractActivity.LOG.fine("Creating a new iteration on activity : " + this);
}
this.createNewIteration(xpdlExecution);
final String nodeName = execution.getNode().getName();
if (AbstractActivity.LOG.isLoggable(Level.FINE)) {
AbstractActivity.LOG.fine("Executing node: " + nodeName + ", class = " + this.getClass().getSimpleName());
}
if (this.multiInstantiationClass != null) {
if (AbstractActivity.LOG.isLoggable(Level.FINE)) {
AbstractActivity.LOG.fine("MultiInstantiation not null on activity " + this);
}
MultiInstantiatorDescriptor actInstDescr = null;
final MultiInstantiator actInstantiator =
ClassDataLoader.getInstance(MultiInstantiator.class,
xpdlExecution.getXpdlInstance().getPackageDefinitionUUID(), this.multiInstantiationClass);
try {
actInstDescr = EngineEnvTool.getHookExecutor()
.executeMultiInstantiator(xpdlExecution, this.activityId, actInstantiator);
if (actInstDescr == null) {
throw new BonitaRuntimeException("MultiInstantiator execution returned null in activity " + this.activityId);
}
} catch (final Exception e) {
throw new BonitaWrapperException(
new MultiInstantiatorInvocationException(this.multiInstantiationClass.toString(), e)
);
}
xpdlExecution.setWaitingForActivityInstanceNb(actInstDescr.getJoinNumber());
int childId = 0;
for (final Object value : actInstDescr.getVariableValues()) {
XpdlExecution childExec = this.createChildExecution(xpdlExecution, childId);
childExec = (XpdlExecution) childExec.createScope(xpdlExecution.getNode());
// TODO check if values are compatibles with variable type
childExec.setVariable(this.multiInstantiationVariable, value);
childExec.setActivityInstanceId(Integer.toString(childId));
this.executeActivityInstance(childExec);
childId++;
}
} else {
xpdlExecution = (XpdlExecution) xpdlExecution.createScope(xpdlExecution.getNode());
this.executeActivityInstance(xpdlExecution);
}
} else {
xpdlExecution.end();
final XpdlExecution parent = xpdlExecution.getParent();
if (parent != null) {
parent.removeExecution(xpdlExecution);
}
}
}
/**
* @param execution
*/
private static void cancelJoinXORIncomingTransitions(final XpdlExecution execution) {
final NodeImpl currentNode = execution.getNode();
final XpdlInstance instance = execution.getXpdlInstance();
AbstractActivity.cancelJoinXORIncomingTransitions(instance, currentNode, currentNode.getName());
for (final Transition t : currentNode.getIncomingTransitions()) {
instance.setTransitionState(t, TransitionState.ABORTED);
}
}
private static void cancelJoinXORIncomingTransitions(final XpdlInstance instance, final NodeImpl currentNode, final String initialNode) {
final List incomingTransitions = currentNode.getIncomingTransitions();
final String currentNodeName = currentNode.getName();
if (AbstractActivity.LOG.isLoggable(Level.FINE)) {
AbstractActivity.LOG.fine("Canceling other branches of the join XOR : " + currentNodeName);
}
for (final Transition incomingTransition : incomingTransitions) {
final NodeImpl sourceNode = (NodeImpl) incomingTransition.getSource();
final String sourceNodeName = sourceNode.getName();
if (!sourceNodeName.equals(initialNode)
&& instance.getTransitionStatus(incomingTransition).getState().equals(TransitionState.READY)) {
// disable transition
instance.setTransitionState(incomingTransition, TransitionState.ABORTED);
// check if source node is still enabled
// it is still enabled if it has an enabled outgoing transition (in the same cycle if in a cycle)
boolean enable = false;
for (final Transition tr : sourceNode.getOutgoingTransitions()) {
if (instance.getTransitionStatus(tr).getState().equals(TransitionState.READY)) {
final AbstractActivity currentActivity = (AbstractActivity) currentNode.getBehaviour();
final List itDescs = currentActivity.getIterationDescriptors();
if (itDescs != null && !itDescs.isEmpty()) {
for (final IterationDescriptor itDesc : itDescs) {
if (itDesc.containsNode(tr.getDestination())) {
// stay in same cycle => do not disable node
enable = true;
}
}
} else {
// no cycles -> do not disable node
enable = true;
}
}
}
if (!enable) {
// abort sourceNode recursively
if (AbstractActivity.LOG.isLoggable(Level.FINE)) {
AbstractActivity.LOG.fine(sourceNodeName + " has no more outgoing transitions enabled.");
}
final List execToAbortList = instance.getExecOnNode(sourceNodeName);
for (final XpdlExecution execToAbort : execToAbortList) {
if (execToAbort.isActive()) {
execToAbort.abort();
}
}
AbstractActivity.cancelJoinXORIncomingTransitions(instance, sourceNode, initialNode);
}
}
}
}
protected void executeActivityInstance(final XpdlExecution xpdlExecution) {
xpdlExecution.setCurrentActivityInstanceUUID(
ServiceEnvTool.getUUIDGenerator().
getActivityInstanceUUID(xpdlExecution.getXpdlInstance().getUUID(), this.activityId));
final Recorder recorder = ServiceEnvTool.getRecorder();
final XpdlInstance xpdlInstance = xpdlExecution.getXpdlInstance();
final ActivityInstanceCurrentInfo activityInstanceCurrentInfo = new ActivityInstanceCurrentInfo(
xpdlInstance.getPackageDefinitionUUID(),
xpdlInstance.getProcessDefinitionUUID(),
xpdlInstance.getUUID(),
xpdlExecution.getCurrentActivityInstanceUUID(),
this.getActivityType(),
this.getActivityId(),
xpdlExecution.getIterationId(),
xpdlExecution.getActivityInstanceId(),
xpdlExecution.getScopeVariables());
recorder.recordEnterActivity(activityInstanceCurrentInfo);
final boolean canContinue = this.executeBody(xpdlExecution);
if (canContinue) {
this.end(xpdlExecution);
} else {
xpdlExecution.waitForSignal();
}
}
protected void end(final XpdlExecution xpdlExecution) {
final ActivityInstanceCurrentInfo activityInstanceCurrentInfo = new ActivityInstanceCurrentInfo(
xpdlExecution.getXpdlInstance().getPackageDefinitionUUID(),
xpdlExecution.getXpdlInstance().getProcessDefinitionUUID(),
xpdlExecution.getXpdlInstance().getUUID(),
xpdlExecution.getCurrentActivityInstanceUUID(),
this.getActivityType(),
this.getActivityId(),
xpdlExecution.getIterationId(),
xpdlExecution.getActivityInstanceId(),
xpdlExecution.getScopeVariables());
ServiceEnvTool.getRecorder().recordBodyEnded(activityInstanceCurrentInfo);
if (!XpdlExecution.MAIN_INSTANCE_NAME.equals(xpdlExecution.getActivityInstanceId())) {
final XpdlExecution activityInstanceExecution = (XpdlExecution) xpdlExecution.destroyScope(xpdlExecution.getNode());
activityInstanceExecution.end();
final XpdlExecution parent = activityInstanceExecution.getParent();
parent.removeExecution(activityInstanceExecution);
this.signal(parent, AbstractActivity.ACT_INSTANCE_FINISHED, null);
} else {
this.executeSplit(xpdlExecution, true);
}
}
public void signal(final ActivityExecution execution, final String signal, final Map parameters) {
final XpdlExecution xpdlExecution = (XpdlExecution) execution;
if (AbstractActivity.BODY_FINISHED.equals(signal)) {
this.end(xpdlExecution);
} else if (AbstractActivity.ACT_INSTANCE_FINISHED.equals(signal)) {
xpdlExecution.setWaitingForActivityInstanceNb(xpdlExecution.getWaitingForActivityInstanceNb() - 1);
if (xpdlExecution.getWaitingForActivityInstanceNb() == 0) {
if (xpdlExecution.getExecutions() != null) {
for (final OpenExecution execToAbort : new ArrayList(xpdlExecution.getExecutions())) {
((XpdlExecution) execToAbort).abort();
}
}
this.executeSplit(xpdlExecution, false);
}
} else if (signal != null && this.deadlines != null) {
for (final String deadline : this.deadlines) {
if (deadline.equals(signal)) {
Authentication.setUserId(BonitaConstants.SYSTEM_USER);
// By default, a deadline does not propagate execution
xpdlExecution.waitForSignal();
final String activityId = xpdlExecution.getNode().getName();
final JavaHook javaHook = new JavaHook(signal, JavaHook.Type.onDeadline, true);
EngineEnvTool.getHookExecutor()
.executeHook(xpdlExecution, activityId, javaHook);
return;
}
}
}
}
protected void executeSplit(final Execution execution, final boolean removeScope) {
XpdlExecution xpdlExecution = (XpdlExecution) execution;
final NodeImpl currentNode = xpdlExecution.getNode();
if (AbstractActivity.LOG.isLoggable(Level.FINE)) {
AbstractActivity.LOG.fine("node = " + currentNode.getName() + " - splitType = "
+ this.splitType + " - execution = " + execution.getName());
}
final List transitions = currentNode.getOutgoingTransitions();
if (transitions == null) {
if (AbstractActivity.LOG.isLoggable(Level.FINE)) {
AbstractActivity.LOG.fine("node = " + currentNode.getName() + " - splitType = "
+ this.splitType + " - execution = " + execution.getName() + " no transition available. Ending execution");
}
xpdlExecution.end();
final XpdlExecution parent = xpdlExecution.getParent();
if (parent != null) {
parent.removeExecution(xpdlExecution);
}
} else {
final List transitionsToTake = new ArrayList();
for (final Transition t : transitions) {
if (this.evaluateTransition((TransitionImpl) t, xpdlExecution)) {
if (
xpdlExecution
.getXpdlInstance()
.getTransitionStatus(t)
.getState().equals(TransitionState.READY)
) {
xpdlExecution.getXpdlInstance().setTransitionState(t, TransitionState.TAKEN);
transitionsToTake.add(t);
}
}
}
// remove not propagated variables
if (removeScope) {
xpdlExecution = (XpdlExecution) xpdlExecution.destroyScope(currentNode);
}
xpdlExecution.setCurrentActivityInstanceUUID(null);
if (transitionsToTake.size() == 0) {
xpdlExecution.end();
final XpdlExecution parent = xpdlExecution.getParent();
if (parent != null) {
parent.removeExecution(xpdlExecution);
}
} else {
// check we are leaving a cycle
if (this.iterationDescriptors != null && !this.iterationDescriptors.isEmpty()) {
for (final IterationDescriptor itD : this.iterationDescriptors) {
boolean isLeaving = false;
for (final Transition t : transitionsToTake) {
if (!itD.containsNode(t.getDestination())) {
isLeaving = true;
}
}
if (isLeaving) {
// abort execution of other nodes.
if (AbstractActivity.LOG.isLoggable(Level.FINE)) {
AbstractActivity.LOG.fine(this.activityId + " is leaving a cycle, aborting other nodes in cycle.");
}
for (final NodeInIterationDescriptor nodeToAbortDescr : itD.getCycleNodes()) {
final NodeImpl nodeToAbort = nodeToAbortDescr.getNode();
if (!nodeToAbort.equals(currentNode)) {
final List execToAbortList = xpdlExecution.getXpdlInstance().getExecOnNode(nodeToAbort.getName());
for (final XpdlExecution execToAbort : execToAbortList) {
if (execToAbort.isActive()) {
execToAbort.abort();
}
}
}
}
}
}
}
if (transitionsToTake.size() == 1 || this.splitType.equals(SplitType.XOR)) {
// We are in a Split/AND and only one transition is true,
// or we are in a Split/XOR, so we take the first one that is true.
final Transition t = transitionsToTake.get(0);
if (AbstractActivity.LOG.isLoggable(Level.FINE)) {
AbstractActivity.LOG.fine("Taking transition " + t);
}
xpdlExecution.take(t);
} else {
// We are in a Split/AND and more than one transition is true.
// check we are not leaving a cycle and staying in the cycle at the same time
if (this.iterationDescriptors != null && !this.iterationDescriptors.isEmpty()) {
for (final IterationDescriptor itD : this.iterationDescriptors) {
boolean isLeaving = false;
boolean isStaying = false;
for (final Transition t : transitionsToTake) {
if (!itD.containsNode(t.getDestination())) {
isLeaving = true;
} else {
isStaying = true;
}
}
if (isStaying && isLeaving) {
throw new BonitaWrapperException(new BonitaRuntimeException("Exception in iterations: an execution is leaving a cycle while the other is still in the cycle."));
}
}
}
final List children = new ArrayList();
for (int i = 0; i < transitionsToTake.size(); i++) {
final XpdlExecution childExecution = this.createChildExecution(xpdlExecution, i);
final Transition t = transitionsToTake.get(i);
childExecution.setNode((NodeImpl)t.getDestination());
children.add(childExecution);
}
for (int i = 0; i < transitionsToTake.size(); i++) {
final XpdlExecution childExecution = children.get(i);
childExecution.setNode(currentNode);
final Transition t = transitionsToTake.get(i);
if (!childExecution.isFinished()) {
if (AbstractActivity.LOG.isLoggable(Level.FINE)) {
AbstractActivity.LOG.fine("Execution " + childExecution.getName() + " is taking transition " + t);
}
childExecution.take(t);
}
}
}
}
}
}
private boolean evaluateTransition(final TransitionImpl t, final XpdlExecution xpdlExecution) {
// testing the guard condition
final Condition condition = t.getCondition();
final ConditionDefinition condDef = (ConditionDefinition) condition;
boolean conditionOK = true;
if (condDef != null) {
conditionOK = condDef.evaluate(xpdlExecution);
if (!conditionOK) {
if (AbstractActivity.LOG.isLoggable(Level.FINE)) {
AbstractActivity.LOG.fine("Unable to take transition: " + t.getName());
}
// TODO : cancel nodes on this branch : may be investigate for cleaning of executions ?
}
}
return conditionOK;
}
protected XpdlExecution createChildExecution(final XpdlExecution parentExecution, final int childId) {
final String executionName = parentExecution.getName() + "/" + childId;
final XpdlExecution childExecution = (XpdlExecution) parentExecution.createExecution(executionName);
if (AbstractActivity.LOG.isLoggable(Level.FINE)) {
AbstractActivity.LOG.fine("Creating child execution with name " + childExecution.getName());
}
return childExecution;
}
protected boolean executeJoin(final XpdlExecution execution) {
final Transition previousTransition = execution.getPreviousTransition();
final String fromName = previousTransition.getSource().getName();
final TransitionStatus fromTransition = execution.getXpdlInstance().getTransitionStatus(previousTransition);
if (fromTransition.getState().equals(TransitionState.ARRIVED)) {
throw new BonitaRuntimeException("transition " + fromName + "->" + this.activityId + " is already arrived in this Join.");
}
if (fromTransition.getState().equals(TransitionState.TAKEN)) {
fromTransition.setState(TransitionState.ARRIVED);
}
return AbstractActivity.isJoinOk(execution.getXpdlInstance(), execution.getNode());
}
private static boolean isJoinOk(final XpdlInstance instance, final NodeImpl node) {
if (!node.hasIncomingTransitions()) {
return true;
}
if (((AbstractActivity) node.getBehaviour()).getJoinType().equals(JoinType.XOR)) {
// join XOR
for (final Transition transition : node.getIncomingTransitions()) {
final TransitionStatus ts = instance.getTransitionStatus(transition);
if (ts.getState().equals(TransitionState.ARRIVED)) {
return true;
}
}
return false;
} else {
// join AND
for (final Transition transition : node.getIncomingTransitions()) {
final TransitionStatus ts = instance.getTransitionStatus(transition);
if (!ts.getState().equals(TransitionState.ARRIVED)) {
return false;
}
}
return true;
}
}
/**
* Describes how a node is involved in a cycle (simple node, entry point or exit point).
* @author Guillaume Porcher
*
*/
public static class NodeInIterationDescriptor {
private NodeImpl node;
private boolean isEntryNode;
private boolean isExitNode;
protected NodeInIterationDescriptor() { }
public NodeInIterationDescriptor(final NodeImpl node, final boolean isEntryNode, final boolean isExitNode) {
this.node = node;
this.isEntryNode = isEntryNode;
this.isExitNode = isExitNode;
}
public NodeImpl getNode() {
return this.node;
}
public boolean isEntryNode() {
return this.isEntryNode;
}
public boolean isExitNode() {
return this.isExitNode;
}
}
/**
* Describes a cycle.
*
* @author Guillaume Porcher
*
*/
public static class IterationDescriptor {
/**
* List of cycle nodes (descriptors)
*/
private Set cycleNodes;
protected IterationDescriptor() { }
public IterationDescriptor(
final Set cycleNodes) {
this.cycleNodes = cycleNodes;
}
public Set getCycleNodes() {
return this.cycleNodes;
}
/**
*
* @param node
* @return true if the node is in his iteration
*/
public boolean containsNode(final Node node) {
return this.getNodeInIterationDescriptor(node) != null;
}
/**
*
* @param node
* @return the node descriptor which describes the behavior of the node in this iteration.
*/
public NodeInIterationDescriptor getNodeInIterationDescriptor(final Node node) {
for (final NodeInIterationDescriptor nodeDesc : this.cycleNodes) {
if (nodeDesc.getNode().equals(node)) {
return nodeDesc;
}
}
return null;
}
}
public List getIterationDescriptors() {
return this.iterationDescriptors;
}
public void setIterationDescriptors(final List iteration) {
this.iterationDescriptors = iteration;
}
private void createNewIteration(final XpdlExecution execution) {
if (this.iterationDescriptors != null && !this.iterationDescriptors.isEmpty()) {
final String iterationUUID = Misc.getUniqueId("it");
execution.setIterationId(iterationUUID);
final XpdlInstance instance = execution.getXpdlInstance();
for (final IterationDescriptor it : this.iterationDescriptors) {
final NodeInIterationDescriptor nodeDescr = it.getNodeInIterationDescriptor(execution.getNode());
if (nodeDescr != null && nodeDescr.isEntryNode()) {
for (final NodeInIterationDescriptor joinNodeDescr : it.getCycleNodes()) {
final NodeImpl joinNode = joinNodeDescr.getNode();
for (final Transition tr : joinNode.getIncomingTransitions()) {
if (it.containsNode(tr.getSource())) {
instance.setTransitionState(tr, TransitionState.READY);
}
}
if (AbstractActivity.isJoinOk(instance, joinNode)) {
throw new BonitaRuntimeException("Error in iteration: join " + joinNode.getName() + " has not been reinitialized");
}
}
}
}
}
}
private boolean executeBody(final XpdlExecution xpdlExecution) {
if (this.bodyStartAutomatically()) {
final ActivityInstanceCurrentInfo activityInstanceCurrentInfo = new ActivityInstanceCurrentInfo(
xpdlExecution.getXpdlInstance().getPackageDefinitionUUID(),
xpdlExecution.getXpdlInstance().getProcessDefinitionUUID(),
xpdlExecution.getXpdlInstance().getUUID(),
xpdlExecution.getCurrentActivityInstanceUUID(),
this.getActivityType(),
this.getActivityId(),
xpdlExecution.getIterationId(),
xpdlExecution.getActivityInstanceId(),
xpdlExecution.getScopeVariables());
ServiceEnvTool.getRecorder().recordBodyStarted(activityInstanceCurrentInfo);
}
return this.executeBusinessLogic(xpdlExecution);
}
//public abstract ActivityBody getBody(XpdlExecution xpdlExecution);
/**
* Return true if the execution can continue
*/
protected abstract boolean executeBusinessLogic(Execution execution);
protected abstract boolean bodyStartAutomatically();
public List getVariableDefinitions() {
return this.variableDefinitions;
}
public void setVariableDefinitions(
final List variableDefinitions) {
this.variableDefinitions = variableDefinitions;
}
public ActivityType getActivityType() {
return this.activityType;
}
public Performer getPerformer() {
return this.performer;
}
public JoinType getJoinType() {
return this.joinType;
}
public void setJoinType(final JoinType joinType) {
this.joinType = joinType;
}
public SplitType getSplitType() {
return this.splitType;
}
public Set getDeadlineHooks() {
return this.deadlines;
}
public void setDeadlineHooks(final Set deadlineHooks) {
this.deadlines = deadlineHooks;
}
public void setJavaHooks(final List javaHooks) {
this.javaHooks = javaHooks;
}
public List getJavaHooks() {
return this.javaHooks;
}
public String getActivityId() {
return this.activityId;
}
public void setMultiInstantiation(final String variableId, final ClassInfo instantiator) {
this.multiInstantiationVariable = variableId;
this.multiInstantiationClass = instantiator;
}
@Override
public String toString() {
final StringBuffer buffer = new StringBuffer();
buffer.append(this.getClass().getName());
buffer.append(": activtyId: " + this.activityId);
return buffer.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy