All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.xmlcalabash.runtime.XStep Maven / Gradle / Ivy
package com.xmlcalabash.runtime;
import com.xmlcalabash.core.XProcRunnable;
import net.sf.saxon.s9api.XdmNode;
import net.sf.saxon.s9api.QName;
import net.sf.saxon.s9api.SaxonApiException;
import org.slf4j.Logger;
import java.util.Hashtable;
import java.util.Set;
import java.util.HashSet;
import java.util.Vector;
import java.util.Optional;
import javax.xml.transform.SourceLocator;
import com.xmlcalabash.core.XProcException;
import com.xmlcalabash.core.XProcRuntime;
import com.xmlcalabash.core.XProcConstants;
import com.xmlcalabash.io.Pipe;
import com.xmlcalabash.io.ReadablePipe;
import com.xmlcalabash.model.RuntimeValue;
import com.xmlcalabash.model.Step;
import com.xmlcalabash.model.Input;
import com.xmlcalabash.model.DeclareStep;
import org.slf4j.LoggerFactory;
/**
* Created by IntelliJ IDEA.
* User: ndw
* Date: Oct 7, 2008
* Time: 8:02:28 AM
* To change this template use File | Settings | File Templates.
*/
public abstract class XStep implements XProcRunnable {
protected Logger logger = null;
protected XProcRuntime runtime = null;
protected Step step = null;
protected String name = null;
private Hashtable xinputs = new Hashtable ();
private Hashtable xoutputs = new Hashtable ();
protected Hashtable> inputs = new Hashtable> ();
protected Hashtable outputs = new Hashtable ();
private Hashtable options = new Hashtable ();
private Hashtable> parameters = new Hashtable> ();
protected XCompoundStep parent = null;
protected Hashtable inScopeOptions = new Hashtable ();
/* the next frames in the call stack */
private static final SourceLocator[] EMPTY_LOCATION = new SourceLocator[]{};
protected SourceLocator[] parentLocation = EMPTY_LOCATION;
private Boolean runLazily = null;
public XStep(XProcRuntime runtime, Step step) {
this.runtime = runtime;
this.step = step;
if (step != null) {
name = step.getName();
}
logger = LoggerFactory.getLogger(this.getClass());
}
public Step getStep() {
return step;
}
public XdmNode getNode() {
return step.getNode();
}
public QName getType() {
return step.getNode().getNodeName();
}
public String getName() {
return name;
}
public DeclareStep getDeclareStep() {
return step.getDeclaration();
}
public XCompoundStep getParent() {
return parent;
}
public void addInput(XInput input) {
String port = input.getPort();
if (xinputs.containsKey(port)) {
throw new XProcException(input.getNode(), "Attempt to add output '" + port + "' port to the same step twice.");
}
xinputs.put(port, input);
}
public void addOutput(XOutput output) {
String port = output.getPort();
if (xoutputs.containsKey(port)) {
throw new XProcException(output.getNode(), "Attempt to add output '" + port + "' port to the same step twice.");
}
xoutputs.put(port, output);
}
public XInput getInput(String port) {
if (xinputs.containsKey(port)) {
return xinputs.get(port);
} else {
throw new XProcException(step, "Attempt to get non-existant input '" + port + "' port from step.");
}
}
public XOutput getOutput(String port) {
if (xoutputs.containsKey(port)) {
return xoutputs.get(port);
} else {
if (XProcConstants.NS_XPROC.equals(step.getType().getNamespaceURI())
&& step.getStep().getVersion() > 1.0) {
return null;
} else {
throw new XProcException(step, "Attempt to get non-existant output '" + port + "' port from step.");
}
}
}
public void setParameter(QName name, RuntimeValue value) {
Set ports = getParameterPorts();
int pportCount = 0;
String pport = null;
String ppport = null;
for (String port : ports) {
pport = port;
pportCount++;
Input pin = getStep().getInput(port);
if (pin.getPrimary()) {
ppport = port;
}
}
if (pportCount == 0) {
throw new XProcException(step, "Attempt to set parameter but there's no parameter port.");
}
if (ppport != null) {
pport = ppport;
} else {
if (pportCount > 1) {
throw new XProcException(step, "Attempt to set parameter w/o specifying a port (and there's more than one)");
}
}
setParameter(pport, name, value);
}
public void setParameter(String port, QName name, RuntimeValue value) {
Hashtable pparams;
if (parameters.containsKey(port)) {
pparams = parameters.get(port);
} else {
XInput xinput = getInput(port); // Make sure there is one
Input input = getDeclareStep().getInput(port);
if (!input.getParameterInput()) {
throw new XProcException(step, "Attempt to write parameters to non-parameter input port: " + port);
}
pparams = new Hashtable ();
parameters.put(port, pparams);
}
if (pparams.containsKey(name)) {
throw new XProcException(step, "Duplicate parameter: " + name);
}
if (XProcConstants.NS_XPROC.equals(name.getNamespaceURI())) {
throw XProcException.dynamicError(31);
}
pparams.put(name, value);
}
public Set getOptions() {
return options.keySet();
}
public RuntimeValue getOption(QName name) {
if (options.containsKey(name)) {
return options.get(name);
} else {
return null;
}
}
public void setOption(QName name, RuntimeValue value) {
/* this causes an attempt to run the same pipeline twice to fail because the passedInOptions get set twice...
if (options.containsKey(name)) {
throw new XProcException(step.getNode(), "Duplicate option: " + name);
}
*/
options.put(name, value);
}
public void clearOptions() {
options.clear();
}
public void clearParameters() {
parameters.clear();
}
public Set getParameters() {
return getParameters("*");
}
public RuntimeValue getParameter(QName name) {
Set ports = getParameterPorts();
int pportCount = 0;
String pport = null;
for (String port : ports) {
pport = port;
pportCount++;
}
if (pportCount != 1) {
return null;
}
return getParameter(pport, name);
}
public Set getParameterPorts() {
HashSet ports = new HashSet ();
for (Input input : step.inputs()) {
if (input.getParameterInput()) {
ports.add(input.getPort());
}
}
return ports;
}
public Set getParameters(String port) {
if (parameters.containsKey(port)) {
return parameters.get(port).keySet();
} else {
return new HashSet ();
}
}
public RuntimeValue getParameter(String port, QName name) {
if (parameters.containsKey(port)) {
Hashtable pparams = parameters.get(port);
if (pparams.containsKey(name)) {
return pparams.get(name);
}
}
return null;
}
public String getExtensionAttribute(QName name) {
if (step != null) {
return step.getExtensionAttribute(name);
} else {
return null;
}
}
public String getInheritedExtensionAttribute(QName name) {
if (getExtensionAttribute(name) != null) {
return getExtensionAttribute(name);
}
if (parent != null) {
return parent.getInheritedExtensionAttribute(name);
}
return null;
}
public boolean hasInScopeVariableBinding(QName name) {
if (inScopeOptions.containsKey(name)) {
return true;
}
return getParent() != null && getParent().hasInScopeVariableBinding(name);
}
public boolean hasInScopeVariableValue(QName name) {
if (inScopeOptions.containsKey(name)) {
RuntimeValue v = getOption(name);
return v.initialized();
}
return getParent() != null && getParent().hasInScopeVariableBinding(name);
}
public Hashtable getInScopeOptions() {
// We make a copy so that what our children do can't effect us
Hashtable globals = new Hashtable ();
if (inScopeOptions != null) {
for (QName name : inScopeOptions.keySet()) {
globals.put(name,inScopeOptions.get(name));
}
}
return globals;
}
public abstract RuntimeValue optionAvailable(QName optName);
public abstract void instantiate(Step step);
public abstract void reset();
public void run() throws SaxonApiException {
if (runLazily == null) {
runLazily = isPure().orElse(false);
}
if (runLazily) {
XProcRunnable runIfNotRunYet = new XProcRunnable() {
private boolean done = false;
public void run() throws SaxonApiException {
if (done) return;
done = true;
doRun();
// next time XStep.run() is called don't run lazily, because we already know an
// output will be accessed so we might as well do it immediately
runLazily = false;
}
};
for (String port : outputs.keySet()) {
outputs.get(port).onRead(runIfNotRunYet);
}
} else {
doRun();
}
}
protected abstract void doRun() throws SaxonApiException;
private Optional isPure() {
if (step != null) {
Optional pure = step.isPure();
DeclareStep decl = getDeclareStep();
if (decl != null) {
Optional declPure = decl.isPure();
if (declPure.isPresent()) {
// cx:pure on step has precedence
if (!pure.isPresent())
return declPure;
else if (pure.get() && !declPure.get()) {
XProcException warning = new XProcException(
this,
"Step was marked with cx:pure=\"true\" but the corresponding declaration is impure");
logger.warn(warning.toString());
}
}
}
return pure;
} else {
return Optional.empty();
}
}
public void error(XProcException error) {
runtime.error(this, error);
}
public void warning(XdmNode location, String message) {
runtime.warning(this, location, message);
}
public void info(XdmNode location, String message) {
runtime.info(this, location, message);
}
public SourceLocator[] getLocation() {
if (step == null)
return parentLocation;
SourceLocator[] location = new SourceLocator[parentLocation.length + 1]; {
location[0] = XProcException.getLocator(step);
for (int i = 0; i < parentLocation.length; i++)
location[i + 1] = parentLocation[i];
}
return location;
}
}