Search in sources :

Example 16 with XQueryPool

use of org.exist.storage.XQueryPool in project exist by eXist-db.

the class XIncludeFilter method processXInclude.

/**
 * @param href     The resource to be xincluded
 * @param xpointer The xpointer
 * @return Optionally a ResourceError if it was not possible to retrieve the resource
 * to be xincluded
 * @throws SAXException              If a SAX processing error occurs
 */
protected Optional<ResourceError> processXInclude(final String href, String xpointer) throws SAXException {
    if (href == null) {
        throw new SAXException("No href attribute found in XInclude include element");
    }
    // save some settings
    DocumentImpl prevDoc = document;
    boolean createContainerElements = serializer.createContainerElements;
    serializer.createContainerElements = false;
    // The following comments are the basis for possible external documents
    XmldbURI docUri = null;
    try {
        docUri = XmldbURI.xmldbUriFor(href);
    /*
               if(!stylesheetUri.toCollectionPathURI().equals(stylesheetUri)) {
                   externalUri = stylesheetUri.getXmldbURI();
               }
               */
    } catch (final URISyntaxException e) {
    // could be an external URI!
    }
    // parse the href attribute
    LOG.debug("found href=\"{}\"", href);
    // String xpointer = null;
    // String docName = href;
    Map<String, String> params = null;
    DocumentImpl doc = null;
    org.exist.dom.memtree.DocumentImpl memtreeDoc = null;
    boolean xqueryDoc = false;
    if (docUri != null) {
        final String fragment = docUri.getFragment();
        if (!(fragment == null || fragment.length() == 0)) {
            throw new SAXException("Fragment identifiers must not be used in an xinclude href attribute. To specify an xpointer, use the xpointer attribute.");
        }
        // extract possible parameters in the URI
        params = null;
        final String paramStr = docUri.getQuery();
        if (paramStr != null) {
            params = processParameters(paramStr);
            // strip query part
            docUri = XmldbURI.create(docUri.getRawCollectionPath());
        }
        // Patch 1520454 start
        if (!docUri.isAbsolute() && document != null) {
            final String base = document.getCollection().getURI() + "/";
            final String child = "./" + docUri.toString();
            final URI baseUri = URI.create(base);
            final URI childUri = URI.create(child);
            final URI uri = baseUri.resolve(childUri);
            docUri = XmldbURI.create(uri);
        }
        // retrieve the document
        try {
            doc = serializer.broker.getResource(docUri, Permission.READ);
        } catch (final PermissionDeniedException e) {
            return Optional.of(new ResourceError("Permission denied to read XInclude'd resource", e));
        }
        /* Check if the document is a stored XQuery */
        if (doc != null && doc.getResourceType() == DocumentImpl.BINARY_FILE) {
            xqueryDoc = "application/xquery".equals(doc.getMimeType());
        }
    }
    // The document could not be found: check if it points to an external resource
    if (docUri == null || (doc == null && !docUri.isAbsolute())) {
        try {
            URI externalUri = new URI(href);
            final String scheme = externalUri.getScheme();
            // XQuery context.
            if (scheme == null && moduleLoadPath != null) {
                final String path = externalUri.getSchemeSpecificPart();
                Path f = Paths.get(path);
                if (!f.isAbsolute()) {
                    if (moduleLoadPath.startsWith(XmldbURI.XMLDB_URI_PREFIX)) {
                        final XmldbURI parentUri = XmldbURI.create(moduleLoadPath);
                        docUri = parentUri.append(path);
                        doc = (DocumentImpl) serializer.broker.getXMLResource(docUri);
                        if (doc != null && !doc.getPermissions().validate(serializer.broker.getCurrentSubject(), Permission.READ)) {
                            throw new PermissionDeniedException("Permission denied to read XInclude'd resource");
                        }
                    } else {
                        f = Paths.get(moduleLoadPath, path);
                        externalUri = f.toUri();
                    }
                }
            }
            if (doc == null) {
                final Either<ResourceError, org.exist.dom.memtree.DocumentImpl> external = parseExternal(externalUri);
                if (external.isLeft()) {
                    return Optional.of(external.left().get());
                } else {
                    memtreeDoc = external.right().get();
                }
            }
        } catch (final PermissionDeniedException e) {
            return Optional.of(new ResourceError("Permission denied on XInclude'd resource", e));
        } catch (final ParserConfigurationException | URISyntaxException e) {
            throw new SAXException("XInclude: failed to parse document at URI: " + href + ": " + e.getMessage(), e);
        }
    }
    /* if document has not been found and xpointer is
               * null, throw an exception. If xpointer != null
               * we retry below and interpret docName as
               * a collection.
               */
    if (doc == null && memtreeDoc == null && xpointer == null) {
        return Optional.of(new ResourceError("document " + docUri + " not found"));
    }
    if (xpointer == null && !xqueryDoc) {
        // no xpointer found - just serialize the doc
        if (memtreeDoc == null) {
            serializer.serializeToReceiver(doc, false);
        } else {
            serializer.serializeToReceiver(memtreeDoc, false);
        }
    } else {
        // process the xpointer or the stored XQuery
        Source source = null;
        final XQueryPool pool = serializer.broker.getBrokerPool().getXQueryPool();
        CompiledXQuery compiled = null;
        try {
            if (xpointer == null) {
                source = new DBSource(serializer.broker, (BinaryDocument) doc, true);
            } else {
                xpointer = checkNamespaces(xpointer);
                source = new StringSource(xpointer);
            }
            final XQuery xquery = serializer.broker.getBrokerPool().getXQueryService();
            XQueryContext context;
            compiled = pool.borrowCompiledXQuery(serializer.broker, source);
            if (compiled == null) {
                context = new XQueryContext(serializer.broker.getBrokerPool());
            } else {
                context = compiled.getContext();
                context.prepareForReuse();
            }
            context.declareNamespaces(namespaces);
            context.declareNamespace("xinclude", Namespaces.XINCLUDE_NS);
            // setup the http context if known
            if (serializer.httpContext != null) {
                context.setHttpContext(serializer.httpContext);
            }
            // TODO: change these to putting the XmldbURI in, but we need to warn users!
            if (document != null) {
                context.declareVariable("xinclude:current-doc", document.getFileURI().toString());
                context.declareVariable("xinclude:current-collection", document.getCollection().getURI().toString());
            }
            if (xpointer != null) {
                if (doc != null) {
                    context.setStaticallyKnownDocuments(new XmldbURI[] { doc.getURI() });
                } else if (docUri != null) {
                    context.setStaticallyKnownDocuments(new XmldbURI[] { docUri });
                }
            }
            // pass parameters as variables
            if (params != null) {
                for (final Map.Entry<String, String> entry : params.entrySet()) {
                    context.declareVariable(entry.getKey(), entry.getValue());
                }
            }
            if (compiled == null) {
                try {
                    compiled = xquery.compile(context, source, xpointer != null);
                } catch (final IOException e) {
                    throw new SAXException("I/O error while reading query for xinclude: " + e.getMessage(), e);
                }
            } else {
                compiled.getContext().updateContext(context);
                context.getWatchDog().reset();
            }
            LOG.info("xpointer query: {}", ExpressionDumper.dump((Expression) compiled));
            Sequence contextSeq = null;
            if (memtreeDoc != null) {
                contextSeq = memtreeDoc;
            }
            try {
                final Sequence seq = xquery.execute(serializer.broker, compiled, contextSeq);
                if (Type.subTypeOf(seq.getItemType(), Type.NODE)) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("xpointer found: {}", seq.getItemCount());
                    }
                    NodeValue node;
                    for (final SequenceIterator i = seq.iterate(); i.hasNext(); ) {
                        node = (NodeValue) i.nextItem();
                        serializer.serializeToReceiver(node, false);
                    }
                } else {
                    String val;
                    for (int i = 0; i < seq.getItemCount(); i++) {
                        val = seq.itemAt(i).getStringValue();
                        characters(val);
                    }
                }
            } finally {
                context.runCleanupTasks();
            }
        } catch (final XPathException | PermissionDeniedException e) {
            LOG.warn("xpointer error", e);
            throw new SAXException("Error while processing XInclude expression: " + e.getMessage(), e);
        } finally {
            if (compiled != null) {
                pool.returnCompiledXQuery(source, compiled);
            }
        }
    }
    // restore settings
    document = prevDoc;
    serializer.createContainerElements = createContainerElements;
    return Optional.empty();
}
Also used : NodeValue(org.exist.xquery.value.NodeValue) XPathException(org.exist.xquery.XPathException) XQuery(org.exist.xquery.XQuery) CompiledXQuery(org.exist.xquery.CompiledXQuery) URISyntaxException(java.net.URISyntaxException) DocumentImpl(org.exist.dom.persistent.DocumentImpl) URI(java.net.URI) XmldbURI(org.exist.xmldb.XmldbURI) StringSource(org.exist.source.StringSource) Source(org.exist.source.Source) DBSource(org.exist.source.DBSource) InputSource(org.xml.sax.InputSource) SAXException(org.xml.sax.SAXException) SequenceIterator(org.exist.xquery.value.SequenceIterator) DBSource(org.exist.source.DBSource) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) XmldbURI(org.exist.xmldb.XmldbURI) Path(java.nio.file.Path) CompiledXQuery(org.exist.xquery.CompiledXQuery) XQueryContext(org.exist.xquery.XQueryContext) IOException(java.io.IOException) Sequence(org.exist.xquery.value.Sequence) XQueryPool(org.exist.storage.XQueryPool) BinaryDocument(org.exist.dom.persistent.BinaryDocument) Expression(org.exist.xquery.Expression) PermissionDeniedException(org.exist.security.PermissionDeniedException) StringSource(org.exist.source.StringSource) Map(java.util.Map) HashMap(java.util.HashMap)

