/* * Copyright 2013-2017 Grzegorz Ligas <[email protected]> and other contributors * (see the CONTRIBUTORS file). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.intellij.xquery.runner.rt.vendor.saxon; import net.sf.saxon.Configuration; import net.sf.saxon.query.QueryModule; import net.sf.saxon.s9api.ItemType; import net.sf.saxon.s9api.Processor; import net.sf.saxon.s9api.QName; import net.sf.saxon.s9api.Serializer; import net.sf.saxon.s9api.XQueryCompiler; import net.sf.saxon.s9api.XQueryEvaluator; import net.sf.saxon.s9api.XQueryExecutable; import net.sf.saxon.s9api.XdmAtomicValue; import net.sf.saxon.s9api.XdmItem; import net.sf.saxon.trans.XPathException; import org.intellij.xquery.runner.rt.FileUtil; import org.intellij.xquery.runner.rt.RunnerApp; import org.intellij.xquery.runner.rt.XQueryItemType; import org.intellij.xquery.runner.rt.XQueryRunConfig; import org.intellij.xquery.runner.rt.XQueryRunnerVariable; import org.w3c.dom.Document; import org.w3c.dom.Text; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.stream.StreamSource; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.PrintStream; public class SaxonRunnerApp implements RunnerApp { protected final XQueryRunConfig config; private final PrintStream output; private Processor processor; private SaxonTypeMapper typeMapper = new SaxonTypeMapper(); public SaxonRunnerApp(XQueryRunConfig config, PrintStream output) throws XPathException { this.config = config; this.output = output; setUpProcessor(config); } private void setUpProcessor(XQueryRunConfig config) throws XPathException { if (config.isConfigFileEnabled()) { Configuration configuration = getConfiguration(config); processor = new Processor(configuration); } else { processor = new Processor(false); } } private Configuration getConfiguration(XQueryRunConfig config) throws XPathException { File configFile = new File(config.getConfigFile()); return Configuration.readConfiguration(new StreamSource(configFile)); } @Override public void runApp() throws Exception { doAdditionalConfiguration(processor); Serializer out = prepareSerializer(); XQueryCompiler compiler = processor.newXQueryCompiler(); XQueryExecutable executable = compiler.compile(new File(config.getMainFile())); setMainModule(executable.getUnderlyingCompiledQuery().getMainModule()); XQueryEvaluator evaluator = executable.load(); bindContextItem(evaluator); bindVariables(evaluator); evaluator.run(out); } private Serializer prepareSerializer() { Serializer out = processor.newSerializer(output); out.setOutputProperty(Serializer.Property.METHOD, "xml"); out.setOutputProperty(Serializer.Property.OMIT_XML_DECLARATION, "yes"); return out; } private void bindContextItem(XQueryEvaluator evaluator) throws Exception { if (config.isContextItemEnabled()) { String contextItemValue = config.isContextItemFromEditorEnabled() ? config.getContextItemText() : readFile(config.getContextItemFile()); evaluator.setContextItem(getXdmValue(config.getContextItemType(), contextItemValue)); } } private void bindVariables(XQueryEvaluator evaluator) throws Exception { for (XQueryRunnerVariable variable : config.getVariables()) { if (variable.ACTIVE) { evaluator.setExternalVariable(getName(variable.NAME, variable.NAMESPACE), getXdmValue(variable.TYPE, variable.VALUE)); } } } private QName getName(String name, String namespace) { if (namespace != null) { return new QName(namespace, name); } else { return new QName(name); } } private XdmItem getXdmValue(String type, String value) throws Exception { XQueryItemType itemType = XQueryItemType.valueFor(type); if (itemType == XQueryItemType.TEXT) { Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); Text textNode = document.createTextNode(value); return processor.newDocumentBuilder().wrap(textNode); } else if (itemType == XQueryItemType.DOCUMENT) { Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(value.getBytes())); return processor.newDocumentBuilder().wrap(document); } else { ItemType mappedType = typeMapper.getType(itemType); return new XdmAtomicValue(value, mappedType); } } protected String readFile(String fileName) throws IOException { return FileUtil.readFile(fileName); } protected void doAdditionalConfiguration(Processor debugger) { } protected void setMainModule(QueryModule mainModule) { } }