Search in sources :

Example 1 with TextImpl

use of org.exist.dom.memtree.TextImpl in project exist by eXist-db.

the class EnclosedExpr method eval.

/* (non-Javadoc)
     * @see org.exist.xquery.AbstractExpression#eval(org.exist.xquery.StaticContext,
     * org.exist.dom.persistent.DocumentSet, org.exist.xquery.value.Sequence)
     */
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 (contextItem != null) {
        contextSequence = contextItem.toSequence();
    }
    // evaluate the expression
    Sequence result;
    context.enterEnclosedExpr();
    try {
        context.pushDocumentContext();
        try {
            result = super.eval(contextSequence, null);
        } finally {
            context.popDocumentContext();
        }
        // create the output
        final MemTreeBuilder builder = context.getDocumentBuilder();
        final DocumentBuilderReceiver receiver = new DocumentBuilderReceiver(builder);
        receiver.setCheckNS(true);
        try {
            // flatten all arrays in the input sequence
            result = ArrayType.flatten(result);
            final SequenceIterator i = result.iterate();
            Item next = i.nextItem();
            StringBuilder buf = null;
            boolean allowAttribs = true;
            while (next != null) {
                context.proceed(this, builder);
                if (Type.subTypeOf(next.getType(), Type.FUNCTION_REFERENCE)) {
                    throw new XPathException(this, ErrorCodes.XQTY0105, "Enclosed expression contains function item");
                // if item is an atomic value, collect the string values of all
                // following atomic values and separate them by a space.
                } else if (Type.subTypeOf(next.getType(), Type.ATOMIC)) {
                    if (buf == null) {
                        buf = new StringBuilder();
                    } else if (buf.length() > 0) {
                        buf.append(' ');
                    }
                    buf.append(next.getStringValue());
                    allowAttribs = false;
                    next = i.nextItem();
                // If the item is a node, flush any collected character data and
                // copy the node to the target doc.
                } else if (Type.subTypeOf(next.getType(), Type.NODE)) {
                    // such a text node will be deleted or merged with another text node.
                    if (next instanceof TextImpl && ((TextImpl) next).getStringValue().isEmpty()) {
                        next = i.nextItem();
                        continue;
                    }
                    if (buf != null && buf.length() > 0) {
                        receiver.characters(buf);
                        buf.setLength(0);
                    }
                    if (next.getType() == Type.ATTRIBUTE && !allowAttribs) {
                        throw new XPathException(this, ErrorCodes.XQTY0024, "An attribute may not appear after another child node.");
                    }
                    try {
                        receiver.setCheckNS(false);
                        next.copyTo(context.getBroker(), receiver);
                        receiver.setCheckNS(true);
                    } catch (DOMException e) {
                        if (e.code == DOMException.NAMESPACE_ERR) {
                            throw new XPathException(this, ErrorCodes.XQDY0102, e.getMessage());
                        } else {
                            throw new XPathException(this, e.getMessage(), e);
                        }
                    }
                    allowAttribs = next.getType() == Type.ATTRIBUTE || next.getType() == Type.NAMESPACE;
                    next = i.nextItem();
                }
            }
            // flush remaining character data
            if (buf != null && buf.length() > 0) {
                receiver.characters(buf);
            }
        } catch (final SAXException e) {
            LOG.warn("SAXException during serialization: {}", e.getMessage(), e);
            throw new XPathException(this, e);
        }
    } finally {
        context.exitEnclosedExpr();
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", result);
    }
    return result;
}
Also used : DOMException(org.w3c.dom.DOMException) MemTreeBuilder(org.exist.dom.memtree.MemTreeBuilder) DocumentBuilderReceiver(org.exist.dom.memtree.DocumentBuilderReceiver) TextImpl(org.exist.dom.memtree.TextImpl) SAXException(org.xml.sax.SAXException)

Aggregations

DocumentBuilderReceiver (org.exist.dom.memtree.DocumentBuilderReceiver)1 MemTreeBuilder (org.exist.dom.memtree.MemTreeBuilder)1 TextImpl (org.exist.dom.memtree.TextImpl)1 DOMException (org.w3c.dom.DOMException)1 SAXException (org.xml.sax.SAXException)1