Example 17 with XQueryPool

use of org.exist.storage.XQueryPool in project exist by eXist-db.

the class ImportModuleTest method withCompiledQuery.

private <T> T withCompiledQuery(final DBBroker broker, final Source source, final Function2E<CompiledXQuery, T, XPathException, PermissionDeniedException> op) throws XPathException, PermissionDeniedException, IOException {
    final BrokerPool pool = broker.getBrokerPool();
    final XQuery xqueryService = pool.getXQueryService();
    final XQueryPool xqueryPool = pool.getXQueryPool();
    final CompiledXQuery compiledQuery = compileQuery(broker, xqueryService, xqueryPool, source);
    try {
        return op.apply(compiledQuery);
    } finally {
        if (compiledQuery != null) {
            xqueryPool.returnCompiledXQuery(source, compiledQuery);
        }
    }
}
Also used : XQueryPool(org.exist.storage.XQueryPool) BrokerPool(org.exist.storage.BrokerPool)

Example 18 with XQueryPool

use of org.exist.storage.XQueryPool in project exist by eXist-db.

the class EmbeddedBinariesTest method executeXQuery.

@Override
protected QueryResultAccessor<Sequence, IOException> executeXQuery(final String query) throws Exception {
    final Source source = new StringSource(query);
    final BrokerPool brokerPool = existEmbeddedServer.getBrokerPool();
    final XQueryPool pool = brokerPool.getXQueryPool();
    final XQuery xquery = brokerPool.getXQueryService();
    try (final DBBroker broker = brokerPool.get(Optional.of(brokerPool.getSecurityManager().getSystemSubject()))) {
        final CompiledXQuery existingCompiled = pool.borrowCompiledXQuery(broker, source);
        final XQueryContext context;
        final CompiledXQuery compiled;
        if (existingCompiled == null) {
            context = new XQueryContext(brokerPool);
            compiled = xquery.compile(context, source);
        } else {
            context = existingCompiled.getContext();
            context.prepareForReuse();
            compiled = existingCompiled;
        }
        final Sequence results = xquery.execute(broker, compiled, null);
        return consumer2E -> {
            try {
                // context.runCleanupTasks();  //TODO(AR) shows the ordering issue with binary values (see comment below)
                consumer2E.accept(results);
            } finally {
                // TODO(AR) performing #runCleanupTasks causes the stream to be closed, so if we do so before we are finished with the results, serialization fails.
                context.runCleanupTasks();
                pool.returnCompiledXQuery(source, compiled);
            }
        };
    }
}
Also used : XQueryPool(org.exist.storage.XQueryPool) Txn(org.exist.storage.txn.Txn) BrokerPool(org.exist.storage.BrokerPool) StringSource(org.exist.source.StringSource) ManagedCollectionLock(org.exist.storage.lock.ManagedCollectionLock) StringInputSource(org.exist.util.StringInputSource) org.exist.xquery.value(org.exist.xquery.value) IOException(java.io.IOException) ExistEmbeddedServer(org.exist.test.ExistEmbeddedServer) MimeType(org.exist.util.MimeType) Source(org.exist.source.Source) UnsynchronizedByteArrayOutputStream(org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream) DBBroker(org.exist.storage.DBBroker) Collection(org.exist.collections.Collection) XmldbURI(org.exist.xmldb.XmldbURI) Optional(java.util.Optional) XQueryPool(org.exist.storage.XQueryPool) Lock(org.exist.storage.lock.Lock) ClassRule(org.junit.ClassRule) DBBroker(org.exist.storage.DBBroker) StringSource(org.exist.source.StringSource) StringSource(org.exist.source.StringSource) StringInputSource(org.exist.util.StringInputSource) Source(org.exist.source.Source) BrokerPool(org.exist.storage.BrokerPool)

