Package com.xmlcalabash.runtime

Source Code of com.xmlcalabash.runtime.XPipeline

package com.xmlcalabash.runtime;

import com.xmlcalabash.core.XProcConstants;
import com.xmlcalabash.core.XProcData;
import com.xmlcalabash.core.XProcException;
import com.xmlcalabash.core.XProcRuntime;
import com.xmlcalabash.io.WritablePipe;
import com.xmlcalabash.io.ReadablePipe;
import com.xmlcalabash.model.DeclareStep;
import com.xmlcalabash.model.Option;
import com.xmlcalabash.model.Output;
import com.xmlcalabash.model.RuntimeValue;
import com.xmlcalabash.model.Serialization;
import com.xmlcalabash.model.Step;
import com.xmlcalabash.model.Variable;
import com.xmlcalabash.util.MessageFormatter;
import com.xmlcalabash.util.TreeWriter;
import net.sf.saxon.s9api.QName;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.XdmNode;

import java.util.*;

/**
* Created by IntelliJ IDEA.
* User: ndw
* Date: Oct 10, 2008
* Time: 7:22:01 AM
* To change this template use File | Settings | File Templates.
*/
public class XPipeline extends XCompoundStep {
    private static final QName c_param_set = new QName("c", XProcConstants.NS_XPROC_STEP, "param-set");
    private static final QName c_param = new QName("c", XProcConstants.NS_XPROC_STEP, "param");
    private static final QName _name = new QName("name");
    private static final QName _namespace = new QName("namespace");
    private static final QName _value = new QName("value");

    private Hashtable<QName, RuntimeValue> optionsPassedIn = null;

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

    public DeclareStep getDeclareStep() {
        return step.getDeclaration();
    }

    public void passOption(QName name, RuntimeValue value) {
        if (optionsPassedIn == null) {
            optionsPassedIn = new Hashtable<QName,RuntimeValue> ();
        }
        optionsPassedIn.put(name,value);
    }

    public Hashtable<QName,RuntimeValue> getInScopeOptions() {
        // We make a copy so that what our children do can't effect us
        Hashtable<QName,RuntimeValue> globals = new Hashtable<QName,RuntimeValue> ();
        if (inScopeOptions != null) {
            for (QName name : inScopeOptions.keySet()) {
                globals.put(name,inScopeOptions.get(name));
            }
        }

        // We also need to pass through any options passed in...
        if (optionsPassedIn != null) {
            for (QName name : optionsPassedIn.keySet()) {
                globals.put(name,optionsPassedIn.get(name));
            }
        }

        return globals;
    }

    public Set<String> getInputs() {
        HashSet<String> ports = new HashSet<String> ();
        for (String port : inputs.keySet()) {
            if (!port.startsWith("|")) {
                ports.add(port);
            }
        }
        return ports;
    }

    public void clearInputs(String port) {
        Vector<ReadablePipe> v = inputs.get(port);
        v.clear();
    }

    public void writeTo(String port, XdmNode node) {
        WritablePipe pipe = outputs.get(port+"|");
        logger.trace(MessageFormatter.nodeMessage(step.getNode(), "writesTo " + pipe + " for " + port));
        pipe.write(node);
    }

    public Set<String> getOutputs() {
        HashSet<String> ports = new HashSet<String> ();
        for (String port : outputs.keySet()) {
            if (!port.endsWith("|")) {
                ports.add(port);
            }
        }
        return ports;
    }

    public ReadablePipe readFrom(String port) {
        ReadablePipe rpipe = null;
        XOutput output = getOutput(port);
        rpipe = output.getReader();
        rpipe.canReadSequence(true); // FIXME: I should be able to set this correctly!
        return rpipe;
    }

    public Serialization getSerialization(String port) {
        Output output = step.getOutput(port);
        return output.getSerialization();
    }

