Search in sources :

Example 11 with DBSource

use of org.exist.source.DBSource in project exist by eXist-db.

the class RpcConnection method executeT.

@Override
public Map<String, Object> executeT(final String pathToQuery, final Map<String, Object> parameters) throws EXistException, PermissionDeniedException {
    final long startTime = System.currentTimeMillis();
    final Optional<String> sortBy = Optional.ofNullable(parameters.get(RpcAPI.SORT_EXPR)).map(Object::toString);
    return this.<Map<String, Object>>readDocument(XmldbURI.createInternal(pathToQuery)).apply((document, broker, transaction) -> {
        final BinaryDocument xquery = (BinaryDocument) document;
        if (xquery.getResourceType() != DocumentImpl.BINARY_FILE) {
            throw new EXistException("Document " + pathToQuery + " is not a binary resource");
        }
        if (!xquery.getPermissions().validate(user, Permission.READ | Permission.EXECUTE)) {
            throw new PermissionDeniedException("Insufficient privileges to access resource");
        }
        final Source source = new DBSource(broker, xquery, true);
        try {
            final Map<String, Object> rpcResponse = this.<Map<String, Object>>compileQuery(broker, transaction, source, parameters).apply(compiledQuery -> queryResultToTypedRpcResponse(startTime, doQuery(broker, compiledQuery, null, parameters), sortBy));
            return rpcResponse;
        } catch (final XPathException e) {
            throw new EXistException(e);
        }
    });
}
Also used : DBSource(org.exist.source.DBSource) PermissionDeniedException(org.exist.security.PermissionDeniedException) EXistException(org.exist.EXistException) StringSource(org.exist.source.StringSource) Source(org.exist.source.Source) DBSource(org.exist.source.DBSource) InputSource(org.xml.sax.InputSource)

Example 12 with DBSource

use of org.exist.source.DBSource 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 13 with DBSource

use of org.exist.source.DBSource in project exist by eXist-db.

the class XQueryTrigger method getScript.

private CompiledXQuery getScript(boolean isBefore, DBBroker broker, Txn transaction, XmldbURI src) throws TriggerException {
    // get the query
    final Source query = getQuerySource(broker);
    if (query == null) {
        return null;
    }
    // avoid infinite recursion by allowing just one trigger per thread
    if (isBefore && !TriggerStatePerThread.verifyUniqueTriggerPerThreadBeforePrepare(this, src)) {
        return null;
    } else if (!isBefore && !TriggerStatePerThread.verifyUniqueTriggerPerThreadBeforeFinish(this, src)) {
        return null;
    }
    TriggerStatePerThread.setTransaction(transaction);
    final XQueryContext context = new XQueryContext(broker.getBrokerPool());
    if (query instanceof DBSource) {
        context.setModuleLoadPath(XmldbURI.EMBEDDED_SERVER_URI_PREFIX + ((DBSource) query).getDocumentPath().removeLastSegment().toString());
    }
    CompiledXQuery compiledQuery;
    try {
        // compile the XQuery
        compiledQuery = service.compile(context, query);
        // declare user defined parameters as external variables
        for (Object o : userDefinedVariables.keySet()) {
            final String varName = (String) o;
            final String varValue = userDefinedVariables.getProperty(varName);
            context.declareVariable(bindingPrefix + varName, new StringValue(varValue));
        }
        // reset & prepareForExecution for execution
        compiledQuery.reset();
        context.getWatchDog().reset();
        // do any preparation before execution
        context.prepareForExecution();
        return compiledQuery;
    } catch (final XPathException | IOException | PermissionDeniedException e) {
        LOG.warn(e.getMessage(), e);
        TriggerStatePerThread.setTriggerRunningState(TriggerStatePerThread.NO_TRIGGER_RUNNING, this, null);
        TriggerStatePerThread.setTransaction(null);
        throw new TriggerException(PREPARE_EXCEPTION_MESSAGE, e);
    }
}
Also used : DBSource(org.exist.source.DBSource) PermissionDeniedException(org.exist.security.PermissionDeniedException) IOException(java.io.IOException) StringValue(org.exist.xquery.value.StringValue) StringSource(org.exist.source.StringSource) Source(org.exist.source.Source) DBSource(org.exist.source.DBSource)

Example 14 with DBSource

use of org.exist.source.DBSource in project exist by eXist-db.

the class XQueryContextAttributesTest method attributesOfMainModuleContextCleared.

@Test
public void attributesOfMainModuleContextCleared() throws EXistException, LockException, SAXException, PermissionDeniedException, IOException, XPathException {
    final BrokerPool brokerPool = existEmbeddedServer.getBrokerPool();
    try (final DBBroker broker = brokerPool.get(Optional.of(brokerPool.getSecurityManager().getSystemSubject()));
        final Txn transaction = brokerPool.getTransactionManager().beginTransaction()) {
        final XmldbURI mainQueryUri = XmldbURI.create("/db/query1.xq");
        final InputSource mainQuery = new StringInputSource("<not-important/>".getBytes(UTF_8));
        final DBSource mainQuerySource = storeQuery(broker, transaction, mainQueryUri, mainQuery);
        final XQueryContext escapedMainQueryContext = withCompiledQuery(broker, mainQuerySource, mainCompiledQuery -> {
            final XQueryContext mainQueryContext = mainCompiledQuery.getContext();
            mainQueryContext.setAttribute("attr1", "value1");
            mainQueryContext.setAttribute("attr2", "value2");
            // execute the query
            final Sequence result = executeQuery(broker, mainCompiledQuery);
            assertEquals(1, result.getItemCount());
            // intentionally escape the context from the lambda
            return mainQueryContext;
        });
        assertNull(escapedMainQueryContext.getAttribute("attr1"));
        assertNull(escapedMainQueryContext.getAttribute("attr2"));
        assertTrue(escapedMainQueryContext.attributes.isEmpty());
        transaction.commit();
    }
}
Also used : DBBroker(org.exist.storage.DBBroker) StringInputSource(org.exist.util.StringInputSource) InputSource(org.xml.sax.InputSource) StringInputSource(org.exist.util.StringInputSource) DBSource(org.exist.source.DBSource) Txn(org.exist.storage.txn.Txn) Sequence(org.exist.xquery.value.Sequence) BrokerPool(org.exist.storage.BrokerPool) XmldbURI(org.exist.xmldb.XmldbURI) Test(org.junit.Test)

