Search in sources :

Example 1 with FileSource

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

the class XQueryURLRewrite method findSourceFromFs.

private SourceInfo findSourceFromFs(final String basePath, final String[] components) {
    final String realPath = config.getServletContext().getRealPath(basePath);
    final Path baseDir = Paths.get(realPath);
    if (!Files.isDirectory(baseDir)) {
        LOG.warn("Base path for XQueryURLRewrite does not point to a directory");
        return null;
    }
    Path controllerFile = null;
    Path subDir = baseDir;
    for (final String component : components) {
        if (!component.isEmpty()) {
            subDir = subDir.resolve(component);
            if (Files.isDirectory(subDir)) {
                Path cf = subDir.resolve(XQUERY_CONTROLLER_FILENAME);
                if (!Files.isReadable(cf)) {
                    cf = subDir.resolve(LEGACY_XQUERY_CONTROLLER_FILENAME);
                }
                if (Files.isReadable(cf)) {
                    controllerFile = cf;
                }
            } else {
                break;
            }
        }
    }
    if (controllerFile == null) {
        Path cf = baseDir.resolve(XQUERY_CONTROLLER_FILENAME);
        if (!Files.isReadable(cf)) {
            cf = subDir.resolve(LEGACY_XQUERY_CONTROLLER_FILENAME);
        }
        if (Files.isReadable(cf)) {
            controllerFile = cf;
        }
    }
    if (controllerFile == null) {
        LOG.warn("XQueryURLRewrite controller could not be found");
        return null;
    }
    if (LOG.isTraceEnabled()) {
        LOG.trace("Found controller file: {}", controllerFile.toAbsolutePath());
    }
    final String parentPath = controllerFile.getParent().toAbsolutePath().toString();
    String controllerPath = parentPath.substring(baseDir.toAbsolutePath().toString().length());
    // replace windows path separators
    controllerPath = controllerPath.replace('\\', '/');
    return new SourceInfo(new FileSource(controllerFile, true), parentPath, controllerPath);
}
Also used : Path(java.nio.file.Path) FileSource(org.exist.source.FileSource)

Example 2 with FileSource

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

the class Eval method doEval.

