clearParameters();
}
public void run() throws SaxonApiException {
XProcStep xstep = runtime.getConfiguration().newStep(runtime, this);
// If there's more than one reader, collapse them all into a single reader
for (String port : inputs.keySet()) {
int totalDocs = 0; // FIXME: this will be more complicated when multiple threads are involved
Input input = step.getInput(port);
if (!input.getParameterInput()) {
int readerCount = inputs.get(port).size();
if (readerCount > 1) {
Pipe pipe = new Pipe(runtime);
pipe.setWriter(step);
pipe.setReader(step);
pipe.canWriteSequence(true);
pipe.canReadSequence(input.getSequence());
for (ReadablePipe reader : inputs.get(port)) {
if (reader.moreDocuments()) {
while (reader.moreDocuments()) {
XdmNode doc = reader.read();
pipe.write(doc);
totalDocs++;
}
} else if (reader instanceof ReadableDocument) {
// HACK: We haven't necessarily read the document yet
totalDocs++;
}
}
xstep.setInput(port, pipe);
} else if (readerCount == 1) {
ReadablePipe pipe = inputs.get(port).firstElement();
pipe.setReader(step);
if (pipe.moreDocuments()) {
totalDocs += pipe.documentCount();
} else if (pipe instanceof ReadableDocument) {
totalDocs++;
}
xstep.setInput(port, pipe);
}
}
if (totalDocs != 1 && !input.getSequence()) {
throw XProcException.dynamicError(6, step.getNode(), totalDocs + " documents appear on the '" + port + "' port.");
}
}
for (String port : outputs.keySet()) {
xstep.setOutput(port, outputs.get(port));
}
// 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 options
DeclareStep decl = step.getDeclaration();
inScopeOptions = parent.getInScopeOptions();
for (QName name : step.getOptions()) {
Option option = step.getOption(name);
RuntimeValue value = computeValue(option);
Option optionDecl = decl.getOption(name);
String typeName = optionDecl.getType();
XdmNode declNode = optionDecl.getNode();
if (typeName != null && declNode != null) {
if (typeName.contains("|")) {
TypeUtils.checkLiteral(value.getString(), typeName);
} else {
QName type = new QName(typeName, declNode);
TypeUtils.checkType(runtime, value.getString(),type,option.getNode());
}
}
xstep.setOption(name, value);
inScopeOptions.put(name, value);
}
xstep.reset();
computeParameters(xstep);
// HACK HACK HACK!
if (XProcConstants.p_in_scope_names.equals(step.getType())) {
for (QName name : inScopeOptions.keySet()) {
xstep.setParameter(name, inScopeOptions.get(name));
}
}
// Make sure we do this *after* calculating any option/parameter values...
XProcData data = runtime.getXProcData();
data.openFrame(this);
runtime.start(this);
try {
xstep.run();
// FIXME: Is it sufficient to only do this for atomic steps?
String cache = getInheritedExtensionAttribute(XProcConstants.cx_cache);
if ("true".equals(cache)) {
for (String port : outputs.keySet()) {