Search in sources :

Example 1 with ValueSequence

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

the class SequenceConstructor method eval.

@Override
public Sequence eval(final Sequence contextSequence, final 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 ValueSequence result = new ValueSequence();
    result.keepUnOrdered(unordered);
    for (final Expression step : steps) {
        context.pushDocumentContext();
        try {
            final Sequence temp = step.eval(contextSequence, contextItem);
            if (temp != null && !temp.isEmpty()) {
                result.addAll(temp);
            }
        } finally {
            context.popDocumentContext();
        }
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", result);
    }
    return result;
}
Also used : ValueSequence(org.exist.xquery.value.ValueSequence) ValueSequence(org.exist.xquery.value.ValueSequence) Sequence(org.exist.xquery.value.Sequence)

Example 2 with ValueSequence

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

the class Predicate method selectByPosition.

/**
 * @param outerSequence the outer sequence
 * @param contextSequence the context sequence
 * @param mode the mode
 * @param innerSeq the inner sequence
 *
 * @return The result of the positional evaluation of the predicate.
 *
 * @throws XPathException if an error occurs
 */
private Sequence selectByPosition(final Sequence outerSequence, final Sequence contextSequence, final int mode, final Sequence innerSeq) throws XPathException {
    if (outerSequence != null && !outerSequence.isEmpty() && Type.subTypeOf(contextSequence.getItemType(), Type.NODE) && contextSequence.isPersistentSet() && outerSequence.isPersistentSet()) {
        final Sequence result = new NewArrayNodeSet();
        final NodeSet contextSet = contextSequence.toNodeSet();
        switch(mode) {
            case Constants.CHILD_AXIS:
            case Constants.ATTRIBUTE_AXIS:
            case Constants.DESCENDANT_AXIS:
            case Constants.DESCENDANT_SELF_AXIS:
            case Constants.DESCENDANT_ATTRIBUTE_AXIS:
                {
                    final NodeSet outerNodeSet = outerSequence.toNodeSet();
                    // TODO: in some cases, especially with in-memory nodes,
                    // outerSequence.toNodeSet() will generate a document
                    // which will be different from the one(s) in contextSet
                    // ancestors will thus be empty :-(
                    // A special treatment of VirtualNodeSet does not seem to be
                    // required anymore
                    final Sequence ancestors = outerNodeSet.selectAncestors(contextSet, true, getExpressionId());
                    if (contextSet.getDocumentSet().intersection(outerNodeSet.getDocumentSet()).getDocumentCount() == 0) {
                        LOG.info("contextSet and outerNodeSet don't share any document");
                    }
                    final NewArrayNodeSet temp = new NewArrayNodeSet();
                    for (final SequenceIterator i = ancestors.iterate(); i.hasNext(); ) {
                        NodeProxy p = (NodeProxy) i.nextItem();
                        ContextItem contextNode = p.getContext();
                        temp.reset();
                        while (contextNode != null) {
                            if (contextNode.getContextId() == getExpressionId()) {
                                temp.add(contextNode.getNode());
                            }
                            contextNode = contextNode.getNextDirect();
                        }
                        p.clearContext(getExpressionId());
                        // TODO : understand why we sort here...
                        temp.sortInDocumentOrder();
                        for (final SequenceIterator j = innerSeq.iterate(); j.hasNext(); ) {
                            final NumericValue v = (NumericValue) j.nextItem();
                            // Non integers return... nothing, not even an error !
                            if (!v.hasFractionalPart() && !v.isZero()) {
                                // ... whereas we don't want a sorted array here
                                // TODO : rename this method as getInDocumentOrder ? -pb
                                p = temp.get(v.getInt() - 1);
                                if (p != null) {
                                    result.add(p);
                                }
                            // TODO : does null make sense here ? Well... sometimes ;-)
                            }
                        }
                    }
                    break;
                }
            default:
                for (final SequenceIterator i = outerSequence.iterate(); i.hasNext(); ) {
                    NodeProxy p = (NodeProxy) i.nextItem();
                    Sequence temp;
                    boolean reverseAxis = true;
                    switch(mode) {
                        case Constants.ANCESTOR_AXIS:
                            temp = contextSet.selectAncestors(p, false, Expression.IGNORE_CONTEXT);
                            break;
                        case Constants.ANCESTOR_SELF_AXIS:
                            temp = contextSet.selectAncestors(p, true, Expression.IGNORE_CONTEXT);
                            break;
                        case Constants.PARENT_AXIS:
                            // TODO : understand why the contextSet is not involved
                            // here
                            // NodeProxy.getParent returns a *theoretical* parent
                            // which is *not* guaranteed to be in the context set !
                            temp = p.getParents(Expression.NO_CONTEXT_ID);
                            break;
                        case Constants.PRECEDING_AXIS:
                            temp = contextSet.selectPreceding(p, Expression.IGNORE_CONTEXT);
                            break;
                        case Constants.PRECEDING_SIBLING_AXIS:
                            temp = contextSet.selectPrecedingSiblings(p, Expression.IGNORE_CONTEXT);
                            break;
                        case Constants.FOLLOWING_SIBLING_AXIS:
                            temp = contextSet.selectFollowingSiblings(p, Expression.IGNORE_CONTEXT);
                            reverseAxis = false;
                            break;
                        case Constants.FOLLOWING_AXIS:
                            temp = contextSet.selectFollowing(p, Expression.IGNORE_CONTEXT);
                            reverseAxis = false;
                            break;
                        case Constants.SELF_AXIS:
                            temp = p;
                            reverseAxis = false;
                            break;
                        default:
                            throw new IllegalArgumentException("Tried to test unknown axis");
                    }
                    if (!temp.isEmpty()) {
                        for (final SequenceIterator j = innerSeq.iterate(); j.hasNext(); ) {
                            final NumericValue v = (NumericValue) j.nextItem();
                            // Non integers return... nothing, not even an error !
                            if (!v.hasFractionalPart() && !v.isZero()) {
                                final int pos = (reverseAxis ? temp.getItemCount() - v.getInt() : v.getInt() - 1);
                                // Other positions are ignored
                                if (pos >= 0 && pos < temp.getItemCount()) {
                                    final NodeProxy t = (NodeProxy) temp.itemAt(pos);
                                    // for the current context: filter out those
                                    // context items not selected by the positional predicate
                                    ContextItem ctx = t.getContext();
                                    t.clearContext(Expression.IGNORE_CONTEXT);
                                    while (ctx != null) {
                                        if (ctx.getContextId() == outerContextId) {
                                            if (ctx.getNode().getNodeId().equals(p.getNodeId())) {
                                                t.addContextNode(outerContextId, ctx.getNode());
                                            }
                                        } else {
                                            t.addContextNode(ctx.getContextId(), ctx.getNode());
                                        }
                                        ctx = ctx.getNextDirect();
                                    }
                                    result.add(t);
                                }
                            }
                        }
                    }
                }
        }
        return result;
    } else {
        final boolean reverseAxis = Type.subTypeOf(contextSequence.getItemType(), Type.NODE) && (mode == Constants.ANCESTOR_AXIS || mode == Constants.ANCESTOR_SELF_AXIS || mode == Constants.PARENT_AXIS || mode == Constants.PRECEDING_AXIS || mode == Constants.PRECEDING_SIBLING_AXIS);
        final Set<NumericValue> set = new TreeSet<>();
        final ValueSequence result = new ValueSequence();
        for (final SequenceIterator i = innerSeq.iterate(); i.hasNext(); ) {
            final NumericValue v = (NumericValue) i.nextItem();
            // Non integers return... nothing, not even an error !
            if (!v.hasFractionalPart() && !v.isZero()) {
                final int pos = (reverseAxis ? contextSequence.getItemCount() - v.getInt() : v.getInt() - 1);
                // Other positions are ignored
                if (pos >= 0 && pos < contextSequence.getItemCount() && !set.contains(v)) {
                    result.add(contextSequence.itemAt(pos));
                    set.add(v);
                }
            }
        }
        return result;
    }
}
Also used : NodeSet(org.exist.dom.persistent.NodeSet) VirtualNodeSet(org.exist.dom.persistent.VirtualNodeSet) NewArrayNodeSet(org.exist.dom.persistent.NewArrayNodeSet) NewArrayNodeSet(org.exist.dom.persistent.NewArrayNodeSet) ContextItem(org.exist.dom.persistent.ContextItem) ValueSequence(org.exist.xquery.value.ValueSequence) Sequence(org.exist.xquery.value.Sequence) NodeProxy(org.exist.dom.persistent.NodeProxy) SequenceIterator(org.exist.xquery.value.SequenceIterator) TreeSet(java.util.TreeSet) ValueSequence(org.exist.xquery.value.ValueSequence) NumericValue(org.exist.xquery.value.NumericValue)

