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;
}
Aggregations