Example 19 with XQueryPool

use of org.exist.storage.XQueryPool in project exist by eXist-db.

the class XQueryTest method importExternalClasspathMainModule.

@Test
public void importExternalClasspathMainModule() throws EXistException, IOException, PermissionDeniedException, XPathException, QName.IllegalQNameException {
    final long timestamp = System.currentTimeMillis();
    final BrokerPool brokerPool = BrokerPool.getInstance();
    try (final DBBroker broker = brokerPool.getBroker()) {
        final org.exist.source.Source source = SourceFactory.getSource(broker, "/", "resource:org/exist/xquery/external-classpath-main-module.xq", false);
        final XQuery xquery = brokerPool.getXQueryService();
        final XQueryPool queryPool = brokerPool.getXQueryPool();
        CompiledXQuery compiled = null;
        XQueryContext context = null;
        try {
            compiled = queryPool.borrowCompiledXQuery(broker, source);
            if (compiled == null) {
                context = new XQueryContext(brokerPool);
            } else {
                context = compiled.getContext();
                context.prepareForReuse();
            }
            context.declareVariable(new QName("s"), new IntegerValue(timestamp));
            if (compiled == null) {
                compiled = xquery.compile(context, source);
            }
            final Sequence result = xquery.execute(broker, compiled, null, null);
            assertEquals(1, result.getItemCount());
            final Item item = result.itemAt(0);
            assertTrue(Type.subTypeOf(item.getType(), Type.NODE));
            final Source expected = Input.fromString("<echo>" + timestamp + "</echo>").build();
            final Source actual = Input.fromNode((Node) item).build();
            final Diff diff = DiffBuilder.compare(expected).withTest(actual).checkForSimilar().build();
            assertFalse(diff.toString(), diff.hasDifferences());
        } finally {
            if (compiled != null) {
                compiled.reset();
            }
            if (context != null) {
                context.reset();
            }
            if (compiled != null) {
                queryPool.returnCompiledXQuery(source, compiled);
            }
        }
    }
}
Also used : Diff(org.xmlunit.diff.Diff) DetailedDiff(org.custommonkey.xmlunit.DetailedDiff) QName(org.exist.dom.QName) IntegerValue(org.exist.xquery.value.IntegerValue) Node(org.w3c.dom.Node) XMLResource(org.xmldb.api.modules.XMLResource) EXistResource(org.exist.xmldb.EXistResource) Resource(org.xmldb.api.base.Resource) Sequence(org.exist.xquery.value.Sequence) Source(javax.xml.transform.Source) XQueryPool(org.exist.storage.XQueryPool) Item(org.exist.xquery.value.Item) DBBroker(org.exist.storage.DBBroker) BrokerPool(org.exist.storage.BrokerPool)

