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

com.xmlcalabash.library.DefaultStep Maven / Gradle / Ivy

The newest version!
package com.xmlcalabash.library;

import com.xmlcalabash.io.ReadablePipe;
import com.xmlcalabash.io.WritablePipe;
import com.xmlcalabash.core.XProcException;
import com.xmlcalabash.core.XProcRuntime;
import com.xmlcalabash.core.XProcStep;
import com.xmlcalabash.core.XProcConstants;
import com.xmlcalabash.model.RuntimeValue;
import net.sf.saxon.s9api.*;
import net.sf.saxon.trans.XPathException;

import java.net.URI;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Iterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.xmlcalabash.runtime.XAtomicStep;
import com.xmlcalabash.util.S9apiUtils;

/**
 * Created by IntelliJ IDEA.
 * User: ndw
 * Date: Oct 8, 2008
 * Time: 7:46:15 AM
 * To change this template use File | Settings | File Templates.
 */
public class DefaultStep implements XProcStep {
    
    public static final QName _byte_order_mark = new QName("", "byte-order-mark");
    public static final QName _cdata_section_elements = new QName("", "cdata-section-elements");
    public static final QName _doctype_public = new QName("", "doctype-public");
    public static final QName _doctype_system = new QName("", "doctype-system");
    public static final QName _encoding = new QName("", "encoding");
    public static final QName _escape_uri_attributes = new QName("", "escape-uri-attributes");
    public static final QName _include_content_type = new QName("", "include-content-type");
    public static final QName _indent = new QName("", "indent");
    public static final QName _media_type = new QName("", "media-type");
    public static final QName _method = new QName("", "method");
    public static final QName _normalization_form = new QName("", "normalization-form");
    public static final QName _omit_xml_declaration = new QName("", "omit-xml-declaration");
    public static final QName _standalone = new QName("", "standalone");
    public static final QName _undeclare_prefixes = new QName("", "undeclare-prefixes");
    public static final QName _version = new QName("", "version");
    public static final QName cx_message = new QName(XProcConstants.NS_CALABASH_EX, "message");

    protected Logger logger = null;
    private Hashtable options = null;
    protected XProcRuntime runtime = null;
    protected XAtomicStep step = null;

    public DefaultStep(XProcRuntime runtime, XAtomicStep step) {
        this.runtime = runtime;
        this.step = step;

        Class impl = runtime.getConfiguration().implementations.get(step.getType());
        if (impl == null) {
            // We're headed for a world of hurt...
            logger = LoggerFactory.getLogger(DefaultStep.class);
        } else {
            logger = LoggerFactory.getLogger(impl);
        }
    }

    public XAtomicStep getStep() {
        return step;
    }

    public static boolean isAvailable() {
        return true;
    }

    public void setInput(String port, ReadablePipe pipe) {
        throw new XProcException("No inputs allowed.");
    }

    public void setOutput(String port, WritablePipe pipe) {
        throw new XProcException("No outputs allowed.");
    }

    public void setParameter(QName name, RuntimeValue value) {
        throw new XProcException("No parameters allowed.");
    }

    public void setParameter(String port, QName name, RuntimeValue value) {
        throw new XProcException("No parameters allowed on port '" + port + "'");
    }

    public void setOption(QName name, RuntimeValue value) {
        if (options == null) {
            options = new Hashtable ();
        }
        options.put(name,value);
    }

    public RuntimeValue getOption(QName name) {
        if (options != null && options.containsKey(name)) {
            return options.get(name);
        } else {
            return null;
        }
    }

    public String getOption(QName name, String defaultValue) {
        if (options == null || !options.containsKey(name)) {
            return defaultValue;
        }
        return options.get(name).getString();
    }

    public QName getOption(QName name, QName defaultValue) {
        if (options == null || !options.containsKey(name)) {
            return defaultValue;
        }
        return options.get(name).getQName();
    }

    public boolean getOption(QName name, boolean defaultValue) {
        if (options == null || !options.containsKey(name)) {
            return defaultValue;
        }
        return options.get(name).getBoolean();
    }

    public int getOption(QName name, int defaultValue) {
        if (options == null || !options.containsKey(name)) {
            return defaultValue;
        }
        return options.get(name).getInt();
    }

    public long getOption(QName name, long defaultValue) {
        if (options == null || !options.containsKey(name)) {
            return defaultValue;
        }
        return options.get(name).getLong();
    }

    public void reset() {
        throw new XProcException("XProcStep implementation must override reset().");
    }

    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 void run() throws SaxonApiException {
        run("");
    }

    public void run(String addnLog) {
        String type = null;
        if (XProcConstants.NS_XPROC.equals(step.getType().getNamespaceURI())) {
            type = step.getType().getLocalName();
        } else {
            type = step.getType().getClarkName();
        }
        logger.debug("Running " + type + " " + step.getName() + addnLog);
        String msg = step.getExtensionAttribute(cx_message);
        if (msg != null) {
            System.err.println("Message: " + msg);
        }
    }

