Search in sources :

Example 6 with Expression

use of org.exist.xquery.Expression in project exist by eXist-db.

the class PreorderedValueSequence method processAll.

private void processAll() throws XPathException {
    for (int i = 0; i < orderSpecs.length; i++) {
        final Expression expr = orderSpecs[i].getSortExpression();
        final NodeSet result = expr.eval(null).toNodeSet();
        for (final NodeProxy p : result) {
            ContextItem context = p.getContext();
            // TODO : review to consider transverse context
            while (context != null) {
                if (context.getNode() instanceof OrderedNodeProxy) {
                    final OrderedNodeProxy cp = (OrderedNodeProxy) context.getNode();
                    cp.values[i] = p.atomize();
                }
                context = context.getNextDirect();
            }
        }
    }
}
Also used : NodeSet(org.exist.dom.persistent.NodeSet) ContextItem(org.exist.dom.persistent.ContextItem) Expression(org.exist.xquery.Expression) NodeProxy(org.exist.dom.persistent.NodeProxy)

Example 7 with Expression

use of org.exist.xquery.Expression 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 8 with Expression

use of org.exist.xquery.Expression in project exist by eXist-db.

the class FunIdRef method eval.

/**
 * @see org.exist.xquery.Expression#eval(Sequence, Item)
 */
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().start(this);
        context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
        if (contextSequence != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
        }
        if (contextItem != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT ITEM", contextItem.toSequence());
        }
    }
    if (getArgumentCount() < 1) {
        throw new XPathException(this, ErrorCodes.XPST0017, "function id requires one argument");
    }
    if (contextItem != null) {
        contextSequence = contextItem.toSequence();
    }
    Sequence result;
    boolean processInMem = false;
    final Expression arg = getArgument(0);
    final Sequence idrefval = arg.eval(contextSequence);
    if (idrefval.isEmpty()) {
        result = Sequence.EMPTY_SEQUENCE;
    } else {
        String nextId;
        DocumentSet docs = null;
        if (getArgumentCount() == 2) {
            // second argument should be a node, whose owner document will be
            // searched for the id
            final Sequence nodes = getArgument(1).eval(contextSequence);
            if (nodes.isEmpty()) {
                throw new XPathException(this, ErrorCodes.XPDY0002, "no node or context item for fn:idref");
            }
            if (!Type.subTypeOf(nodes.itemAt(0).getType(), Type.NODE)) {
                throw new XPathException(this, ErrorCodes.XPTY0004, "fn:idref() argument is not a node");
            }
            NodeValue node = (NodeValue) nodes.itemAt(0);
            if (node.getImplementationType() == NodeValue.IN_MEMORY_NODE) // TODO : how to enforce this ?
            // If $node, or the context item if the second argument is omitted,
            // is a node in a tree whose root is not a document node [err:FODC0001] is raised                    processInMem = true;
            {
                processInMem = true;
            } else {
                MutableDocumentSet ndocs = new DefaultDocumentSet();
                ndocs.add(((NodeProxy) node).getOwnerDocument());
                docs = ndocs;
            }
            contextSequence = node;
        } else if (contextSequence == null) {
            throw new XPathException(this, ErrorCodes.XPDY0002, "no context item specified");
        } else if (!Type.subTypeOf(contextSequence.getItemType(), Type.NODE)) {
            throw new XPathException(this, ErrorCodes.XPTY0004, "context item is not a node");
        } else {
            if (contextSequence.isPersistentSet()) {
                docs = contextSequence.toNodeSet().getDocumentSet();
            } else {
                processInMem = true;
            }
        }
        if (processInMem) {
            result = new ValueSequence();
        } else {
            result = new ExtArrayNodeSet();
        }
        for (final SequenceIterator i = idrefval.iterate(); i.hasNext(); ) {
            nextId = i.nextItem().getStringValue();
            if (nextId.isEmpty()) {
                continue;
            }
            if (XMLNames.isNCName(nextId)) {
                if (processInMem) {
                    getIdRef(result, contextSequence, nextId);
                } else {
                    getIdRef((NodeSet) result, docs, nextId);
                }
            }
        }
    }
    result.removeDuplicates();
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", result);
    }
    return result;
}
Also used : NodeValue(org.exist.xquery.value.NodeValue) MutableDocumentSet(org.exist.dom.persistent.MutableDocumentSet) DefaultDocumentSet(org.exist.dom.persistent.DefaultDocumentSet) ExtArrayNodeSet(org.exist.dom.persistent.ExtArrayNodeSet) SequenceIterator(org.exist.xquery.value.SequenceIterator) XPathException(org.exist.xquery.XPathException) Expression(org.exist.xquery.Expression) ValueSequence(org.exist.xquery.value.ValueSequence) ValueSequence(org.exist.xquery.value.ValueSequence) Sequence(org.exist.xquery.value.Sequence) DefaultDocumentSet(org.exist.dom.persistent.DefaultDocumentSet) DocumentSet(org.exist.dom.persistent.DocumentSet) MutableDocumentSet(org.exist.dom.persistent.MutableDocumentSet)

