use of org.exist.dom.memtree.DocumentImpl in project exist by eXist-db.
the class ValueSequence method expand.
/**
* Scan the sequence and check all in-memory documents.
* They may contains references to nodes stored in the database.
* Expand those references to get a pure in-memory DOM tree.
*/
private void expand() {
final Set<DocumentImpl> docs = new HashSet<>();
for (int i = 0; i <= size; i++) {
final NodeImpl node = (NodeImpl) values[i];
final DocumentImpl ownerDoc = node.getNodeType() == Node.DOCUMENT_NODE ? (DocumentImpl) node : node.getOwnerDocument();
if (ownerDoc.hasReferenceNodes()) {
docs.add(ownerDoc);
}
}
for (final DocumentImpl doc : docs) {
doc.expand();
}
}
use of org.exist.dom.memtree.DocumentImpl in project exist by eXist-db.
the class ValueSequence method toNodeSet.
/**
* Makes all in-memory nodes in this sequence persistent,
* so they can be handled like other node sets.
*
* @see org.exist.xquery.value.Sequence#toNodeSet()
*/
@Override
public NodeSet toNodeSet() throws XPathException {
if (size == UNSET_SIZE) {
return NodeSet.EMPTY_SET;
}
// for this method to work, all items have to be nodes
if (itemType != Type.ANY_TYPE && Type.subTypeOf(itemType, Type.NODE)) {
final NodeSet set = new NewArrayNodeSet();
for (int i = 0; i <= size; i++) {
NodeValue v = (NodeValue) values[i];
if (v.getImplementationType() != NodeValue.PERSISTENT_NODE) {
// found an in-memory document
final DocumentImpl doc;
if (v.getType() == Type.DOCUMENT) {
doc = (DocumentImpl) v;
} else {
doc = ((NodeImpl) v).getOwnerDocument();
}
if (doc == null) {
continue;
}
// make this document persistent: doc.makePersistent()
// returns a map of all root node ids mapped to the corresponding
// persistent node. We scan the current sequence and replace all
// in-memory nodes with their new persistent node objects.
final DocumentImpl expandedDoc = doc.expandRefs(null);
final org.exist.dom.persistent.DocumentImpl newDoc = expandedDoc.makePersistent();
if (newDoc != null) {
NodeId rootId = newDoc.getBrokerPool().getNodeFactory().createInstance();
for (int j = i; j <= size; j++) {
v = (NodeValue) values[j];
if (v.getImplementationType() != NodeValue.PERSISTENT_NODE) {
NodeImpl node = (NodeImpl) v;
final Document nodeOwnerDoc;
if (node.getNodeType() == Node.DOCUMENT_NODE) {
nodeOwnerDoc = (Document) node;
} else {
nodeOwnerDoc = node.getOwnerDocument();
}
if (nodeOwnerDoc == doc) {
if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
node = expandedDoc.getAttribute(node.getNodeNumber());
} else {
node = expandedDoc.getNode(node.getNodeNumber());
}
NodeId nodeId = node.getNodeId();
if (nodeId == null) {
throw new XPathException("Internal error: nodeId == null");
}
if (node.getNodeType() == Node.DOCUMENT_NODE) {
nodeId = rootId;
} else {
nodeId = rootId.append(nodeId);
}
final NodeProxy p = new NodeProxy(newDoc, nodeId, node.getNodeType());
// replace the node by the NodeProxy
values[j] = p;
}
}
}
set.add((NodeProxy) values[i]);
}
} else {
set.add((NodeProxy) v);
}
}
if (holderVar != null) {
holderVar.setValue(set);
}
return set;
} else {
throw new XPathException("Type error: the sequence cannot be converted into" + " a node set. Item type is " + Type.getTypeName(itemType));
}
}
use of org.exist.dom.memtree.DocumentImpl in project exist by eXist-db.
the class ArrayListValueSequence method toNodeSet.
@Override
public NodeSet toNodeSet() throws XPathException {
if (isEmpty) {
return NodeSet.EMPTY_SET;
}
// for this method to work, all items have to be nodes
if (itemType != Type.ANY_TYPE && Type.subTypeOf(itemType, Type.NODE)) {
final NodeSet set = new NewArrayNodeSet();
for (int i = 0; i <= values.size(); i++) {
NodeValue v = (NodeValue) values.get(i);
if (v.getImplementationType() != NodeValue.PERSISTENT_NODE) {
// found an in-memory document
final DocumentImpl doc;
if (v.getType() == Type.DOCUMENT) {
doc = (DocumentImpl) v;
} else {
doc = ((NodeImpl) v).getOwnerDocument();
}
if (doc == null) {
continue;
}
// make this document persistent: doc.makePersistent()
// returns a map of all root node ids mapped to the corresponding
// persistent node. We scan the current sequence and replace all
// in-memory nodes with their new persistent node objects.
final DocumentImpl expandedDoc = doc.expandRefs(null);
final org.exist.dom.persistent.DocumentImpl newDoc = expandedDoc.makePersistent();
if (newDoc != null) {
NodeId rootId = newDoc.getBrokerPool().getNodeFactory().createInstance();
for (int j = i; j <= values.size(); j++) {
v = (NodeValue) values.get(j);
if (v.getImplementationType() != NodeValue.PERSISTENT_NODE) {
NodeImpl node = (NodeImpl) v;
final Document nodeOwnerDoc;
if (node.getNodeType() == Node.DOCUMENT_NODE) {
nodeOwnerDoc = (Document) node;
} else {
nodeOwnerDoc = node.getOwnerDocument();
}
if (nodeOwnerDoc == doc) {
if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
node = expandedDoc.getAttribute(node.getNodeNumber());
} else {
node = expandedDoc.getNode(node.getNodeNumber());
}
NodeId nodeId = node.getNodeId();
if (nodeId == null) {
throw new XPathException("Internal error: nodeId == null");
}
if (node.getNodeType() == Node.DOCUMENT_NODE) {
nodeId = rootId;
} else {
nodeId = rootId.append(nodeId);
}
final NodeProxy p = new NodeProxy(newDoc, nodeId, node.getNodeType());
// replace the node by the NodeProxy
values.set(j, p);
setHasChanged();
}
}
}
set.add((NodeProxy) values.get(i));
}
} else {
set.add((NodeProxy) v);
}
}
// }
return set;
} else {
throw new XPathException("Type error: the sequence cannot be converted into" + " a node set. Item type is " + Type.getTypeName(itemType));
}
}
use of org.exist.dom.memtree.DocumentImpl in project exist by eXist-db.
the class SubSequence method makePersistent.
@Nullable
private NodeProxy makePersistent(NodeImpl node, final Map<DocumentImpl, Tuple2<DocumentImpl, org.exist.dom.persistent.DocumentImpl>> expandedDocs) throws XPathException {
// found an in-memory document
final DocumentImpl doc;
if (node.getType() == Type.DOCUMENT) {
doc = (DocumentImpl) node;
} else {
doc = node.getOwnerDocument();
}
if (doc == null) {
return null;
}
final DocumentImpl expandedDoc;
final org.exist.dom.persistent.DocumentImpl newDoc;
if (expandedDocs.containsKey(doc)) {
final Tuple2<DocumentImpl, org.exist.dom.persistent.DocumentImpl> expandedDocNewDoc = expandedDocs.get(doc);
expandedDoc = expandedDocNewDoc._1;
newDoc = expandedDocNewDoc._2;
} else {
// make this document persistent: doc.makePersistent()
// returns a map of all root node ids mapped to the corresponding
// persistent node. We scan the current sequence and replace all
// in-memory nodes with their new persistent node objects.
expandedDoc = doc.expandRefs(null);
newDoc = expandedDoc.makePersistent();
expandedDocs.put(doc, Tuple(expandedDoc, newDoc));
}
if (newDoc != null) {
final NodeId rootId = newDoc.getBrokerPool().getNodeFactory().createInstance();
if (node.getImplementationType() != NodeValue.PERSISTENT_NODE) {
final Document nodeOwnerDoc;
if (node.getNodeType() == Node.DOCUMENT_NODE) {
nodeOwnerDoc = (Document) node;
} else {
nodeOwnerDoc = node.getOwnerDocument();
}
if (nodeOwnerDoc == doc) {
if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
node = expandedDoc.getAttribute(node.getNodeNumber());
} else {
node = expandedDoc.getNode(node.getNodeNumber());
}
NodeId nodeId = node.getNodeId();
if (nodeId == null) {
throw new XPathException("Internal error: nodeId == null");
}
if (node.getNodeType() == Node.DOCUMENT_NODE) {
nodeId = rootId;
} else {
nodeId = rootId.append(nodeId);
}
final NodeProxy p = new NodeProxy(newDoc, nodeId, node.getNodeType());
// replace the node by the NodeProxy
return p;
}
}
}
return null;
}
use of org.exist.dom.memtree.DocumentImpl in project exist by eXist-db.
the class SubSequence method toMemNodeSet.
@Override
public MemoryNodeSet toMemNodeSet() throws XPathException {
if (isEmpty()) {
return MemoryNodeSet.EMPTY;
}
final ValueSequence memNodeSet = new ValueSequence(getItemCount());
final Set<DocumentImpl> expandedDocs = new HashSet<>();
final SequenceIterator iterator = iterate();
while (iterator.hasNext()) {
final Item item = iterator.nextItem();
if (!Type.subTypeOf(item.getType(), Type.NODE)) {
throw new XPathException("Type error: the sub-sequence cannot be converted into" + " a MemoryNodeSet. It contains items which are not nodes");
}
final NodeValue v = (NodeValue) item;
if (v.getImplementationType() == NodeValue.PERSISTENT_NODE) {
throw new XPathException("Type error: the sub-sequence cannot be converted into" + " a MemoryNodeSet. It contains nodes from stored resources.");
}
final org.exist.dom.memtree.NodeImpl node = (org.exist.dom.memtree.NodeImpl) item;
final DocumentImpl ownerDoc = node.getNodeType() == Node.DOCUMENT_NODE ? (DocumentImpl) node : node.getOwnerDocument();
if (ownerDoc.hasReferenceNodes() && !expandedDocs.contains(ownerDoc)) {
ownerDoc.expand();
expandedDocs.add(ownerDoc);
}
memNodeSet.add(node);
}
return memNodeSet;
}
Aggregations