Example 15 with DBSource

use of org.exist.source.DBSource in project exist by eXist-db.

the class XQueryContextAttributesTest method attributesOfLibraryModuleContextCleared.

@Test
public void attributesOfLibraryModuleContextCleared() throws EXistException, LockException, SAXException, PermissionDeniedException, IOException, XPathException {
    final BrokerPool brokerPool = existEmbeddedServer.getBrokerPool();
    try (final DBBroker broker = brokerPool.get(Optional.of(brokerPool.getSecurityManager().getSystemSubject()));
        final Txn transaction = brokerPool.getTransactionManager().beginTransaction()) {
        final XmldbURI libraryQueryUri = XmldbURI.create("/db/mod1.xqm");
        final InputSource libraryQuery = new StringInputSource(("module namespace mod1 = 'http://mod1';\n" + "declare function mod1:f1() { <not-important/> };").getBytes(UTF_8));
        storeQuery(broker, transaction, libraryQueryUri, libraryQuery);
        final XmldbURI mainQueryUri = XmldbURI.create("/db/query1.xq");
        final InputSource mainQuery = new StringInputSource(("import module namespace mod1 = 'http://mod1' at 'xmldb:exist://" + libraryQueryUri + "';\n" + "mod1:f1()").getBytes(UTF_8));
        final DBSource mainQuerySource = storeQuery(broker, transaction, mainQueryUri, mainQuery);
        final Tuple2<XQueryContext, ModuleContext> escapedContexts = withCompiledQuery(broker, mainQuerySource, mainCompiledQuery -> {
            final XQueryContext mainQueryContext = mainCompiledQuery.getContext();
            // get the context of the library module
            final Module[] libraryModules = mainQueryContext.getModules("http://mod1");
            assertEquals(1, libraryModules.length);
            assertTrue(libraryModules[0] instanceof ExternalModule);
            final ExternalModule libraryModule = (ExternalModule) libraryModules[0];
            final XQueryContext libraryQueryContext = libraryModule.getContext();
            assertTrue(libraryQueryContext instanceof ModuleContext);
            libraryQueryContext.setAttribute("attr1", "value1");
            libraryQueryContext.setAttribute("attr2", "value2");
            // execute the query
            final Sequence result = executeQuery(broker, mainCompiledQuery);
            assertEquals(1, result.getItemCount());
            // intentionally escape the contexts from the lambda
            return Tuple(mainQueryContext, (ModuleContext) libraryQueryContext);
        });
        final XQueryContext escapedMainQueryContext = escapedContexts._1;
        final ModuleContext escapedLibraryQueryContext = escapedContexts._2;
        assertTrue(escapedMainQueryContext != escapedLibraryQueryContext);
        assertNull(escapedMainQueryContext.getAttribute("attr1"));
        assertNull(escapedMainQueryContext.getAttribute("attr2"));
        assertTrue(escapedMainQueryContext.attributes.isEmpty());
        assertNull(escapedLibraryQueryContext.getAttribute("attr1"));
        assertNull(escapedLibraryQueryContext.getAttribute("attr2"));
        assertTrue(escapedLibraryQueryContext.attributes.isEmpty());
        transaction.commit();
    }
}
Also used : StringInputSource(org.exist.util.StringInputSource) InputSource(org.xml.sax.InputSource) Txn(org.exist.storage.txn.Txn) Sequence(org.exist.xquery.value.Sequence) DBBroker(org.exist.storage.DBBroker) StringInputSource(org.exist.util.StringInputSource) DBSource(org.exist.source.DBSource) BrokerPool(org.exist.storage.BrokerPool) XmldbURI(org.exist.xmldb.XmldbURI) Test(org.junit.Test)

Aggregations

DBSource (org.exist.source.DBSource)20 Source (org.exist.source.Source)12 XmldbURI (org.exist.xmldb.XmldbURI)10 PermissionDeniedException (org.exist.security.PermissionDeniedException)8 StringSource (org.exist.source.StringSource)8 InputSource (org.xml.sax.InputSource)8 IOException (java.io.IOException)7 BinaryDocument (org.exist.dom.persistent.BinaryDocument)6 LockedDocument (org.exist.dom.persistent.LockedDocument)5 Sequence (org.exist.xquery.value.Sequence)5 URISyntaxException (java.net.URISyntaxException)4 DocumentImpl (org.exist.dom.persistent.DocumentImpl)4 BrokerPool (org.exist.storage.BrokerPool)4 DBBroker (org.exist.storage.DBBroker)4 XQueryPool (org.exist.storage.XQueryPool)4 XQueryContext (org.exist.xquery.XQueryContext)4 Properties (java.util.Properties)3 EXistException (org.exist.EXistException)3 Subject (org.exist.security.Subject)3 FileSource (org.exist.source.FileSource)3