Example 3 with ValueSequence

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

the class GrammarTooling method eval.

/**
 * @see org.exist.xquery.BasicFunction#eval(Sequence[], Sequence)
 */
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
    final GrammarPool grammarpool = (GrammarPool) config.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL);
    if (isCalledAs("clear-grammar-cache")) {
        final Sequence result = new ValueSequence();
        final int before = countTotalNumberOfGrammar(grammarpool);
        LOG.debug("Clearing {} grammars", before);
        clearGrammarPool(grammarpool);
        final int after = countTotalNumberOfGrammar(grammarpool);
        LOG.debug("Remained {} grammars", after);
        final int delta = before - after;
        result.add(new IntegerValue(delta));
        return result;
    } else if (isCalledAs("show-grammar-cache")) {
        context.pushDocumentContext();
        try {
            final MemTreeBuilder builder = context.getDocumentBuilder();
            final NodeImpl result = writeReport(grammarpool, builder);
            return result;
        } finally {
            context.popDocumentContext();
        }
    } else if (isCalledAs("pre-parse-grammar")) {
        if (args[0].isEmpty()) {
            return Sequence.EMPTY_SEQUENCE;
        }
        // Setup for XML schema support only
        final XMLGrammarPreparser parser = new XMLGrammarPreparser();
        parser.registerPreparser(TYPE_XSD, null);
        final List<Grammar> allGrammars = new ArrayList<>();
        // iterate through the argument sequence and parse url
        for (final SequenceIterator i = args[0].iterate(); i.hasNext(); ) {
            String url = i.nextItem().getStringValue();
            // Fix database urls
            if (url.startsWith("/")) {
                url = "xmldb:exist://" + url;
            }
            LOG.debug("Parsing {}", url);
            // parse XSD grammar
            try {
                if (url.endsWith(".xsd")) {
                    final InputStream is = new URL(url).openStream();
                    final XMLInputSource xis = new XMLInputSource(null, url, url, is, null);
                    final Grammar schema = parser.preparseGrammar(TYPE_XSD, xis);
                    is.close();
                    allGrammars.add(schema);
                } else {
                    throw new XPathException(this, "Only XMLSchemas can be preparsed.");
                }
            } catch (final Exception ex) {
                LOG.debug(ex);
                throw new XPathException(this, ex);
            }
        }
        LOG.debug("Successfully parsed {} grammars.", allGrammars.size());
        // Send all XSD grammars to grammarpool
        Grammar[] grammars = new Grammar[allGrammars.size()];
        grammars = allGrammars.toArray(grammars);
        grammarpool.cacheGrammars(TYPE_XSD, grammars);
        // Construct result to end user
        final ValueSequence result = new ValueSequence();
        for (final Grammar one : grammars) {
            result.add(new StringValue(one.getGrammarDescription().getNamespace()));
        }
        return result;
    } else {
        // oh oh
        LOG.error("function not found error");
        throw new XPathException(this, "function not found");
    }
}
Also used : NodeImpl(org.exist.dom.memtree.NodeImpl) XMLInputSource(org.apache.xerces.xni.parser.XMLInputSource) XPathException(org.exist.xquery.XPathException) InputStream(java.io.InputStream) IntegerValue(org.exist.xquery.value.IntegerValue) ArrayList(java.util.ArrayList) GrammarPool(org.exist.validation.GrammarPool) ValueSequence(org.exist.xquery.value.ValueSequence) Sequence(org.exist.xquery.value.Sequence) Grammar(org.apache.xerces.xni.grammars.Grammar) URL(java.net.URL) XPathException(org.exist.xquery.XPathException) MemTreeBuilder(org.exist.dom.memtree.MemTreeBuilder) XMLGrammarPreparser(org.apache.xerces.parsers.XMLGrammarPreparser) SequenceIterator(org.exist.xquery.value.SequenceIterator) ValueSequence(org.exist.xquery.value.ValueSequence) StringValue(org.exist.xquery.value.StringValue)

