Search in sources :

Example 6 with XdmItem

use of net.sf.saxon.s9api.XdmItem in project nifi by apache.

the class EvaluateXQuery method onTrigger.

@Override
public void onTrigger(final ProcessContext context, final ProcessSession session) {
    final List<FlowFile> flowFileBatch = session.get(50);
    if (flowFileBatch.isEmpty()) {
        return;
    }
    final ComponentLog logger = getLogger();
    final Map<String, XQueryExecutable> attributeToXQueryMap = new HashMap<>();
    final Processor proc = new Processor(false);
    final XMLReader xmlReader;
    try {
        xmlReader = XMLReaderFactory.createXMLReader();
    } catch (SAXException e) {
        logger.error("Error while constructing XMLReader {}", new Object[] { e });
        throw new ProcessException(e.getMessage());
    }
    if (!context.getProperty(VALIDATE_DTD).asBoolean()) {
        xmlReader.setEntityResolver(new EntityResolver() {

            @Override
            public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
                return new InputSource(new StringReader(""));
            }
        });
    }
    final XQueryCompiler comp = proc.newXQueryCompiler();
    for (final Map.Entry<PropertyDescriptor, String> entry : context.getProperties().entrySet()) {
        if (!entry.getKey().isDynamic()) {
            continue;
        }
        final XQueryExecutable exp;
        try {
            exp = comp.compile(entry.getValue());
            attributeToXQueryMap.put(entry.getKey().getName(), exp);
        } catch (SaxonApiException e) {
            // should not happen because we've already validated the XQuery (in XQueryValidator)
            throw new ProcessException(e);
        }
    }
    final XQueryExecutable slashExpression;
    try {
        slashExpression = comp.compile("/");
    } catch (SaxonApiException e) {
        logger.error("unable to compile XQuery expression due to {}", new Object[] { e });
        session.transfer(flowFileBatch, REL_FAILURE);
        return;
    }
    final String destination = context.getProperty(DESTINATION).getValue();
    flowFileLoop: for (FlowFile flowFile : flowFileBatch) {
        if (!isScheduled()) {
            session.rollback();
            return;
        }
        final AtomicReference<Throwable> error = new AtomicReference<>(null);
        final AtomicReference<XdmNode> sourceRef = new AtomicReference<>(null);
        session.read(flowFile, new InputStreamCallback() {

            @Override
            public void process(final InputStream rawIn) throws IOException {
                try (final InputStream in = new BufferedInputStream(rawIn)) {
                    XQueryEvaluator qe = slashExpression.load();
                    qe.setSource(new SAXSource(xmlReader, new InputSource(in)));
                    DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
                    dfactory.setNamespaceAware(true);
                    Document dom = dfactory.newDocumentBuilder().newDocument();
                    qe.run(new DOMDestination(dom));
                    XdmNode rootNode = proc.newDocumentBuilder().wrap(dom);
                    sourceRef.set(rootNode);
                } catch (final Exception e) {
                    error.set(e);
                }
            }
        });
        if (error.get() != null) {
            logger.error("unable to evaluate XQuery against {} due to {}; routing to 'failure'", new Object[] { flowFile, error.get() });
            session.transfer(flowFile, REL_FAILURE);
            continue;
        }
        final Map<String, String> xQueryResults = new HashMap<>();
        List<FlowFile> childrenFlowFiles = new ArrayList<>();
        for (final Map.Entry<String, XQueryExecutable> entry : attributeToXQueryMap.entrySet()) {
            try {
                XQueryEvaluator qe = entry.getValue().load();
                qe.setContextItem(sourceRef.get());
                XdmValue result = qe.evaluate();
                if (DESTINATION_ATTRIBUTE.equals(destination)) {
                    int index = 1;
                    for (XdmItem item : result) {
                        String value = formatItem(item, context);
                        String attributeName = entry.getKey();
                        if (result.size() > 1) {
                            attributeName += "." + index++;
                        }
                        xQueryResults.put(attributeName, value);
                    }
                } else {
                    // if (DESTINATION_CONTENT.equals(destination)){
                    if (result.size() == 0) {
                        logger.info("Routing {} to 'unmatched'", new Object[] { flowFile });
                        session.transfer(flowFile, REL_NO_MATCH);
                        continue flowFileLoop;
                    } else if (result.size() == 1) {
                        final XdmItem item = result.itemAt(0);
                        flowFile = session.write(flowFile, new OutputStreamCallback() {

                            @Override
                            public void process(final OutputStream rawOut) throws IOException {
                                try (final OutputStream out = new BufferedOutputStream(rawOut)) {
                                    writeformattedItem(item, context, out);
                                } catch (TransformerFactoryConfigurationError | TransformerException e) {
                                    throw new IOException(e);
                                }
                            }
                        });
                    } else {
                        for (final XdmItem item : result) {
                            FlowFile ff = session.clone(flowFile);
                            ff = session.write(ff, new OutputStreamCallback() {

                                @Override
                                public void process(final OutputStream rawOut) throws IOException {
                                    try (final OutputStream out = new BufferedOutputStream(rawOut)) {
                                        try {
                                            writeformattedItem(item, context, out);
                                        } catch (TransformerFactoryConfigurationError | TransformerException e) {
                                            throw new IOException(e);
                                        }
                                    }
                                }
                            });
                            childrenFlowFiles.add(ff);
                        }
                    }
                }
            } catch (final SaxonApiException e) {
                logger.error("failed to evaluate XQuery for {} for Property {} due to {}; routing to failure", new Object[] { flowFile, entry.getKey(), e });
                session.transfer(flowFile, REL_FAILURE);
                session.remove(childrenFlowFiles);
                continue flowFileLoop;
            } catch (TransformerFactoryConfigurationError | TransformerException | IOException e) {
                logger.error("Failed to write XQuery result for {} due to {}; routing original to 'failure'", new Object[] { flowFile, error.get() });
                session.transfer(flowFile, REL_FAILURE);
                session.remove(childrenFlowFiles);
                continue flowFileLoop;
            }
        }
        if (DESTINATION_ATTRIBUTE.equals(destination)) {
            flowFile = session.putAllAttributes(flowFile, xQueryResults);
            final Relationship destRel = xQueryResults.isEmpty() ? REL_NO_MATCH : REL_MATCH;
            logger.info("Successfully evaluated XQueries against {} and found {} matches; routing to {}", new Object[] { flowFile, xQueryResults.size(), destRel.getName() });
            session.transfer(flowFile, destRel);
            session.getProvenanceReporter().modifyAttributes(flowFile);
        } else {
            // if (DESTINATION_CONTENT.equals(destination)) {
            if (!childrenFlowFiles.isEmpty()) {
                logger.info("Successfully created {} new FlowFiles from {}; routing all to 'matched'", new Object[] { childrenFlowFiles.size(), flowFile });
                session.transfer(childrenFlowFiles, REL_MATCH);
                session.remove(flowFile);
            } else {
                logger.info("Successfully updated content for {}; routing to 'matched'", new Object[] { flowFile });
                session.transfer(flowFile, REL_MATCH);
                session.getProvenanceReporter().modifyContent(flowFile);
            }
        }
    }
