All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.xmlcalabash.runtime.XTry Maven / Gradle / Ivy

There is a newer version: 1.1.20-p16-98
Show newest version
package com.xmlcalabash.runtime;

import com.xmlcalabash.core.XProcRuntime;
import com.xmlcalabash.core.XProcConstants;
import com.xmlcalabash.core.XProcException;
import com.xmlcalabash.util.MessageFormatter;
import com.xmlcalabash.util.TreeWriter;
import com.xmlcalabash.util.XProcMessageListenerHelper;
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;

/**
 * Created by IntelliJ IDEA.
 * User: ndw
 * Date: Oct 13, 2008
 * Time: 7:40:35 PM
 * To change this template use File | Settings | File Templates.
 */
public class XTry extends XCompoundStep {
    private static final String NS_DAISY_PIPELINE_XPROC = "http://www.daisy.org/ns/pipeline/xproc";
    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 final QName px_location = new QName("px", NS_DAISY_PIPELINE_XPROC, "location");
    private static final QName px_file = new QName("px", NS_DAISY_PIPELINE_XPROC, "file");
    private static final QName px_cause = new QName("px", NS_DAISY_PIPELINE_XPROC, "cause");
    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 errors = new Vector ();

    public XTry(XProcRuntime runtime, Step step, XCompoundStep parent) {
          super(runtime, step, parent);
    }

    public void instantiate(Step step) {
        parent.addStep(this);

        DeclareStep decl = step.getDeclaration();

        for (Step substep : decl.subpipeline()) {
            if (XProcConstants.p_group.equals(substep.getType())) {
                XGroup newstep = new XGroup(runtime, substep, this);
                newstep.instantiate(substep);
            } else if (XProcConstants.p_catch.equals(substep.getType())) {
                XCatch newstep = new XCatch(runtime, substep, this);
                newstep.instantiate(substep);
            } else {
                throw new XProcException(step.getNode(), "This can't happen, can it? try contains something that isn't a group or a catch?");
            }
        }

        for (Output output : step.outputs()) {
            String port = output.getPort();
            if (port.endsWith("|")) {
                String rport = port.substring(0,port.length()-1);
                XInput xinput = getInput(rport);
                WritablePipe wpipe = xinput.getWriter();
                outputs.put(port, wpipe);
                logger.trace(MessageFormatter.nodeMessage(step.getNode(), " writes to " + wpipe + " for " + port));
            } else {
                XOutput xoutput = new XOutput(runtime, output);
                addOutput(xoutput);
                WritablePipe wpipe = xoutput.getWriter();
                outputs.put(port, wpipe);
                logger.trace(MessageFormatter.nodeMessage(step.getNode(), " writes to " + wpipe + " for " + port));
            }
        }
    }

    public void run() throws SaxonApiException {

        inScopeOptions = parent.getInScopeOptions();
        for (Variable var : step.getVariables()) {
            RuntimeValue value = computeValue(var);
            inScopeOptions.put(var.getName(), value);
        }

        XGroup xgroup = (XGroup) subpipeline.get(0);

        for (String port : inputs.keySet()) {
            if (!port.startsWith("|")) {
                xgroup.inputs.put(port, inputs.get(port));
            }
        }

        for (String port : outputs.keySet()) {
            if (!port.endsWith("|")) {
                xgroup.outputs.put(port, outputs.get(port));
            }
        }

        try {
            XProcMessageListenerHelper.openStep(runtime, this);
        } catch (Throwable e) {
            throw handleException(e);
        }
        try {
            xgroup.run();
        } catch (Exception xe) {
            
            logger.debug("p:try: caught error: " + xe.toString());
            logger.trace("", xe);
            
            TreeWriter treeWriter = new TreeWriter(runtime);
            treeWriter.startDocument(step.getNode().getBaseURI());
            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.
                serializeError(xe, runtime.runningStep(), treeWriter);
            }

            treeWriter.addEndElement();
            treeWriter.endDocument();

            XCatch xcatch = (XCatch) subpipeline.get(1);

            xcatch.writeError(treeWriter.getResult());

            for (String port : inputs.keySet()) {
                if (!port.startsWith("|")) {
                    xcatch.inputs.put(port, inputs.get(port));
                }
            }

            for (String port : outputs.keySet()) {
                if (!port.endsWith("|")) {
                    xcatch.outputs.put(port, outputs.get(port));
                }
            }

            xcatch.run();
        } finally {
            runtime.getMessageListener().closeStep();
        }
    }

    private static void serializeError(Throwable xe, XStep step, TreeWriter treeWriter) {
        treeWriter.addStartElement(c_error);

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

        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();
            if (code != null) {
                qCode = new StructuredQName(code.getPrefix(), code.getNamespaceURI(), code.getLocalName());
            }
            if (message == null) {
                Throwable underlying = xe.getCause();
                if (underlying != null && !(underlying instanceof XProcException)) {
                    message = underlying.getMessage();
                }
            }
        }

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

        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();
        
        if (message != null)
            treeWriter.addText(message);

        if (xe instanceof XProcException) {
            XProcException xxx = (XProcException) xe;
            treeWriter.addStartElement(px_location);
            treeWriter.startContent();
            for (SourceLocator l : xxx.getLocator()) {
                treeWriter.addStartElement(px_file);
                treeWriter.addAttribute(_href, l.getSystemId());
                int line = l.getLineNumber();
                if (line > 0)
                    treeWriter.addAttribute(_line, ""+line);
                treeWriter.addEndElement();
            }
            treeWriter.addEndElement();
            XProcException underlying = ((XProcException)xe).getXProcCause();
            if (underlying != null) {
                treeWriter.addStartElement(px_cause);
                treeWriter.startContent();
                serializeError(underlying, null, treeWriter);
                treeWriter.addEndElement();
            }
        }

        treeWriter.addEndElement();
    }

    public void reportError(XdmNode doc) {
        errors.add(doc);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy