Skip to content
Permalink
Browse files

Attempt to work around issue #97 by dealing with exceptions that aren…

…'t caught by the error listener; its better but could probably still be improved
  • Loading branch information
ndw committed Jul 30, 2013
1 parent 05ac4ad commit 1f1c05e380803713bb529cc2579914454ff1041c
@@ -40,6 +40,7 @@
import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;
import java.util.Stack;
import java.util.Vector;
import java.util.logging.Logger;

@@ -932,7 +933,11 @@ public void finest(XProcRunnable step, XdmNode node, String message) {

// ===========================================================

private Stack<XStep> runningSteps = new Stack<XStep>();

public void start(XStep step) {
runningSteps.push(step);

if (profile == null) {
return;
}
@@ -963,7 +968,13 @@ public void start(XStep step) {
profileWriter.startContent();
}

public XStep runningStep() {
return runningSteps.peek();
}

public void finish(XStep step) {
runningSteps.pop();

if (profile == null) {
return;
}
@@ -51,10 +51,8 @@ public void add(XdmNode document) {
if (closed) {
throw new XProcException("You can't add a document to a closed DocumentSequence.");
} else {
if (!S9apiUtils.isDocument(document)) {
throw XProcException.dynamicError(1);
}

S9apiUtils.assertDocument(document);

//runtime.finest(logger, null, "Wrote " + (document == null ? "null" : document.getBaseURI()) + " to " + toString());
documents.add(document);
if (outputlog != null) {
@@ -588,7 +588,9 @@ private void doPutOrPostSinglepart(HttpEntityEnclosingRequest method, XdmNode bo
} else if (xmlContentType(contentType)) {
Serializer serializer = makeSerializer();

if (!S9apiUtils.isDocumentContent(body.axisIterator(Axis.CHILD))) {
try {
S9apiUtils.assertDocumentContent(body.axisIterator(Axis.CHILD));
} catch (XProcException xe) {
throw XProcException.stepError(22);
}

@@ -6,10 +6,14 @@
import com.xmlcalabash.util.TreeWriter;
import com.xmlcalabash.io.WritablePipe;
import com.xmlcalabash.model.*;
import net.sf.saxon.om.StructuredQName;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.XdmNode;
import net.sf.saxon.s9api.QName;
import net.sf.saxon.trans.XPathException;

import javax.xml.transform.SourceLocator;
import javax.xml.transform.TransformerException;
import java.util.Vector;

/**
@@ -21,6 +25,11 @@
*/
public class XTry extends XCompoundStep {
private static final QName c_errors = new QName("c", XProcConstants.NS_XPROC_STEP, "errors");
private static final QName c_error = new QName("c", XProcConstants.NS_XPROC_STEP, "error");
private static QName _href = new QName("", "href");
private static QName _line = new QName("", "line");
private static QName _column = new QName("", "column");
private static QName _code = new QName("", "code");
private Vector<XdmNode> errors = new Vector<XdmNode> ();

public XTry(XProcRuntime runtime, Step step, XCompoundStep parent) {
@@ -92,12 +101,67 @@ public void run() throws SaxonApiException {
treeWriter.addStartElement(c_errors);
treeWriter.startContent();

boolean reported = false;
for (XdmNode doc : runtime.getXProcData().errors()) {
treeWriter.addSubtree(doc);
reported = true;
}

for (XdmNode doc : errors) {
treeWriter.addSubtree(doc);
reported = true;
}

if (!reported) {
// Hey, no one reported this exception. We better do it.
treeWriter.addStartElement(c_error);

String message = xe.getMessage();
StructuredQName qCode = null;

if (xe instanceof XPathException) {
XPathException xxx = (XPathException) xe;
qCode = xxx.getErrorCodeQName();

Throwable underlying = xe.getCause();
if (underlying != null) {
message = underlying.toString();
}
}

if (xe instanceof XProcException) {
XProcException xxx = (XProcException) xe;
QName code = xxx.getErrorCode();
qCode = new StructuredQName(code.getPrefix(), code.getNamespaceURI(), code.getLocalName());
message = xxx.getMessage();
Throwable underlying = xe.getCause();
if (underlying != null) {
message = underlying.getMessage();
}
}

if (qCode != null) {
treeWriter.addNamespace(qCode.getPrefix(), qCode.getNamespaceBinding().getURI());
treeWriter.addAttribute(_code, qCode.getDisplayName());
}

XStep step = runtime.runningStep();
if (step != null && step.getNode() != null) {
XdmNode node = step.getNode();
if (node.getBaseURI() != null) {
treeWriter.addAttribute(_href, node.getBaseURI().toString());
}
if (node.getLineNumber() > 0) {
treeWriter.addAttribute(_line, ""+node.getLineNumber());
}
if (node.getColumnNumber() > 0) {
treeWriter.addAttribute(_column, ""+node.getColumnNumber());
}
}

treeWriter.startContent();
treeWriter.addText(message);
treeWriter.addEndElement();
}

treeWriter.addEndElement();
@@ -382,42 +382,35 @@ public static boolean xpathSyntaxError(SaxonApiException sae) {
return (cause != null && cause instanceof XPathException);
}

public static
boolean isDocument(XdmNode doc) {
boolean ok = true;

public static void assertDocument(XdmNode doc) {
if (doc.getNodeKind() == XdmNodeKind.DOCUMENT) {
ok = S9apiUtils.isDocumentContent(doc.axisIterator(Axis.CHILD));
S9apiUtils.assertDocumentContent(doc.axisIterator(Axis.CHILD));
} else if (doc.getNodeKind() == XdmNodeKind.ELEMENT) {
// this is ok
} else {
ok = false;
throw XProcException.dynamicError(1, "Document root cannot be " + doc.getNodeKind());
}

return ok;
}

public static
boolean isDocumentContent(XdmSequenceIterator iter) {
boolean ok = true;

public static void assertDocumentContent(XdmSequenceIterator iter) {
int elemCount = 0;
while (ok && iter.hasNext()) {
while (iter.hasNext()) {
XdmNode child = (XdmNode) iter.next();
if (child.getNodeKind() == XdmNodeKind.ELEMENT) {
elemCount++;
ok = ok && elemCount == 1;
if (elemCount > 1) {
throw XProcException.dynamicError(1, "Document must have exactly one top-level element");
}
} else if (child.getNodeKind() == XdmNodeKind.PROCESSING_INSTRUCTION
|| child.getNodeKind() == XdmNodeKind.COMMENT) {
// that's ok
} else if (child.getNodeKind() == XdmNodeKind.TEXT) {
ok = ok && "".equals(child.getStringValue().trim());
if (!"".equals(child.getStringValue().trim()))
throw XProcException.dynamicError(1, "Only whitespace text nodes can appear at the top level in a document");
} else {
ok = false;
throw XProcException.dynamicError(1, "Document cannot have top level " + child.getNodeKind());
}
}

return ok;
}

// FIXME: This method exists only to work around a bug in SaxonHE 9.5.1.1

0 comments on commit 1f1c05e

Please sign in to comment.
You can’t perform that action at this time.