// end flowFileLoop
}
Also used : InputSource(org.xml.sax.InputSource) Processor(net.sf.saxon.s9api.Processor) AbstractProcessor(org.apache.nifi.processor.AbstractProcessor) DocumentBuilderFactory(javax.xml.parsers.DocumentBuilderFactory) HashMap(java.util.HashMap) XQueryCompiler(net.sf.saxon.s9api.XQueryCompiler) BufferedOutputStream(org.apache.nifi.stream.io.BufferedOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) OutputStream(java.io.OutputStream) Document(org.w3c.dom.Document) SAXException(org.xml.sax.SAXException) XdmValue(net.sf.saxon.s9api.XdmValue) BufferedInputStream(org.apache.nifi.stream.io.BufferedInputStream) StringReader(java.io.StringReader) List(java.util.List) ArrayList(java.util.ArrayList) OutputStreamCallback(org.apache.nifi.processor.io.OutputStreamCallback) BufferedOutputStream(org.apache.nifi.stream.io.BufferedOutputStream) XMLReader(org.xml.sax.XMLReader) TransformerException(javax.xml.transform.TransformerException) TransformerFactoryConfigurationError(javax.xml.transform.TransformerFactoryConfigurationError) FlowFile(org.apache.nifi.flowfile.FlowFile) PropertyDescriptor(org.apache.nifi.components.PropertyDescriptor) BufferedInputStream(org.apache.nifi.stream.io.BufferedInputStream) InputStream(java.io.InputStream) AtomicReference(java.util.concurrent.atomic.AtomicReference) EntityResolver(org.xml.sax.EntityResolver) IOException(java.io.IOException) ComponentLog(org.apache.nifi.logging.ComponentLog) SaxonApiException(net.sf.saxon.s9api.SaxonApiException) XdmNode(net.sf.saxon.s9api.XdmNode) SAXException(org.xml.sax.SAXException) TransformerException(javax.xml.transform.TransformerException) ProcessException(org.apache.nifi.processor.exception.ProcessException) SaxonApiException(net.sf.saxon.s9api.SaxonApiException) TransformerConfigurationException(javax.xml.transform.TransformerConfigurationException) IOException(java.io.IOException) XQueryExecutable(net.sf.saxon.s9api.XQueryExecutable) ProcessException(org.apache.nifi.processor.exception.ProcessException) SAXSource(javax.xml.transform.sax.SAXSource) Relationship(org.apache.nifi.processor.Relationship) InputStreamCallback(org.apache.nifi.processor.io.InputStreamCallback) DOMDestination(net.sf.saxon.s9api.DOMDestination) Map(java.util.Map) HashMap(java.util.HashMap) XQueryEvaluator(net.sf.saxon.s9api.XQueryEvaluator) XdmItem(net.sf.saxon.s9api.XdmItem)