private Sequence doEval(final XQueryContext evalContext, final Sequence contextSequence, final Sequence[] args) throws XPathException {
    if (evalContext.getProfiler().isEnabled()) {
        evalContext.getProfiler().start(this);
        evalContext.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
        if (contextSequence != null) {
            evalContext.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
        }
    }
    int argCount = 0;
    Sequence exprContext = null;
    if (isCalledAs(FS_EVAL_INLINE_NAME)) {
        // the current expression context
        exprContext = args[argCount++];
    }
    // get the query expression
    final Item expr = args[argCount++].itemAt(0);
    final Source querySource;
    if (Type.subTypeOf(expr.getType(), Type.ANY_URI)) {
        querySource = loadQueryFromURI(expr);
    } else {
        final String queryStr = expr.getStringValue();
        if (queryStr.trim().isEmpty()) {
            return new EmptySequence();
        }
        querySource = new StringSource(queryStr);
    }
    final NodeValue contextInit;
    if (isCalledAs(FS_EVAL_WITH_CONTEXT_NAME)) {
        // set the context initialization param for later use
        contextInit = (NodeValue) args[argCount++].itemAt(0);
    } else {
        contextInit = null;
    }
    // should the compiled query be cached?
    final boolean cache;
    if (isCalledAs(FS_EVAL_AND_SERIALIZE_NAME)) {
        cache = true;
    } else if (argCount < getArgumentCount()) {
        cache = ((BooleanValue) args[argCount++].itemAt(0)).effectiveBooleanValue();
    } else {
        cache = false;
    }
    // save some context properties
    evalContext.pushNamespaceContext();
    final LocalVariable mark = evalContext.markLocalVariables(false);
    // save the static document set of the current context, so it can be restored later
    final DocumentSet oldDocs = evalContext.getStaticDocs();
    if (exprContext != null) {
        evalContext.setStaticallyKnownDocuments(exprContext.getDocumentSet());
    }
    if (evalContext.isProfilingEnabled(2)) {
        evalContext.getProfiler().start(this, "eval: " + expr);
    }
    // fixme! - hook for debugger here /ljo
    final XQuery xqueryService = evalContext.getBroker().getBrokerPool().getXQueryService();
    final XQueryContext innerContext;
    final Sequence initContextSequence;
    if (contextInit != null) {
        // eval-with-context: initialize a new context
        innerContext = new XQueryContext(context.getBroker().getBrokerPool());
        initContextSequence = initContext(contextInit.getNode(), innerContext);
    } else {
        // use the existing outer context
        // TODO: check if copying the static context would be sufficient???
        innerContext = evalContext.copyContext();
        innerContext.setShared(true);
        // innerContext = context;
        initContextSequence = null;
    }
    // set module load path
    if (Type.subTypeOf(expr.getType(), Type.ANY_URI)) {
        String uri = null;
        if (querySource instanceof DBSource) {
            final XmldbURI documentPath = ((DBSource) querySource).getDocumentPath();
            uri = XmldbURI.EMBEDDED_SERVER_URI.append(documentPath).removeLastSegment().toString();
        } else if (querySource instanceof FileSource) {
            uri = ((FileSource) querySource).getPath().getParent().toString();
        }
        if (uri != null) {
            innerContext.setModuleLoadPath(uri);
        }
    }
    // bind external vars?
    if (isCalledAs(FS_EVAL_NAME) && getArgumentCount() >= 3) {
        final Sequence externalVars = args[argCount++];
        for (int i = 0; i < externalVars.getItemCount(); i++) {
            final Item varName = externalVars.itemAt(i);
            if (varName.getType() == Type.QNAME) {
                final Item varValue = externalVars.itemAt(++i);
                innerContext.declareVariable(((QNameValue) varName).getQName(), varValue);
            }
        }
    }
    // determine if original line/column number are passed on
    final boolean pass;
    if (isCalledAs(FS_EVAL_NAME) && getArgumentCount() == 4) {
        pass = args[3].itemAt(0).toJavaObject(Boolean.class);
    } else if (isCalledAs(FS_EVAL_WITH_CONTEXT_NAME) && getArgumentCount() == 5) {
        pass = args[4].itemAt(0).toJavaObject(Boolean.class);
    } else if (isCalledAs(FS_EVAL_INLINE_NAME) && getArgumentCount() == 4) {
        pass = args[3].itemAt(0).toJavaObject(Boolean.class);
    } else if (isCalledAs(FS_EVAL_AND_SERIALIZE_NAME) && getArgumentCount() == 5) {
        pass = args[4].itemAt(0).toJavaObject(Boolean.class);
    } else {
        // default
        pass = false;
    }
    // fixme! - hook for debugger here /ljo
    try {
        if (isCalledAs(FS_EVAL_WITH_CONTEXT_NAME) && getArgumentCount() >= 4) {
            final Item contextItem = args[argCount++].itemAt(0);
            if (contextItem != null) {
                // TODO : sort this out
                if (exprContext != null) {
                    LOG.warn("exprContext and contextItem are not null");
                }
                exprContext = contextItem.toSequence();
            }
        }
        if (initContextSequence != null) {
            exprContext = initContextSequence;
        }
        Sequence result = null;
        try {
            if (!isCalledAs(FS_EVAL_AND_SERIALIZE_NAME)) {
                result = execute(evalContext.getBroker(), xqueryService, querySource, innerContext, exprContext, cache, null);
                return result;
            } else {
                // get the default serialization options
                final Properties defaultOutputOptions;
                if (getArgumentCount() >= 2 && !args[1].isEmpty()) {
                    defaultOutputOptions = FunSerialize.getSerializationProperties(this, args[1].itemAt(0));
                } else {
                    defaultOutputOptions = new Properties();
                }
                // execute the query, XQuery prolog serialization options are collected into `xqueryOutputProperties`
                final Properties xqueryOutputProperties = new Properties();
                result = execute(evalContext.getBroker(), xqueryService, querySource, innerContext, exprContext, cache, xqueryOutputProperties);
                // do we need to subsequence the results?
                if (getArgumentCount() > 2) {
                    result = FunSubSequence.subsequence(result, ((DoubleValue) getArgument(2).eval(contextSequence, null).convertTo(Type.DOUBLE)), getArgumentCount() == 3 ? null : ((DoubleValue) getArgument(3).eval(contextSequence, null).convertTo(Type.DOUBLE)));
                }
                // override the default options with the ones from the xquery prolog
                final Properties serializationProperties = new Properties();
                serializationProperties.putAll(defaultOutputOptions);
                serializationProperties.putAll(xqueryOutputProperties);
                // serialize the results
                try (final StringWriter writer = new StringWriter()) {
                    final XQuerySerializer xqSerializer = new XQuerySerializer(context.getBroker(), serializationProperties, writer);
                    final Sequence seq;
                    if (xqSerializer.normalize()) {
                        seq = FunSerialize.normalize(this, context, result);
                    } else {
                        seq = result;
                    }
                    xqSerializer.serialize(seq);
                    return new StringValue(writer.toString());
                } catch (final IOException | SAXException e) {
                    throw new XPathException(this, FnModule.SENR0001, e.getMessage());
                }
            }
        } finally {
            cleanup(evalContext, innerContext, oldDocs, mark, expr, result);
        }
    } catch (final XPathException e) {
        try {
            e.prependMessage("Error while evaluating expression: " + querySource.getContent() + ". ");
        } catch (final IOException e1) {
        }
        if (!pass) {
            e.setLocation(line, column);
        }
        throw e;
    }
}
Also used : XQuerySerializer(org.exist.util.serializer.XQuerySerializer) Properties(java.util.Properties) StringSource(org.exist.source.StringSource) Source(org.exist.source.Source) DBSource(org.exist.source.DBSource) InputSource(org.xml.sax.InputSource) FileSource(org.exist.source.FileSource) SAXException(org.xml.sax.SAXException) StringWriter(java.io.StringWriter) DBSource(org.exist.source.DBSource) XmldbURI(org.exist.xmldb.XmldbURI) FileSource(org.exist.source.FileSource) FunSubSequence(org.exist.xquery.functions.fn.FunSubSequence) IOException(java.io.IOException) StringSource(org.exist.source.StringSource) DocumentSet(org.exist.dom.persistent.DocumentSet)