Example 4 with ValueSequence

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

the class Jaxv method eval.

public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
    // Check input parameters
    if (args.length != 2 && args.length != 3) {
        return Sequence.EMPTY_SEQUENCE;
    }
    final ValidationReport report = new ValidationReport();
    StreamSource instance = null;
    StreamSource[] grammars = null;
    String schemaLang = XMLConstants.W3C_XML_SCHEMA_NS_URI;
    try {
        report.start();
        // Get inputstream for instance document
        instance = Shared.getStreamSource(args[0].itemAt(0), context);
        // Validate using resource speciefied in second parameter
        grammars = Shared.getStreamSource(args[1], context);
        // Check input
        for (final StreamSource grammar : grammars) {
            final String grammarUrl = grammar.getSystemId();
            if (grammarUrl != null && !grammarUrl.endsWith(".xsd") && !grammarUrl.endsWith(".rng")) {
                throw new XPathException("Only XML schemas (.xsd) and RELAXNG grammars (.rng) are supported" + ", depending on the used XML parser.");
            }
        }
        // Fetch third argument if available, and override defailt value
        if (args.length == 3) {
            schemaLang = args[2].getStringValue();
        }
        // Get language specific factory
        SchemaFactory factory = null;
        try {
            factory = SchemaFactory.newInstance(schemaLang);
        } catch (final IllegalArgumentException ex) {
            final String msg = "Schema language '" + schemaLang + "' is not supported. " + ex.getMessage();
            LOG.error(msg);
            throw new XPathException(msg);
        }
        // Create grammar
        final Schema schema = factory.newSchema(grammars);
        // Setup validator
        final Validator validator = schema.newValidator();
        validator.setErrorHandler(report);
        // Perform validation
        validator.validate(instance);
    } catch (final MalformedURLException ex) {
        LOG.error(ex.getMessage());
        report.setException(ex);
    } catch (final Throwable ex) {
        LOG.error(ex);
        report.setException(ex);
    } finally {
        report.stop();
        Shared.closeStreamSource(instance);
        Shared.closeStreamSources(grammars);
    }
    // Create response
    if (isCalledAs("jaxv")) {
        final Sequence result = new ValueSequence();
        result.add(new BooleanValue(report.isValid()));
        return result;
    } else /* isCalledAs("jaxv-report") */
    {
        context.pushDocumentContext();
        try {
            final MemTreeBuilder builder = context.getDocumentBuilder();
            final NodeImpl result = Shared.writeReport(report, builder);
            return result;
        } finally {
            context.popDocumentContext();
        }
    }
}
Also used : SchemaFactory(javax.xml.validation.SchemaFactory) MalformedURLException(java.net.MalformedURLException) NodeImpl(org.exist.dom.memtree.NodeImpl) XPathException(org.exist.xquery.XPathException) StreamSource(javax.xml.transform.stream.StreamSource) Schema(javax.xml.validation.Schema) ValueSequence(org.exist.xquery.value.ValueSequence) Sequence(org.exist.xquery.value.Sequence) MemTreeBuilder(org.exist.dom.memtree.MemTreeBuilder) ValidationReport(org.exist.validation.ValidationReport) BooleanValue(org.exist.xquery.value.BooleanValue) ValueSequence(org.exist.xquery.value.ValueSequence) Validator(javax.xml.validation.Validator)