    public Serializer makeSerializer() {
        Serializer serializer = runtime.getProcessor().newSerializer();

        // This is XML; default to UTF-8
        serializer.setOutputProperty(Serializer.Property.ENCODING, "UTF-8");

        if (options == null) {
            return serializer;
        }

        if (options.containsKey(_byte_order_mark)) {
            serializer.setOutputProperty(Serializer.Property.BYTE_ORDER_MARK, getOption(_byte_order_mark, false) ? "yes" : "no");
        }

        if (options.containsKey(_cdata_section_elements)) {
            String list = getOption(_cdata_section_elements).getString();

            // FIXME: Why is list="" sometimes?
            if (!"".equals(list)) {
                String[] names = list.split("\\s+");
                list = "";
                for (String name : names) {
                    QName q = new QName(name, step.getNode());
                    list += q.getClarkName() + " ";
                }

                serializer.setOutputProperty(Serializer.Property.CDATA_SECTION_ELEMENTS, list);
            }
        }

        if (options.containsKey(_doctype_public)) {
            serializer.setOutputProperty(Serializer.Property.DOCTYPE_PUBLIC, getOption(_doctype_public).getString());
        }

        if (options.containsKey(_doctype_system)) {
            serializer.setOutputProperty(Serializer.Property.DOCTYPE_SYSTEM, getOption(_doctype_system).getString());
        }

        if (options.containsKey(_encoding)) {
            serializer.setOutputProperty(Serializer.Property.ENCODING, getOption(_encoding).getString());
        }

        if (options.containsKey(_escape_uri_attributes)) {
            serializer.setOutputProperty(Serializer.Property.ESCAPE_URI_ATTRIBUTES, getOption(_escape_uri_attributes, true) ? "yes" : "no");
        }

        if (options.containsKey(_include_content_type)) {
            serializer.setOutputProperty(Serializer.Property.INCLUDE_CONTENT_TYPE, getOption(_include_content_type, true) ? "yes" : "no");
        }

        if (options.containsKey(_indent)) {
            serializer.setOutputProperty(Serializer.Property.INDENT, getOption(_indent, true) ? "yes" : "no");
        }

        if (options.containsKey(_media_type)) {
            serializer.setOutputProperty(Serializer.Property.MEDIA_TYPE, getOption(_media_type).getString());
        }

        if (options.containsKey(_method)) {
            serializer.setOutputProperty(Serializer.Property.METHOD, getOption(_method).getString());
        }

        if (options.containsKey(_normalization_form)) {
            serializer.setOutputProperty(Serializer.Property.NORMALIZATION_FORM, getOption(_normalization_form).getString());
        }

        if (options.containsKey(_omit_xml_declaration)) {
           serializer.setOutputProperty(Serializer.Property.OMIT_XML_DECLARATION, getOption(_omit_xml_declaration, true) ? "yes" : "no");
        }

        if (options.containsKey(_standalone)) {
            String standalone = getOption(_standalone).getString();
            if ("true".equals(standalone)) {
                serializer.setOutputProperty(Serializer.Property.STANDALONE, "yes");
            } else if ("false".equals(standalone)) {
                serializer.setOutputProperty(Serializer.Property.STANDALONE, "no");
            }
            // What about omit?
        }

        if (options.containsKey(_undeclare_prefixes)) {
            serializer.setOutputProperty(Serializer.Property.UNDECLARE_PREFIXES, getOption(_undeclare_prefixes, true) ? "yes" : "no");
        }

        if (options.containsKey(_version)) {
            serializer.setOutputProperty(Serializer.Property.VERSION, getOption(_version).getString());
        }

        return serializer;
    }

    public Vector evaluateXPath(XdmNode doc, Hashtable nsBindings, String xpath, Hashtable globals) {
        Vector results = new Vector ();

        try {
            XPathCompiler xcomp = runtime.getProcessor().newXPathCompiler();
            URI baseURI = step.getNode().getBaseURI();
            if (!"".equals(baseURI.toASCIIString())) {
                xcomp.setBaseURI(baseURI);
            }

            // Extension functions are not available here...

            for (QName varname : globals.keySet()) {
                xcomp.declareVariable(varname);
            }

            for (String prefix : nsBindings.keySet()) {
                xcomp.declareNamespace(prefix, nsBindings.get(prefix));
            }
            XPathExecutable xexec = null;
            try {
                xexec = xcomp.compile(xpath);
            } catch (SaxonApiException sae) {
                Throwable t = sae.getCause();
                if (t instanceof XPathException) {
                    XPathException xe = (XPathException) t;
                    if (xe.getMessage().contains("Undeclared variable")) {
                        throw XProcException.dynamicError(26, xe.getMessage());
                    }
                }
                throw sae;
            }

            XPathSelector selector = xexec.load();

            for (QName varname : globals.keySet()) {
                XdmAtomicValue avalue = globals.get(varname).getUntypedAtomic(runtime);
                selector.setVariable(varname,avalue);
            }

            if (doc != null) {
                selector.setContextItem(doc);
            }

            try {
                Iterator values = selector.iterator();
                while (values.hasNext()) {
                    results.add(values.next());
                }
            } catch (SaxonApiUncheckedException saue) {
                Throwable sae = saue.getCause();
                if (sae instanceof XPathException) {
                    XPathException xe = (XPathException) sae;
                    if ("http://www.w3.org/2005/xqt-errors".equals(xe.getErrorCodeNamespace()) && "XPDY0002".equals(xe.getErrorCodeLocalPart())) {
                        throw XProcException.dynamicError(26,"Expression refers to context when none is available: " + xpath);
                    } else {
                        throw saue;
                    }

                } else {
                    throw saue;
                }
            }
        } catch (SaxonApiException sae) {
            if (S9apiUtils.xpathSyntaxError(sae)) {
                throw XProcException.dynamicError(23, "Invalid XPath expression: '" + xpath + "'.");
            } else {
                throw new XProcException(sae);
            }
        }

        return results;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy