* @return The last loaded step after the queue element.
*/
protected Step loadQueue(Element queueElement, final Assignment assignment)
{
final Lookup eventMap = new HashTab();
final Fork fork = new Fork();
final Decision decision = new Decision();
fork.setActivity(assignment.getActivity());
decision.setActivity(assignment.getActivity());
XMLUtil.forEachChildElement(queueElement, null,
m_helper.new ElementHandler("queueEvent")
{
private boolean m_bTimer;
protected String getName(Element eventElement)
{
return XMLUtil.getStringAttr(eventElement, "name");
}
public void handleElement(Element eventElement, String sEventName)
{
Node child = eventElement.getFirstChild();
String sElement = eventElement.getNodeName();
Concurrent activity = new Concurrent();
Branch branch = null;
activity.setFork(fork);
if (sElement.equals("TimerEvent"))
{
if (m_bTimer)
{
throw new MetadataException("err.meta.workflow.multipleQueueTimers",
new Object[]{assignment.getName()});
}
Timeout timeout = new Timeout();
timeout.setActivity(activity);
timeout.setValue(m_helper.parse(XMLUtil.getReqStringAttr(eventElement, "value"),
false, activity.getFlow().getPosMap(), null, m_metadata.getGlobalEnvironment()));
activity.addStep(timeout);
Wait wait = new Wait(timeout);
timeout.setNext(wait);
activity.addStep(wait);
m_bTimer = true;
}
else if (sElement.equals("ClassEvent"))
{
AutoCompletion completion = new AutoCompletion(assignment);
loadWorkflowHandler(eventElement, completion, activity.getFlow());
activity.addStep(completion);
}
else if (sElement.equals("ManualEvent"))
{
Object condition = m_helper.parse(XMLUtil.getStringAttr(eventElement, "condition"),
false, assignment.getActivity().getFlow().getPosMap(),
Boolean.TRUE, m_metadata.getGlobalEnvironment());
boolean bTarget = loadTarget(eventElement, assignment, condition, sEventName, false);
Element first = XMLUtil.findFirstElement(child);
if (first != null && first.getNodeName().equals("UIAction"))
{
loadTarget(first, assignment, condition, sEventName, bTarget);
child = first.getNextSibling();
}
if (assignment.getManualCompletion() == null)
{
ManualCompletion completion = new ManualCompletion(assignment);
activity.addStep(completion);
}
else
{
activity = null;
}
}
else if (sElement.equals("ProcessEvent"))
{
branch = new Branch();
decision.addBranch(branch);
assignment.setSemaphore(true);
Semaphore semaphore = new Semaphore(assignment.getName() + ":Semaphore", assignment);
semaphore.setActivity(activity);
activity.addStep(semaphore);
Block block = new Block();
block.setActivity(branch);
branch.addStep(block);
loadActivity(child, block.getContainedActivity());
block.setCleanupCode(semaphore.getExitCode());
}
else
{
throw new MetadataException("err.meta.workflow.invalidQueueElement",
new Object[]{sElement, assignment.getName()});
}
if (eventMap.put(sEventName, Boolean.TRUE) != null)
{
throw new MetadataException("err.meta.workflow.queueEventDup",
new Object[]{sEventName, assignment.getName()});
}
Variable var = assignment.getActivity().getFlow().findVariable(assignment.getName());
if (var == null)
{
var = new Variable(assignment.getName());
assignment.getActivity().getFlow().addVariable(var);
}
if (activity != null)
{
Object code;
if (activity.getStep(0) instanceof ManualCompletion)
{
// ((:state'bind ('<assignment>'targetFunction)) '() (:flow'getToken <step>))
code =
Pair.list(
Pair.list(Symbol._STATE, Pair.quote(Symbol.BIND),
Pair.list(Pair.quote(assignment), Pair.quote(Symbol.TARGETFUNCTION))),
null,
Pair.list(Symbol._FLOW, Pair.quote(Symbol.GETTOKEN), Pair.quote(activity.getStep(0))));
}
else
{
code = sEventName;
}
Script script = new Script();
script.setBody(Pair.list(Pair.list(Symbol.SET, var.getSymbol(), code)));
activity.addStep(script);
fork.addConcurrent(activity);
}
if (branch == null)
{
branch = new Branch();
decision.addBranch(branch);
loadActivity(child, branch);
}
branch.setCondition(Pair.list(Symbol.EQUAL_P, var.getSymbol(), sEventName));
}
});
if (fork.getConcurrentCount() == 0)
{
throw new MetadataException("err.meta.workflow.eventlessQueue",
new Object[]{assignment.getName()});
}
if (fork.getConcurrentCount() == 1)
{
Activity activity = fork.getConcurrent(0);
if (activity.getStep(0) instanceof Timeout)
{
activity.addStep(new Completion(assignment));
}