Example 7 with XdmItem

use of net.sf.saxon.s9api.XdmItem in project sirix by sirixdb.

the class TestNodeWrapperS9ApiXPath method testB1.

@Test
public void testB1() throws Exception {
    final XPathSelector selector = new XPathEvaluator.Builder("//b[1]", mHolder.getSession()).build().call();
    final StringBuilder strBuilder = new StringBuilder();
    for (final XdmItem item : selector) {
        strBuilder.append(item.toString());
    }
    assertXMLEqual("expected pieces to be similar", "<b xmlns:p=\"ns\">foo<c xmlns:p=\"ns\"/></b>", strBuilder.toString());
}
Also used : XPathSelector(net.sf.saxon.s9api.XPathSelector) XdmItem(net.sf.saxon.s9api.XdmItem) Test(org.junit.Test)

Example 8 with XdmItem

use of net.sf.saxon.s9api.XdmItem in project sirix by sirixdb.

the class TestNodeWrapperS9ApiXPath method testB2Text.

@Test
public void testB2Text() throws Exception {
    final XPathSelector selector = new XPathEvaluator.Builder("//b[2]/text()", mHolder.getSession()).build().call();
    final StringBuilder strBuilder = new StringBuilder();
    for (final XdmItem item : selector) {
        strBuilder.append(item.toString());
    }
    assertEquals("bar", strBuilder.toString());
}
Also used : XPathSelector(net.sf.saxon.s9api.XPathSelector) XdmItem(net.sf.saxon.s9api.XdmItem) Test(org.junit.Test)

Example 9 with XdmItem

use of net.sf.saxon.s9api.XdmItem in project sirix by sirixdb.

the class TestNodeWrapperS9ApiXPath method testB1String.

@Test
public void testB1String() throws Exception {
    final XPathSelector selector = new XPathEvaluator.Builder("//b[1]/text()", mHolder.getSession()).build().call();
    final StringBuilder strBuilder = new StringBuilder();
    for (final XdmItem item : selector) {
        strBuilder.append(item.toString());
    }
    assertEquals("foo", strBuilder.toString());
}
Also used : XPathSelector(net.sf.saxon.s9api.XPathSelector) XdmItem(net.sf.saxon.s9api.XdmItem) Test(org.junit.Test)

Example 10 with XdmItem

use of net.sf.saxon.s9api.XdmItem in project sirix by sirixdb.

the class TestNodeWrapperS9ApiXQuery method testWhereBooks.

@Test
public void testWhereBooks() throws Exception {
    final XdmValue value = new XQueryEvaluator("for $x in /bookstore/book where $x/price>30 return $x/title", mHolder.getSession()).call();
    final StringBuilder strBuilder = new StringBuilder();
    for (final XdmItem item : value) {
        strBuilder.append(item.toString());
    }
    assertEquals("<title lang=\"en\">XQuery Kick Start</title><title lang=\"en\">Learning XML</title>", strBuilder.toString());
}
Also used : XdmValue(net.sf.saxon.s9api.XdmValue) XQueryEvaluator(org.sirix.saxon.evaluator.XQueryEvaluator) XdmItem(net.sf.saxon.s9api.XdmItem) Test(org.junit.Test)

Aggregations

XdmItem (net.sf.saxon.s9api.XdmItem)14 XPathSelector (net.sf.saxon.s9api.XPathSelector)9 Test (org.junit.Test)9 XdmValue (net.sf.saxon.s9api.XdmValue)6 StringReader (java.io.StringReader)3 Processor (net.sf.saxon.s9api.Processor)3 SaxonApiException (net.sf.saxon.s9api.SaxonApiException)3 XdmNode (net.sf.saxon.s9api.XdmNode)3 XQueryEvaluator (org.sirix.saxon.evaluator.XQueryEvaluator)3 IOException (java.io.IOException)2 TransformerException (javax.xml.transform.TransformerException)2 SAXSource (javax.xml.transform.sax.SAXSource)2 XPathCompiler (net.sf.saxon.s9api.XPathCompiler)2 XPathExecutable (net.sf.saxon.s9api.XPathExecutable)2 InputSource (org.xml.sax.InputSource)2 SAXException (org.xml.sax.SAXException)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 InputStream (java.io.InputStream)1 OutputStream (java.io.OutputStream)1 ArrayList (java.util.ArrayList)1