Example 9 with Expression

use of org.exist.xquery.Expression in project exist by eXist-db.

the class FunSubstringAfter method eval.

public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().start(this);
        context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
        if (contextSequence != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
        }
        if (contextItem != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT ITEM", contextItem.toSequence());
        }
    }
    final Expression arg0 = getArgument(0);
    final Expression arg1 = getArgument(1);
    if (contextItem != null) {
        contextSequence = contextItem.toSequence();
    }
    final Sequence seq1 = arg0.eval(contextSequence);
    final Sequence seq2 = arg1.eval(contextSequence);
    String value;
    String cmp;
    Sequence result;
    if (seq1.isEmpty()) {
        value = StringValue.EMPTY_STRING.getStringValue();
    } else {
        value = seq1.getStringValue();
    }
    if (seq2.isEmpty()) {
        cmp = StringValue.EMPTY_STRING.getStringValue();
    } else {
        cmp = seq2.getStringValue();
    }
    if (cmp.isEmpty()) {
        result = new StringValue(value);
    } else {
        final Collator collator = getCollator(contextSequence, contextItem, 3);
        final int p = Collations.indexOf(collator, value, cmp);
        if (p == Constants.STRING_NOT_FOUND) {
            result = StringValue.EMPTY_STRING;
        } else {
            result = new StringValue(p + cmp.length() < value.length() ? value.substring(p + cmp.length()) : "");
        }
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", result);
    }
    return result;
}
Also used : Expression(org.exist.xquery.Expression) Sequence(org.exist.xquery.value.Sequence) StringValue(org.exist.xquery.value.StringValue) Collator(com.ibm.icu.text.Collator)

Example 10 with Expression

use of org.exist.xquery.Expression in project exist by eXist-db.

the class FunSubstringBefore method eval.

public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().start(this);
        context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
        if (contextSequence != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
        }
        if (contextItem != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT ITEM", contextItem.toSequence());
        }
    }
    final Expression arg0 = getArgument(0);
    final Expression arg1 = getArgument(1);
    if (contextItem != null) {
        contextSequence = contextItem.toSequence();
    }
    final Sequence seq1 = arg0.eval(contextSequence);
    final Sequence seq2 = arg1.eval(contextSequence);
    String value;
    String cmp;
    Sequence result;
    if (seq1.isEmpty()) {
        value = StringValue.EMPTY_STRING.getStringValue();
    } else {
        value = seq1.getStringValue();
    }
    if (seq2.isEmpty()) {
        cmp = StringValue.EMPTY_STRING.getStringValue();
    } else {
        cmp = seq2.getStringValue();
    }
    if (cmp.isEmpty()) {
        result = StringValue.EMPTY_STRING;
    } else {
        final Collator collator = getCollator(contextSequence, contextItem, 3);
        final int p = Collations.indexOf(collator, value, cmp);
        if (p == Constants.STRING_NOT_FOUND) {
            result = StringValue.EMPTY_STRING;
        } else {
            result = new StringValue(value.substring(0, p));
        }
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", result);
    }
    return result;
}
Also used : Expression(org.exist.xquery.Expression) Sequence(org.exist.xquery.value.Sequence) StringValue(org.exist.xquery.value.StringValue) Collator(com.ibm.icu.text.Collator)

Aggregations

Expression (org.exist.xquery.Expression)12 Sequence (org.exist.xquery.value.Sequence)7 XPathException (org.exist.xquery.XPathException)3 SequenceIterator (org.exist.xquery.value.SequenceIterator)3 Collator (com.ibm.icu.text.Collator)2 NodeProxy (org.exist.dom.persistent.NodeProxy)2 NodeSet (org.exist.dom.persistent.NodeSet)2 DynamicCardinalityCheck (org.exist.xquery.DynamicCardinalityCheck)2 Error (org.exist.xquery.util.Error)2 NodeValue (org.exist.xquery.value.NodeValue)2 StringValue (org.exist.xquery.value.StringValue)2 ValueSequence (org.exist.xquery.value.ValueSequence)2 IOException (java.io.IOException)1 URI (java.net.URI)1 URISyntaxException (java.net.URISyntaxException)1 Path (java.nio.file.Path)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)1