Example 20 with XQueryPool

use of org.exist.storage.XQueryPool in project exist by eXist-db.

the class Eval method execute.

private Sequence execute(final DBBroker broker, final XQuery xqueryService, final Source querySource, final XQueryContext innerContext, final Sequence exprContext, final boolean cache, @Nullable final Properties outputProperties) throws XPathException {
    CompiledXQuery compiled = null;
    final XQueryPool pool = broker.getBrokerPool().getXQueryPool();
    try {
        compiled = cache ? pool.borrowCompiledXQuery(broker, querySource) : null;
        if (compiled == null) {
            compiled = xqueryService.compile(innerContext, querySource);
        } else {
            compiled.getContext().updateContext(innerContext);
            compiled.getContext().prepareForReuse();
        }
        Sequence sequence = xqueryService.execute(broker, compiled, exprContext, outputProperties, false);
        ValueSequence newSeq = new ValueSequence();
        newSeq.keepUnOrdered(unordered);
        boolean hasSupplements = false;
        for (int i = 0; i < sequence.getItemCount(); i++) {
            // if (sequence.itemAt(i) instanceof StringValue) {
            if (Type.subTypeOf(sequence.itemAt(i).getType(), Type.STRING)) {
                newSeq.add(new StringValue(((StringValue) sequence.itemAt(i)).getStringValue(true)));
                hasSupplements = true;
            } else {
                newSeq.add(sequence.itemAt(i));
            }
        }
        if (hasSupplements) {
            sequence = newSeq;
        }
        return sequence;
    } catch (final IOException | PermissionDeniedException ioe) {
        throw new XPathException(this, ioe);
    } finally {
        if (compiled != null) {
            compiled.getContext().runCleanupTasks();
            if (cache) {
                pool.returnCompiledXQuery(querySource, compiled);
            } else {
                compiled.reset();
            }
        }
    }
}
Also used : XQueryPool(org.exist.storage.XQueryPool) PermissionDeniedException(org.exist.security.PermissionDeniedException) FunSubSequence(org.exist.xquery.functions.fn.FunSubSequence) IOException(java.io.IOException)

Aggregations

XQueryPool (org.exist.storage.XQueryPool)24 XQuery (org.exist.xquery.XQuery)15 CompiledXQuery (org.exist.xquery.CompiledXQuery)14 BrokerPool (org.exist.storage.BrokerPool)10 XQueryContext (org.exist.xquery.XQueryContext)10 Source (org.exist.source.Source)9 DBBroker (org.exist.storage.DBBroker)8 IOException (java.io.IOException)7 StringSource (org.exist.source.StringSource)7 DBSource (org.exist.source.DBSource)6 XmldbURI (org.exist.xmldb.XmldbURI)6 Sequence (org.exist.xquery.value.Sequence)6 EXistException (org.exist.EXistException)3 URLSource (org.exist.source.URLSource)3 InputSource (org.xml.sax.InputSource)3 Path (java.nio.file.Path)2 Optional (java.util.Optional)2 UnsynchronizedByteArrayOutputStream (org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream)2 Collection (org.exist.collections.Collection)2 BinaryDocument (org.exist.dom.persistent.BinaryDocument)2