}
public void run() throws SaxonApiException {
logger.trace("Running p:for-each " + step.getName());
XProcData data = runtime.getXProcData();
data.openFrame(this);
if (current == null) {
current = new Pipe(runtime);
}
String iport = "#iteration-source";
sequencePosition = 0;
sequenceLength = 0;
inScopeOptions = parent.getInScopeOptions();
// FIXME: Do I really have to do this? At the very least, only do it if we have to!
Vector<XdmNode> nodes = new Vector<XdmNode> ();
for (ReadablePipe is_reader : inputs.get(iport)) {
while (is_reader.moreDocuments()) {
XdmNode is_doc = is_reader.read();
logger.trace(MessageFormatter.nodeMessage(step.getNode(), "Input copy from " + is_reader));
logger.trace(MessageFormatter.nodeMessage(step.getNode(), is_doc.toString()));
nodes.add(is_doc);
sequenceLength++;
}
}
runtime.getXProcData().setIterationSize(sequenceLength);
runtime.start(this);
try {
for (XdmNode is_doc : nodes) {
// Setup the current port before we compute variables!
current.resetWriter();
current.write(is_doc);
logger.trace(MessageFormatter.nodeMessage(step.getNode(), "Copy to current"));
sequencePosition++;
runtime.getXProcData().setIterationPosition(sequencePosition);
for (Variable var : step.getVariables()) {
RuntimeValue value = computeValue(var);
inScopeOptions.put(var.getName(), value);
}
// N.B. At this time, there are no compound steps that accept parameters or options,
// so the order in which we calculate them doesn't matter. That will change if/when
// there are such compound steps.
// Calculate all the variables
inScopeOptions = parent.getInScopeOptions();
for (Variable var : step.getVariables()) {
RuntimeValue value = computeValue(var);
inScopeOptions.put(var.getName(), value);
}
for (XStep step : subpipeline) {
step.run();
}
for (String port : inputs.keySet()) {
if (port.startsWith("|")) {
String wport = port.substring(1);
boolean seqOk = step.getOutput(wport).getSequence();
int docsCopied = 0;
WritablePipe pipe = outputs.get(wport);
// The output of a for-each is a sequence, irrespective of what the output says
pipe.canWriteSequence(true);
for (ReadablePipe reader : inputs.get(port)) {
reader.canReadSequence(true); // Hack again!
while (reader.moreDocuments()) {
XdmNode doc = reader.read();
pipe.write(doc);
docsCopied++;
logger.trace(MessageFormatter.nodeMessage(step.getNode(), "Output copy from " + reader + " to " + pipe));
}
reader.resetReader();
}
if (docsCopied != 1 && !seqOk) {
throw XProcException.dynamicError(6);
}
}
}
for (XStep step : subpipeline) {
step.reset();
}
}
} finally {
for (String port : inputs.keySet()) {
if (port.startsWith("|")) {
String wport = port.substring(1);
WritablePipe pipe = outputs.get(wport);
pipe.close(); // Indicate that we're done
}
}
runtime.finish(this);
data.closeFrame();
}
}