use of org.exist.dom.memtree.NodeImpl in project exist by eXist-db.
the class XQueryContext method getXMLStreamReader.
@Override
public ExtendedXMLStreamReader getXMLStreamReader(final NodeValue nv) throws XMLStreamException, IOException {
final ExtendedXMLStreamReader reader;
if (nv.getImplementationType() == NodeValue.IN_MEMORY_NODE) {
final NodeImpl node = (NodeImpl) nv;
final org.exist.dom.memtree.DocumentImpl ownerDoc = node.getNodeType() == Node.DOCUMENT_NODE ? (org.exist.dom.memtree.DocumentImpl) node : node.getOwnerDocument();
reader = new InMemoryXMLStreamReader(ownerDoc, ownerDoc);
} else {
final NodeProxy proxy = (NodeProxy) nv;
reader = getBroker().newXMLStreamReader(new NodeProxy(proxy.getOwnerDocument(), NodeId.DOCUMENT_NODE, proxy.getOwnerDocument().getFirstChildAddress()), false);
}
return reader;
}
use of org.exist.dom.memtree.NodeImpl in project exist by eXist-db.
the class HighlightMatches method eval.
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
if (args[0].isEmpty())
return Sequence.EMPTY_SEQUENCE;
context.pushDocumentContext();
final Serializer serializer = context.getBroker().borrowSerializer();
try (FunctionReference func = (FunctionReference) args[1].itemAt(0)) {
MemTreeBuilder builder = context.getDocumentBuilder();
NGramIndexWorker index = (NGramIndexWorker) context.getBroker().getIndexController().getWorkerByIndexId(NGramIndex.ID);
DocumentBuilderReceiver docBuilder = new DocumentBuilderReceiver(builder);
MatchCallback matchCb = new MatchCallback(func, docBuilder);
ValueSequence result = new ValueSequence();
for (SequenceIterator i = args[0].iterate(); i.hasNext(); ) {
NodeValue v = (NodeValue) i.nextItem();
try {
int nodeNr = builder.getDocument().getLastNode();
if (v.getImplementationType() == NodeValue.IN_MEMORY_NODE) {
((NodeImpl) v).copyTo(context.getBroker(), docBuilder);
} else {
NodeProxy p = (NodeProxy) v;
MatchListener ml = index.getMatchListener(context.getBroker(), p, matchCb);
Receiver receiver;
if (ml == null)
receiver = docBuilder;
else {
ml.setNextInChain(docBuilder);
receiver = ml;
}
serializer.setReceiver(receiver);
serializer.toReceiver((NodeProxy) v, false);
}
result.add(builder.getDocument().getNode(++nodeNr));
} catch (SAXException e) {
LOG.warn(e.getMessage(), e);
throw new XPathException(this, e.getMessage());
}
}
return result;
} finally {
context.getBroker().returnSerializer(serializer);
context.popDocumentContext();
}
}
use of org.exist.dom.memtree.NodeImpl in project exist by eXist-db.
the class ElementConstructor method eval.
@Override
public Sequence eval(final Sequence contextSequence, final Item contextItem) throws XPathException {
context.expressionStart(this);
context.pushInScopeNamespaces();
if (newDocumentContext) {
context.pushDocumentContext();
}
try {
final MemTreeBuilder builder = context.getDocumentBuilder();
// declare namespaces
if (namespaceDecls != null) {
for (QName namespaceDecl : namespaceDecls) {
// if ("".equals(namespaceDecls[i].getNamespaceURI())) {
// TODO: the specs are unclear here: should we throw XQST0085 or not?
// context.inScopeNamespaces.remove(namespaceDecls[i].getLocalPart());
// if (context.inScopeNamespaces.remove(namespaceDecls[i].getLocalPart()) == null)
// throw new XPathException(getAS TNode(), "XQST0085 : can not undefine '" + namespaceDecls[i] + "'");
// } else
context.declareInScopeNamespace(namespaceDecl.getLocalPart(), namespaceDecl.getNamespaceURI());
}
}
// process attributes
final AttributesImpl attrs = new AttributesImpl();
if (attributes != null) {
// first, search for xmlns attributes and declare in-scope namespaces
for (final AttributeConstructor constructor : attributes) {
if (constructor.isNamespaceDeclaration()) {
final int p = constructor.getQName().indexOf(':');
if (p == Constants.STRING_NOT_FOUND) {
context.declareInScopeNamespace(XMLConstants.DEFAULT_NS_PREFIX, constructor.getLiteralValue());
} else {
final String prefix = constructor.getQName().substring(p + 1);
context.declareInScopeNamespace(prefix, constructor.getLiteralValue());
}
}
}
String v = null;
// process the remaining attributes
for (int i = 0; i < attributes.length; i++) {
context.proceed(this, builder);
final AttributeConstructor constructor = attributes[i];
final Sequence attrValues = constructor.eval(contextSequence, contextItem);
QName attrQName;
try {
attrQName = QName.parse(context, constructor.getQName(), XMLConstants.NULL_NS_URI);
} catch (final QName.IllegalQNameException e) {
throw new XPathException(this, ErrorCodes.XPTY0004, "'" + constructor.getQName() + "' is not a valid attribute name");
}
final String namespaceURI = attrQName.getNamespaceURI();
if (namespaceURI != null && !namespaceURI.isEmpty() && attrQName.getPrefix() == null) {
String prefix = context.getPrefixForURI(namespaceURI);
if (prefix != null) {
attrQName = new QName(attrQName.getLocalPart(), attrQName.getNamespaceURI(), prefix);
} else {
// generate prefix
for (final int n = 1; i < 100; i++) {
prefix = "eXnsp" + n;
if (context.getURIForPrefix(prefix) == null) {
attrQName = new QName(attrQName.getLocalPart(), attrQName.getNamespaceURI(), prefix);
break;
}
prefix = null;
}
if (prefix == null) {
throw new XPathException(this, "Prefix can't be generated.");
}
}
}
if (attrs.getIndex(attrQName.getNamespaceURI(), attrQName.getLocalPart()) != -1) {
throw new XPathException(this, ErrorCodes.XQST0040, "'" + attrQName.getLocalPart() + "' is a duplicate attribute name");
}
v = DynamicAttributeConstructor.normalize(this, attrQName, attrValues.getStringValue());
attrs.addAttribute(attrQName.getNamespaceURI(), attrQName.getLocalPart(), attrQName.getStringValue(), "CDATA", v);
}
}
context.proceed(this, builder);
// create the element
final Sequence qnameSeq = qnameExpr.eval(contextSequence, contextItem);
if (!qnameSeq.hasOne()) {
throw new XPathException(this, ErrorCodes.XPTY0004, "Type error: the node name should evaluate to a single item");
}
final Item qnitem = qnameSeq.itemAt(0);
QName qn;
if (qnitem instanceof QNameValue) {
qn = ((QNameValue) qnitem).getQName();
} else {
// Do we have the same result than Atomize there ? -pb
try {
qn = QName.parse(context, qnitem.getStringValue());
} catch (final QName.IllegalQNameException e) {
throw new XPathException(this, ErrorCodes.XPTY0004, "'" + qnitem.getStringValue() + "' is not a valid element name");
} catch (final XPathException e) {
e.setLocation(getLine(), getColumn(), getSource());
throw e;
}
/*
if (qn.getPrefix() == null && context.inScopeNamespaces.get("xmlns") != null) {
qn.setNamespaceURI((String)context.inScopeNamespaces.get("xmlns"));
}
*/
if (qn.getPrefix() == null && context.getInScopeNamespace(XMLConstants.DEFAULT_NS_PREFIX) != null) {
qn = new QName(qn.getLocalPart(), context.getInScopeNamespace(XMLConstants.DEFAULT_NS_PREFIX), qn.getPrefix());
}
}
// Not in the specs but... makes sense
if (!XMLNames.isName(qn.getLocalPart())) {
throw new XPathException(this, ErrorCodes.XPTY0004, "'" + qnitem.getStringValue() + "' is not a valid element name");
}
// add namespace declaration nodes
final int nodeNr = builder.startElement(qn, attrs);
if (namespaceDecls != null) {
for (QName namespaceDecl : namespaceDecls) {
builder.namespaceNode(namespaceDecl);
}
}
// do we need to add a namespace declaration for the current node?
if (qn.hasNamespace()) {
if (context.getInScopePrefix(qn.getNamespaceURI()) == null) {
String prefix = qn.getPrefix();
if (prefix == null) {
prefix = XMLConstants.DEFAULT_NS_PREFIX;
}
context.declareInScopeNamespace(prefix, qn.getNamespaceURI());
builder.namespaceNode(new QName(prefix, qn.getNamespaceURI(), XMLConstants.XMLNS_ATTRIBUTE));
}
} else if ((qn.getPrefix() == null || qn.getPrefix().length() == 0) && context.getInheritedNamespace(XMLConstants.DEFAULT_NS_PREFIX) != null) {
context.declareInScopeNamespace(XMLConstants.DEFAULT_NS_PREFIX, XMLConstants.NULL_NS_URI);
builder.namespaceNode(new QName("", XMLConstants.NULL_NS_URI, XMLConstants.XMLNS_ATTRIBUTE));
} else if (qn.getPrefix() == null || qn.getPrefix().length() == 0) {
context.declareInScopeNamespace(XMLConstants.DEFAULT_NS_PREFIX, XMLConstants.NULL_NS_URI);
}
// process element contents
if (content != null) {
content.eval(contextSequence, contextItem);
}
builder.endElement();
final NodeImpl node = builder.getDocument().getNode(nodeNr);
return node;
} finally {
context.popInScopeNamespaces();
if (newDocumentContext) {
context.popDocumentContext();
}
context.expressionEnd(this);
}
}
use of org.exist.dom.memtree.NodeImpl in project exist by eXist-db.
the class DocumentConstructor method eval.
/* (non-Javadoc)
* @see org.exist.xquery.Expression#eval(org.exist.xquery.value.Sequence, org.exist.xquery.value.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());
}
}
context.pushDocumentContext();
final Sequence contentSeq = content.eval(contextSequence, contextItem);
context.popDocumentContext();
context.pushDocumentContext();
final MemTreeBuilder builder = context.getDocumentBuilder(true);
final DocumentBuilderReceiver receiver = new DocumentBuilderReceiver(builder);
try {
if (!contentSeq.isEmpty()) {
StringBuilder buf = null;
final SequenceIterator i = contentSeq.iterate();
Item next = i.nextItem();
while (next != null) {
context.proceed(this, builder);
if (next.getType() == Type.ATTRIBUTE || next.getType() == Type.NAMESPACE) {
throw new XPathException(this, "Found a node of type " + Type.getTypeName(next.getType()) + " inside a document constructor");
}
// following atomic values and seperate them by a space.
if (Type.subTypeOf(next.getType(), Type.ATOMIC)) {
if (buf == null) {
buf = new StringBuilder();
} else if (buf.length() > 0) {
buf.append(' ');
}
buf.append(next.getStringValue());
next = i.nextItem();
// if item is a node, flush any collected character data and
// copy the node to the target doc.
} else if (next.getType() == Type.DOCUMENT) {
if (buf != null && buf.length() > 0) {
receiver.characters(buf);
buf.setLength(0);
}
next.copyTo(context.getBroker(), receiver);
next = i.nextItem();
} else if (Type.subTypeOf(next.getType(), Type.NODE)) {
if (buf != null && buf.length() > 0) {
receiver.characters(buf);
buf.setLength(0);
}
next.copyTo(context.getBroker(), receiver);
next = i.nextItem();
}
}
// flush remaining character data
if (buf != null && buf.length() > 0) {
receiver.characters(buf);
buf.setLength(0);
}
}
} catch (final SAXException e) {
throw new XPathException(this, "Encountered SAX exception while processing document constructor: " + ExpressionDumper.dump(this));
}
context.popDocumentContext();
final NodeImpl node = builder.getDocument();
if (context.getProfiler().isEnabled()) {
context.getProfiler().end(this, "", node);
}
return node;
}
use of org.exist.dom.memtree.NodeImpl in project exist by eXist-db.
the class CDATAConstructor 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());
}
}
if (newDocumentContext) {
context.pushDocumentContext();
}
try {
final MemTreeBuilder builder = context.getDocumentBuilder();
final NodeImpl node = builder.getDocument().getNode(builder.cdataSection(cdata));
if (context.getProfiler().isEnabled()) {
context.getProfiler().end(this, "", node);
}
return node;
} finally {
if (newDocumentContext) {
context.popDocumentContext();
}
}
}
Aggregations