Example 3 with FileSource

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

the class Deployment method runQuery.

private Sequence runQuery(final DBBroker broker, final XmldbURI targetCollection, final Path tempDir, final String fileName, final String pkgName, final QueryPurpose purpose) throws PackageException, IOException, XPathException {
    final Path xquery = tempDir.resolve(fileName);
    if (!Files.isReadable(xquery)) {
        LOG.warn("The XQuery resource specified in the {} was not found for EXPath Package: '{}'", purpose.getPurposeString(), pkgName);
        return Sequence.EMPTY_SEQUENCE;
    }
    final XQuery xqs = broker.getBrokerPool().getXQueryService();
    final XQueryContext ctx = new XQueryContext(broker.getBrokerPool());
    ctx.declareVariable("dir", tempDir.toAbsolutePath().toString());
    final Optional<Path> home = broker.getConfiguration().getExistHome();
    if (home.isPresent()) {
        ctx.declareVariable("home", home.get().toAbsolutePath().toString());
    }
    if (targetCollection != null) {
        ctx.declareVariable("target", targetCollection.toString());
        ctx.setModuleLoadPath(XmldbURI.EMBEDDED_SERVER_URI + targetCollection.toString());
    } else {
        ctx.declareVariable("target", Sequence.EMPTY_SEQUENCE);
    }
    if (QueryPurpose.PREINSTALL == purpose) {
        // when running pre-setup scripts, base path should point to directory
        // because the target collection does not yet exist
        ctx.setModuleLoadPath(tempDir.toAbsolutePath().toString());
    }
    CompiledXQuery compiled;
    try {
        compiled = xqs.compile(ctx, new FileSource(xquery, false));
        return xqs.execute(broker, compiled, null);
    } catch (final PermissionDeniedException e) {
        throw new PackageException(e.getMessage(), e);
    }
}
Also used : Path(java.nio.file.Path) FileSource(org.exist.source.FileSource) PermissionDeniedException(org.exist.security.PermissionDeniedException)

