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

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

The 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.Pipe;
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 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 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 _href = new QName("", "href");
    private static final QName _line = new QName("", "line");
    private static final QName _column = new QName("", "column");
    private static final QName _code = new QName("", "code");
    private boolean inCatch = false;
    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, "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);
                Pipe 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);
                Pipe wpipe = xoutput.getWriter();
                outputs.put(port, wpipe);
                logger.trace(MessageFormatter.nodeMessage(step.getNode(), " writes to " + wpipe + " for " + port));
            }
        }
    }

    protected void doRun() 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));
            }
        }

        XProcMessageListenerHelper.openStep(runtime, this);
        try {
            xgroup.run();
        // FIXME: only catch DynamicXProcException
        // FIXME: also catch SaxonApiException ?
        // -> or stop throwing SaxonApiException (handle in steps)?
        } catch (XProcException xe) {
            
            logger.trace("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.
                xe.serialize(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));
                }
            }

            inCatch = true;
            xcatch.run();
        } finally {
            inCatch = false;
            runtime.getMessageListener().closeStep();
        }
    }

    public void reportError(XdmNode doc) {
        if (inCatch) {
            // if the error is coming from the catch group, report to parent
            super.reportError(doc);
        } else {
            errors.add(doc);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy