org.jboss.bpm.ri.model.impl.FlowObjectImpl Maven / Gradle / Ivy
The newest version!
/*
* 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.jboss.bpm.ri.model.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.jboss.bpm.InvalidProcessException;
import org.jboss.bpm.NameNotUniqueException;
import org.jboss.bpm.model.Assignment;
import org.jboss.bpm.model.ConnectingObject;
import org.jboss.bpm.model.Expression;
import org.jboss.bpm.model.FlowObject;
import org.jboss.bpm.model.Gate;
import org.jboss.bpm.model.Gateway;
import org.jboss.bpm.model.Process;
import org.jboss.bpm.model.SingleInFlowSupport;
import org.jboss.bpm.model.SingleOutFlowSupport;
import org.jboss.bpm.model.Assignment.AssignTime;
import org.jboss.bpm.runtime.ExecutionContext;
import org.jboss.bpm.runtime.ExecutionHandler;
import org.jboss.bpm.runtime.FlowHandler;
import org.jboss.bpm.runtime.SignalHandler;
import org.jboss.bpm.runtime.Token;
import org.jboss.bpm.runtime.TokenExecutor;
//$Id: FlowObjectImpl.java 1982 2008-08-22 10:09:27Z [email protected] $
/**
* A Flow Object is one of the set of following graphical objects: Event, Activity, and
*
* @author [email protected]
* @since 08-Jul-2008
*/
@SuppressWarnings("serial")
public abstract class FlowObjectImpl extends GraphicalElementImpl implements FlowObject, HandlerSetterSupport
{
private String name;
private Process proc;
private FlowHandler flowHandler;
private SignalHandler signalHandler;
private ExecutionHandler executionHandler;
private List assignments = new ArrayList();
public FlowObjectImpl(String name)
{
this.name = name;
}
public Process getProcess()
{
return proc;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public List getAssignments()
{
return Collections.unmodifiableList(assignments);
}
public void addAssignment(Assignment assignment)
{
this.assignments.add(assignment);
}
public ExecutionHandler getExecutionHandler()
{
return executionHandler;
}
public void setExecutionHandler(ExecutionHandler executionHandler)
{
this.executionHandler = executionHandler;
}
public FlowHandler getFlowHandler()
{
return flowHandler;
}
public void setFlowHandler(FlowHandler flowHandler)
{
this.flowHandler = flowHandler;
}
public SignalHandler getSignalHandler()
{
return signalHandler;
}
public void setSignalHandler(SignalHandler signalHandler)
{
this.signalHandler = signalHandler;
}
/**
* Execute this FlowObject
*/
public void execute(Token token)
{
// Process the start time assignments
startTimeAssignments(token);
// Call the ExecutionHandler
ExecutionHandler exHandler = getExecutionHandler();
if (exHandler != null)
{
exHandler.execute(token);
}
else
{
defaultExecution(token);
}
// Process the end time assignments
endTimeAssignments(token);
}
protected void startTimeAssignments(Token token)
{
for (Assignment ass : getAssignments())
{
if (ass.getAssignTime() == AssignTime.Start)
processAssignment(ass, token);
}
}
protected void endTimeAssignments(Token token)
{
for (Assignment ass : getAssignments())
{
if (ass.getAssignTime() == AssignTime.End)
processAssignment(ass, token);
}
}
protected void processAssignment(Assignment ass, Token token)
{
Expression expr = ass.getFrom();
ExpressionEvaluator exprEvaluator = new ExpressionEvaluator(expr);
Object result = exprEvaluator.evaluateExpression(token);
String propName = ass.getTo().getName();
ExecutionContext exContext = token.getExecutionContext();
exContext.addAttachment(propName, result);
}
/**
* Execute the FlowHandler. Keep final, it should not be necessary to override this.
*/
public final void executeFlowHandler(TokenExecutor tokenExecutor, Token token)
{
// Call the ExecutionHandler
FlowHandler flowHandler = getFlowHandler();
if (flowHandler != null)
{
flowHandler.execute(tokenExecutor, token);
}
else
{
defaultFlowHandler(tokenExecutor, token);
}
}
/**
* Overwrite to provide an implementation
*/
protected void defaultExecution(Token token)
{
// noting to do
}
/**
* Overwrite to provide an implementation
*/
protected abstract void defaultFlowHandler(TokenExecutor tokenExecutor, Token token);
/**
* Reset the FlowObject's state
*/
public void reset()
{
// noting to do
}
@Override
protected void create(Process proc)
{
super.create(proc);
this.proc = proc;
// Check required name
if (name == null)
throw new InvalidProcessException("Name is required for: " + this);
// Check name uniqueness
for (FlowObject aux : proc.getFlowObjects())
{
String auxName = aux.getName();
if (aux != this && name.equals(auxName))
throw new NameNotUniqueException(toString());
}
// Initialize in/out flows
ConnectingObject outFlow = null;
if (this instanceof SingleOutFlowSupport)
{
SingleOutFlowSupport sof = (SingleOutFlowSupport)this;
outFlow = sof.getOutFlow();
initFlow(proc, (SequenceFlowImpl)outFlow);
}
else if (this instanceof MultipleOutFlowSupport)
{
MultipleOutFlowSupport mof = (MultipleOutFlowSupport)this;
for (ConnectingObject flow : mof.getOutFlows())
{
outFlow = flow;
initFlow(proc, (SequenceFlowImpl)outFlow);
}
}
else if (this instanceof Gateway)
{
Gateway gateway = (Gateway)this;
for (Gate gate : gateway.getGates())
{
outFlow = gate.getOutgoingSequenceFlow();
initFlow(proc, (SequenceFlowImpl)outFlow);
}
}
ConnectingObject inFlow = null;
if (this instanceof SingleInFlowSupport)
{
SingleInFlowSupport sif = (SingleInFlowSupport)this;
inFlow = sif.getInFlow();
}
else if (this instanceof MultipleInFlowSupport)
{
MultipleInFlowSupport mif = (MultipleInFlowSupport)this;
for (ConnectingObject flow : mif.getInFlows())
{
inFlow = flow;
}
}
if (inFlow == null && outFlow == null)
throw new InvalidProcessException("Unconnected flow object: " + this);
}
private void initFlow(Process proc, SequenceFlowImpl flow)
{
if (flow != null)
{
String name = flow.getTargetName();
FlowObject target = proc.getFlowObject(name);
if (target == null)
throw new InvalidProcessException("Cannot find target for out flow: " + name);
if (target instanceof SingleInFlowSetterSupport)
{
SingleInFlowSetterSupport sif = (SingleInFlowSetterSupport)target;
sif.setInFlow(flow);
}
else if (target instanceof MultipleInFlowSetterSupport)
{
MultipleInFlowSetterSupport mif = (MultipleInFlowSetterSupport)target;
mif.addInFlow(flow);
}
else
{
throw new InvalidProcessException("Target does not support in flow: " + target);
}
flow.setSourceRef(this);
flow.setTargetRef(target);
}
}
}