    public void run() throws SaxonApiException {
        QName infoName = XProcConstants.p_pipeline;
        /*
        if (!step.isAnonymous()) {
            infoName = step.getDeclaredType();
        }
        */

        logger.trace("Running " + infoName + " " + step.getName());
        if (runtime.getAllowGeneralExpressions()) {
            logger.trace(MessageFormatter.nodeMessage(step.getNode(), "Running with the 'general-values' extension enabled."));
        }

        XProcData data = runtime.getXProcData();
        data.openFrame(this);

        runtime.start(this);
        try {
            doRun();
        } catch (XProcException ex) {
            runtime.error(ex);
            throw ex;
        } catch (SaxonApiException ex) {
            runtime.error(ex);
            throw ex;
        } finally {
            runtime.finish(this);
            data.closeFrame();
        }
    }

    private void setupParameters() {
        Vector<String> ports = new Vector<String> ();
        Iterator<String> portIter = getParameterPorts().iterator();
        while (portIter.hasNext()) {
            ports.add(portIter.next());
        }

        for (String port : ports) {
            TreeWriter tree = new TreeWriter(runtime);

            tree.startDocument(step.getNode().getBaseURI());
            tree.addStartElement(c_param_set);
            tree.startContent();

            Iterator<QName> paramIter = getParameters(port).iterator();
            while (paramIter.hasNext()) {
                QName name = paramIter.next();

                String value = getParameter(port, name).getString();
                tree.addStartElement(c_param);
                tree.addAttribute(_name, name.getLocalName());
                if (name.getNamespaceURI() != null) {
                    tree.addAttribute(_namespace, name.getNamespaceURI());
                }
                tree.addAttribute(_value, value);
                tree.startContent();
                tree.addEndElement();
            }

            tree.addEndElement();
            tree.endDocument();

            writeTo(port,tree.getResult());
        }
    }

    private void doRun() throws SaxonApiException {
        for (String port : inputs.keySet()) {
            if (!port.startsWith("|")) {
                String wport = port + "|";
                WritablePipe pipe = outputs.get(wport);

                for (ReadablePipe reader : inputs.get(port)) {
                    while (reader.moreDocuments()) {
                        XdmNode doc = reader.read();
                        pipe.write(doc);
                        logger.trace(MessageFormatter.nodeMessage(step.getNode(), "Pipeline input copy from " + reader + " to " + pipe));
                    }
                }
            }
        }

        setupParameters();

        // 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
        inScopeOptions = parent.getInScopeOptions();
        for (QName name : step.getOptions()) {
            Option option = step.getOption(name);
            RuntimeValue value = null;
            if (optionsPassedIn != null && optionsPassedIn.containsKey(name)) {
                value = optionsPassedIn.get(name);
            } else {
                if (option.getRequired() && option.getSelect() == null) {
                    throw XProcException.staticError(18, option.getNode(), "No value provided for required option \"" + option.getName() + "\"");
                }

                if (option.getSelect() == null) {
                    value = new RuntimeValue();
                } else {
                    value = computeValue(option);
                }
            }

            setOption(name, value);
            inScopeOptions.put(name, value);
        }

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

        for (XStep step : subpipeline) {
            step.run();
        }

        for (String port : inputs.keySet()) {
            if (port.startsWith("|")) {
                String wport = port.substring(1);
                WritablePipe pipe = outputs.get(wport);
                try {
                    for (ReadablePipe reader : inputs.get(port)) {
                        // Check for the case where there are no documents, but a sequence is not allowed
                        if (!reader.moreDocuments() && !pipe.writeSequence()) {
                            throw XProcException.dynamicError(7);
                        }


                        while (reader.moreDocuments()) {
                            XdmNode doc = reader.read();
                            pipe.write(doc);
                            logger.trace(MessageFormatter.nodeMessage(step.getNode(), "Pipeline output copy from " + reader + " to " + pipe));
                        }
                    }
                } finally {
                    pipe.close(); // Indicate that we're done writing to it
                }
            }
        }
    }
}
TOP

Related Classes of com.xmlcalabash.runtime.XPipeline

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.