Example 5 with ValueSequence

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

the class Jaxp method eval.

public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
    XMLEntityResolver entityResolver = null;
    GrammarPool grammarPool = null;
    final ValidationReport report = new ValidationReport();
    ContentHandler contenthandler = null;
    MemTreeBuilder instanceBuilder = null;
    InputSource instance = null;
    if (isCalledAs("jaxp-parse")) {
        instanceBuilder = context.getDocumentBuilder();
        // (namespace?)
        contenthandler = new DocumentBuilderReceiver(instanceBuilder, true);
    } else {
        contenthandler = new ValidationContentHandler();
    }
    try {
        report.start();
        // Get initialized parser
        final XMLReader xmlReader = getXMLReader();
        // Setup validation reporting
        xmlReader.setContentHandler(contenthandler);
        xmlReader.setErrorHandler(report);
        // Get inputstream for instance document
        instance = Shared.getInputSource(args[0].itemAt(0), context);
        // Handle catalog
        if (args.length == 2) {
            LOG.debug("No Catalog specified");
        } else if (args[2].isEmpty()) {
            // Use system catalog
            LOG.debug("Using system catalog.");
            final Configuration config = brokerPool.getConfiguration();
            entityResolver = (eXistXMLCatalogResolver) config.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER);
            setXmlReaderEnitityResolver(xmlReader, entityResolver);
        } else {
            // Get URL for catalog
            final String[] catalogUrls = Shared.getUrls(args[2]);
            final String singleUrl = catalogUrls[0];
            if (singleUrl.endsWith("/")) {
                // Search grammar in collection specified by URL. Just one collection is used.
                LOG.debug("Search for grammar in {}", singleUrl);
                entityResolver = new SearchResourceResolver(catalogUrls[0], brokerPool);
                setXmlReaderEnitityResolver(xmlReader, entityResolver);
            } else if (singleUrl.endsWith(".xml")) {
                LOG.debug("Using catalogs {}", getStrings(catalogUrls));
                entityResolver = new eXistXMLCatalogResolver();
                ((eXistXMLCatalogResolver) entityResolver).setCatalogList(catalogUrls);
                setXmlReaderEnitityResolver(xmlReader, entityResolver);
            } else {
                LOG.error("Catalog URLs should end on / or .xml");
            }
        }
        // Use grammarpool
        final boolean useCache = ((BooleanValue) args[1].itemAt(0)).getValue();
        if (useCache) {
            LOG.debug("Grammar caching enabled.");
            final Configuration config = brokerPool.getConfiguration();
            grammarPool = (GrammarPool) config.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL);
            xmlReader.setProperty(XMLReaderObjectFactory.APACHE_PROPERTIES_INTERNAL_GRAMMARPOOL, grammarPool);
        }
        // Jaxp document
        LOG.debug("Start parsing document");
        xmlReader.parse(instance);
        LOG.debug("Stopped parsing document");
        // Distill namespace from document
        if (contenthandler instanceof ValidationContentHandler) {
            report.setNamespaceUri(((ValidationContentHandler) contenthandler).getNamespaceUri());
        }
    } catch (final MalformedURLException ex) {
        LOG.error(ex.getMessage());
        report.setException(ex);
    } catch (final IOException ex) {
        LOG.error(ex.getCause());
        report.setException(ex);
    } catch (final Throwable ex) {
        LOG.error(ex);
        report.setException(ex);
    } finally {
        report.stop();
        Shared.closeInputSource(instance);
    }
    // Create response
    if (isCalledAs("jaxp")) {
        final Sequence result = new ValueSequence();
        result.add(new BooleanValue(report.isValid()));
        return result;
    } else /* isCalledAs("jaxp-report or jaxp-parse ") */
    {
        if (report.getThrowable() != null) {
            throw new XPathException(report.getThrowable().getMessage(), report.getThrowable());
        }
        if (contenthandler instanceof DocumentBuilderReceiver) {
            // DocumentBuilderReceiver dbr = (DocumentBuilderReceiver) contenthandler;
            return instanceBuilder.getDocument().getNode(0);
        } else {
            context.pushDocumentContext();
            try {
                final MemTreeBuilder builder = context.getDocumentBuilder();
                return Shared.writeReport(report, builder);
            } finally {
                context.popDocumentContext();
            }
        }
    }
}
Also used : ValidationContentHandler(org.exist.validation.ValidationContentHandler) InputSource(org.xml.sax.InputSource) SearchResourceResolver(org.exist.validation.resolver.SearchResourceResolver) MalformedURLException(java.net.MalformedURLException) org.exist.validation.resolver.eXistXMLCatalogResolver(org.exist.validation.resolver.eXistXMLCatalogResolver) Configuration(org.exist.util.Configuration) XPathException(org.exist.xquery.XPathException) XMLEntityResolver(org.apache.xerces.xni.parser.XMLEntityResolver) GrammarPool(org.exist.validation.GrammarPool) IOException(java.io.IOException) ValueSequence(org.exist.xquery.value.ValueSequence) Sequence(org.exist.xquery.value.Sequence) DocumentBuilderReceiver(org.exist.dom.memtree.DocumentBuilderReceiver) ContentHandler(org.xml.sax.ContentHandler) ValidationContentHandler(org.exist.validation.ValidationContentHandler) MemTreeBuilder(org.exist.dom.memtree.MemTreeBuilder) ValidationReport(org.exist.validation.ValidationReport) BooleanValue(org.exist.xquery.value.BooleanValue) ValueSequence(org.exist.xquery.value.ValueSequence) XMLReader(org.xml.sax.XMLReader)

Aggregations

ValueSequence (org.exist.xquery.value.ValueSequence)62 Sequence (org.exist.xquery.value.Sequence)44 StringValue (org.exist.xquery.value.StringValue)26 XPathException (org.exist.xquery.XPathException)25 Item (org.exist.xquery.value.Item)15 SequenceIterator (org.exist.xquery.value.SequenceIterator)15 MemTreeBuilder (org.exist.dom.memtree.MemTreeBuilder)7 DocumentImpl (org.exist.dom.persistent.DocumentImpl)7 EXistException (org.exist.EXistException)6 NodeProxy (org.exist.dom.persistent.NodeProxy)6 PermissionDeniedException (org.exist.security.PermissionDeniedException)6 Txn (org.exist.storage.txn.Txn)6 LockException (org.exist.util.LockException)6 TriggerException (org.exist.collections.triggers.TriggerException)5 NodeImpl (org.exist.dom.memtree.NodeImpl)5 NotificationService (org.exist.storage.NotificationService)5 BooleanValue (org.exist.xquery.value.BooleanValue)5 IOException (java.io.IOException)4 Path (java.nio.file.Path)4 StoredNode (org.exist.dom.persistent.StoredNode)4