Example 4 with FileSource

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

the class FunUnparsedText method getSource.

private Source getSource(final String uriParam) throws XPathException {
    try {
        final URI uri = new URI(uriParam);
        if (uri.getFragment() != null) {
            throw new XPathException(this, ErrorCodes.FOUT1170, "href argument may not contain fragment identifier");
        }
        final Source source = SourceFactory.getSource(context.getBroker(), "", uri.toASCIIString(), false);
        if (source == null) {
            throw new XPathException(this, ErrorCodes.FOUT1170, "Could not find source for: " + uriParam);
        }
        if (source instanceof FileSource && !context.getBroker().getCurrentSubject().hasDbaRole()) {
            throw new PermissionDeniedException("non-dba user not allowed to read from file system");
        }
        return source;
    } catch (final IOException | PermissionDeniedException | URISyntaxException e) {
        throw new XPathException(this, ErrorCodes.FOUT1170, e.getMessage());
    }
}
Also used : FileSource(org.exist.source.FileSource) PermissionDeniedException(org.exist.security.PermissionDeniedException) URISyntaxException(java.net.URISyntaxException) XmldbURI(org.exist.xmldb.XmldbURI) URI(java.net.URI) FileSource(org.exist.source.FileSource) Source(org.exist.source.Source)

Example 5 with FileSource

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

the class RedirectorServlet method service.

