Package eu.musoft.eclipse.xpath.evaluation.plugin

Source Code of eu.musoft.eclipse.xpath.evaluation.plugin.XPathEvaluator

/**
* Copyright (c) 2011, Martin Uhlir
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * The name of the author may not be used to endorse or promote
*       products derived from this software without specific prior written
*       permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package eu.musoft.eclipse.xpath.evaluation.plugin;

import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.List;

import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import net.sf.saxon.s9api.DocumentBuilder;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.Serializer;
import net.sf.saxon.s9api.XPathCompiler;
import net.sf.saxon.s9api.XPathExecutable;
import net.sf.saxon.s9api.XPathSelector;
import net.sf.saxon.s9api.XdmAtomicValue;
import net.sf.saxon.s9api.XdmItem;
import net.sf.saxon.s9api.XdmNode;
import net.sf.saxon.s9api.XdmValue;
import net.sf.saxon.s9api.XsltExecutable;
import net.sf.saxon.s9api.XsltTransformer;
import eu.musoft.eclipse.xpath.evaluation.plugin.views.namespaces.Namespace;

/**
* This class performs evaluation of XPath expression against an XML document.
*/
public class XPathEvaluator {

  private static final Processor processor;

  private static final XsltExecutable xsltExec;
  private static final boolean isPrettyPrintEnabled;

  static {
    processor = new Processor(false);

    xsltExec = getXsltRuntime();
    isPrettyPrintEnabled = xsltExec != null;
  }

  /**
   * Evaluates XPath expression against provided XML.<br/>
   * </br>
   *
   * <i>Implementation details of XPath evaluation using Saxon are described at
   * http://www.saxonica.com/documentation/xpath-api/s9api-xpath.xml</i>
   *
   * @param xpath
   *          string representation of XPath expression
   * @param namespaces
   *          list of namespaces used in Xpath expression
   * @param xml
   *          string representation of XML document
   * @param isPrettyPrint
   *          indicates whether pretty print is enabled for current evaluation
   * @return a subset of elements from original XML document which satisfy
   *         provided XPath expression
   * @throws Exception
   *           is thrown, if either XPath could not be compiled or XML document
   *           could not be parsed properly or the XPath evaluation against the
   *           XML document fails
   */
  public static XdmValue evaluate(String xpath, List<Namespace> namespaces, String xml, boolean isPrettyPrint) throws Exception {
    Activator.logInfo("Evaluating XPath: " + xpath);
    Activator.logInfo("Against XML with length: " + ((xml == null) ? null : xml.length()));
    Activator.logInfo("Pretty print:" + isPrettyPrint);

    if (xpath == null)
      throw new IllegalArgumentException("xpath can not be null");
    if (xml == null)
      throw new IllegalArgumentException("xml can not be null");

    XPathExecutable exec = getXPathExecuatble(xpath, namespaces);
    XdmNode xdm = buildXdm(xml);
    return evaluate(exec, xdm);
  }

  private static XsltExecutable getXsltRuntime() {
    Activator.logInfo("Getting XSLT runtime");

    try {
      return processor.newXsltCompiler().compile(new StreamSource(Activator.loadFile("xslt/indent.xsl")));
    } catch (Exception e) {
      // unable to load XSLT runtime
      Activator.logError("Unable to load XSLT runtime", e);
      return null;
    }
  }

  private static XPathExecutable getXPathExecuatble(String xpath, List<Namespace> namespaces) throws SaxonApiException {
    Activator.logInfo("Getting XPath executable");

    XPathCompiler xpathCompiler = processor.newXPathCompiler();
    for (Namespace n: namespaces) {
      xpathCompiler.declareNamespace(n.getPrefix(), n.getURI());
    }
    return xpathCompiler.compile(xpath);
  }

  private static XdmNode buildXdm(String xml) throws SaxonApiException {
    Activator.logInfo("Building Xdm");
    DocumentBuilder builder = processor.newDocumentBuilder();
    Source source = new StreamSource(new StringReader(xml));
    return builder.build(source);
  }

  private static XdmValue evaluate(XPathExecutable exec, XdmNode xdm) throws SaxonApiException {
    Activator.logInfo("Evaluating XPath");
    XPathSelector selector = exec.load();
    selector.setContextItem(xdm);
    return selector.evaluate();
  }

  public static String transformResult(XdmValue xdm, boolean isPrettyPrint) throws Exception {
    Activator.logInfo("Transforming result");

    boolean isAtomicValue = xdm instanceof XdmAtomicValue;
    Activator.logInfo("Result atomic value: " + isAtomicValue);
   
    if (!isAtomicValue && isPrettyPrint && isPrettyPrintEnabled) {
      return prettyPrint(xdm);
    }

    StringBuilder sb = new StringBuilder();
    for (XdmItem item: xdm) {
      sb.append(item);
    }
    return sb.toString();
  }

  private static String prettyPrint(XdmValue xdm) throws Exception {
    Activator.logInfo("Pretty printing");

    Writer result = new StringWriter();
    XsltTransformer xsltTransformer = xsltExec.load();
    xsltTransformer.setDestination(new Serializer(result));

    for (XdmItem item: xdm) {
      if (item instanceof XdmNode) {
        xsltTransformer.setInitialContextNode((XdmNode) item);
        xsltTransformer.transform();
      }
    }

    return result.toString();
  }

}
TOP

Related Classes of eu.musoft.eclipse.xpath.evaluation.plugin.XPathEvaluator

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.