@Override
protected void service(final HttpServletRequest req, final HttpServletResponse res) throws ServletException, IOException {
    final RequestWrapper request = new HttpRequestWrapper(req);
    final ResponseWrapper response = new HttpResponseWrapper(res);
    if (request.getCharacterEncoding() == null)
        try {
            request.setCharacterEncoding("UTF-8");
        } catch (final IllegalStateException e) {
        }
    // Try to find the XQuery
    final String qpath = getServletContext().getRealPath(query);
    final Path p = Paths.get(qpath);
    if (!(Files.isReadable(p) && Files.isRegularFile(p))) {
        throw new ServletException("Cannot read XQuery source from " + p.toAbsolutePath());
    }
    final FileSource source = new FileSource(p, true);
    try {
        // Prepare and execute the XQuery
        final Sequence result = executeQuery(source, request, response);
        String redirectTo = null;
        String servletName = null;
        String path = null;
        ModifiableRequestWrapper modifiedRequest = null;
        // parse the query result element
        if (result != null && result.getItemCount() == 1) {
            Node node = (Node) result.itemAt(0);
            if (node.getNodeType() == Node.DOCUMENT_NODE) {
                node = ((Document) node).getDocumentElement();
            }
            if (node.getNodeType() != Node.ELEMENT_NODE) {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Redirect XQuery should return an XML element. Received: " + node);
                return;
            }
            Element elem = (Element) node;
            final String ns = elem.getNamespaceURI();
            if (ns == null || ((!Namespaces.EXIST_NS.equals(ns)) && "dispatch".equals(elem.getLocalName()))) {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Redirect XQuery should return an element <exist:dispatch>. Received: " + node);
                return;
            }
            if (elem.hasAttribute("path")) {
                path = elem.getAttribute("path");
            } else if (elem.hasAttribute("servlet-name")) {
                servletName = elem.getAttribute("servlet-name");
            } else if (elem.hasAttribute("redirect")) {
                redirectTo = elem.getAttribute("redirect");
            } else {
                response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Element <exist:dispatch> should either provide an attribute 'path' or 'servlet-name'. Received: " + node);
                return;
            }
            // Check for add-parameter elements etc.
            if (elem.hasChildNodes()) {
                node = elem.getFirstChild();
                while (node != null) {
                    final String nsUri = node.getNamespaceURI();
                    if (node.getNodeType() == Node.ELEMENT_NODE && nsUri != null && Namespaces.EXIST_NS.equals(nsUri)) {
                        elem = (Element) node;
                        if ("add-parameter".equals(elem.getLocalName())) {
                            if (modifiedRequest == null) {
                                modifiedRequest = new ModifiableRequestWrapper(req);
                            }
                            modifiedRequest.addParameter(elem.getAttribute("name"), elem.getAttribute("value"));
                        }
                    }
                    node = node.getNextSibling();
                }
            }
        }
        if (redirectTo != null) {
            // directly redirect to the specified URI
            response.sendRedirect(redirectTo);
            return;
        }
        // Get a RequestDispatcher, either from the servlet context or the request
        RequestDispatcher dispatcher;
        if (servletName != null && servletName.length() > 0) {
            dispatcher = getServletContext().getNamedDispatcher(servletName);
        } else {
            LOG.debug("Dispatching to {}", path);
            dispatcher = getServletContext().getRequestDispatcher(path);
            if (dispatcher == null) {
                dispatcher = request.getRequestDispatcher(path);
            }
        }
        if (dispatcher == null) {
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Could not create a request dispatcher. Giving up.");
            return;
        }
        if (modifiedRequest != null) {
            // store the original request URI to org.exist.forward.request-uri
            modifiedRequest.setAttribute("org.exist.forward.request-uri", modifiedRequest.getRequestURI());
            modifiedRequest.setAttribute("org.exist.forward.servlet-path", modifiedRequest.getServletPath());
            // finally, execute the forward
            dispatcher.forward(modifiedRequest, res);
        } else {
            // store the original request URI to org.exist.forward.request-uri
            request.setAttribute("org.exist.forward.request-uri", request.getRequestURI());
            request.setAttribute("org.exist.forward.servlet-path", request.getServletPath());
            // finally, execute the forward
            dispatcher.forward(req, res);
        }
    } catch (final XPathException | EXistException | PermissionDeniedException | IOException e) {
        throw new ServletException("An error occurred while executing the RedirectorServlet XQuery: " + e.getMessage(), e);
    }
}
Also used : Path(java.nio.file.Path) XPathException(org.exist.xquery.XPathException) FileSource(org.exist.source.FileSource) Node(org.w3c.dom.Node) Element(org.w3c.dom.Element) Sequence(org.exist.xquery.value.Sequence) EXistException(org.exist.EXistException) IOException(java.io.IOException) RequestDispatcher(javax.servlet.RequestDispatcher) ServletException(javax.servlet.ServletException) PermissionDeniedException(org.exist.security.PermissionDeniedException)

Aggregations

FileSource (org.exist.source.FileSource)8 Path (java.nio.file.Path)4 PermissionDeniedException (org.exist.security.PermissionDeniedException)4 IOException (java.io.IOException)3 Source (org.exist.source.Source)3 XmldbURI (org.exist.xmldb.XmldbURI)2 Tuple2 (com.evolvedbinary.j8fu.tuple.Tuple2)1 StringWriter (java.io.StringWriter)1 URI (java.net.URI)1 URISyntaxException (java.net.URISyntaxException)1 Properties (java.util.Properties)1 RequestDispatcher (javax.servlet.RequestDispatcher)1 ServletException (javax.servlet.ServletException)1 EXistException (org.exist.EXistException)1 QName (org.exist.dom.QName)1 DocumentSet (org.exist.dom.persistent.DocumentSet)1 SecurityManager (org.exist.security.SecurityManager)1 ClassLoaderSource (org.exist.source.ClassLoaderSource)1 DBSource (org.exist.source.DBSource)1 StringSource (org.exist.source.StringSource)1