use of org.sirix.axis.DescendantAxis in project sirix by sirixdb.
the class AbstractSerializer method call.
/**
* Serialize the storage.
*
* @return null.
* @throws SirixException if can't call serailzer
*/
@Override
public Void call() throws SirixException {
emitStartDocument();
final int nrOfRevisions = mRevisions.length;
final int length = (nrOfRevisions == 1 && mRevisions[0] < 0) ? (int) mSession.getMostRecentRevisionNumber() : nrOfRevisions;
if (length > 1) {
emitStartManualRootElement();
}
for (int i = 1; i <= length; i++) {
try (final XdmNodeReadTrx rtx = mSession.beginNodeReadTrx((nrOfRevisions == 1 && mRevisions[0] < 0) ? i : mRevisions[i - 1])) {
if (length > 1) {
emitStartManualElement(i);
}
rtx.moveTo(mNodeKey);
final Axis descAxis = new DescendantAxis(rtx, IncludeSelf.YES);
// Setup primitives.
boolean closeElements = false;
long key = rtx.getNodeKey();
// Iterate over all nodes of the subtree including self.
while (descAxis.hasNext()) {
key = descAxis.next();
// Emit all pending end elements.
if (closeElements) {
while (!mStack.isEmpty() && mStack.peek() != rtx.getLeftSiblingKey()) {
rtx.moveTo(mStack.pop());
emitEndElement(rtx);
rtx.moveTo(key);
}
if (!mStack.isEmpty()) {
rtx.moveTo(mStack.pop());
emitEndElement(rtx);
}
rtx.moveTo(key);
closeElements = false;
}
// Emit node.
emitStartElement(rtx);
// children.
if (rtx.getKind() == Kind.ELEMENT && rtx.hasFirstChild()) {
mStack.push(rtx.getNodeKey());
}
// required.
if (!rtx.hasFirstChild() && !rtx.hasRightSibling()) {
closeElements = true;
}
}
// Finally emit all pending end elements.
while (!mStack.isEmpty()) {
rtx.moveTo(mStack.pop());
emitEndElement(rtx);
}
if (length > 1) {
emitEndManualElement(i);
}
}
}
if (length > 1) {
emitEndManualRootElement();
}
emitEndDocument();
return null;
}
use of org.sirix.axis.DescendantAxis in project sirix by sirixdb.
the class StAXSerializer method getElementText.
@Override
public String getElementText() throws XMLStreamException {
final XdmNodeReadTrx rtx = mAxis.getTrx();
final long nodeKey = rtx.getNodeKey();
/*
* The cursor has to move back (once) after determining, that a closing tag would be the next
* event (precond: closeElement and either goBack or goUp is true).
*/
if (mCloseElements && mToLastKey) {
rtx.moveTo(mLastKey);
}
if (mEvent.getEventType() != XMLStreamConstants.START_ELEMENT) {
rtx.moveTo(nodeKey);
throw new XMLStreamException("getElementText() only can be called on a start element");
}
final FilterAxis textFilterAxis = new FilterAxis(new DescendantAxis(rtx), new TextFilter(rtx));
final StringBuilder strBuilder = new StringBuilder();
while (textFilterAxis.hasNext()) {
textFilterAxis.next();
strBuilder.append(rtx.getValue());
}
rtx.moveTo(nodeKey);
return XMLToken.escapeContent(strBuilder.toString());
}
use of org.sirix.axis.DescendantAxis in project sirix by sirixdb.
the class PathSummaryReader method matchDescendants.
/**
* Match all descendants of the node denoted by its {@code pathNodeKey} with the given
* {@code name}.
*
* @param name the QName
* @param pathNodeKey the path node key to start the search from
* @param inclSelf
* @return a set with bits set for each matching path node (its {@code pathNodeKey})
*/
public BitSet matchDescendants(final QNm name, @Nonnegative final long pathNodeKey, final IncludeSelf inclSelf) {
assertNotClosed();
final Set<PathNode> set = mQNmMapping.get(name);
if (set == null) {
return new BitSet(0);
}
moveTo(pathNodeKey);
final BitSet matches = new BitSet();
for (final long nodeKey : new FilterAxis(new DescendantAxis(this, inclSelf), new NameFilter(this, name.toString()))) {
matches.set((int) nodeKey);
}
return matches;
}
use of org.sirix.axis.DescendantAxis in project sirix by sirixdb.
the class PathSummaryWriter method processFoundPathNode.
/**
* Process a found path node.
*
* @param oldPathNodeKey key of old path node
* @param newPathNodeKey key of new path node
* @param oldNodeKey key of old node
* @param uriKey key of URI
* @param prefixKey key of prefix
* @param localNameKey key of local name
* @param remove determines if a {@link PathNode} must be removed or not
* @param type type of operation
* @throws SirixException if Sirix fails to do so
*/
private void processFoundPathNode(@Nonnegative final long oldPathNodeKey, @Nonnegative final long newPathNodeKey, @Nonnegative final long oldNodeKey, final int uriKey, final int prefixKey, final int localNameKey, final Remove remove, final OPType type) throws SirixException {
final PathSummaryReader cloned = PathSummaryReader.getInstance(mPageWriteTrx, mNodeRtx.getResourceManager());
boolean moved = cloned.moveTo(oldPathNodeKey).hasMoved();
assert moved;
// Set new reference count of the root.
if (type != OPType.MOVEDSAMELEVEL) {
final PathNode currNode = (PathNode) mPageWriteTrx.prepareEntryForModification(mPathSummaryReader.getNodeKey(), PageKind.PATHSUMMARYPAGE, 0, Optional.<UnorderedKeyValuePage>empty());
currNode.setReferenceCount(currNode.getReferences() + cloned.getReferences());
currNode.setLocalNameKey(localNameKey);
currNode.setPrefixKey(prefixKey);
currNode.setURIKey(uriKey);
}
// For all old path nodes: Merge paths and adapt reference counts.
mPathSummaryReader.moveToFirstChild();
final int oldLevel = cloned.getLevel();
for (final Axis oldDescendants = new DescendantAxis(cloned); oldDescendants.hasNext(); ) {
oldDescendants.next();
// Search for new path entry.
final Axis axis = new FilterAxis(new LevelOrderAxis.Builder(mPathSummaryReader).filterLevel(cloned.getLevel() - oldLevel).includeSelf().build(), new NameFilter(mPathSummaryReader, Utils.buildName(cloned.getName())), new PathKindFilter(mPathSummaryReader, cloned.getPathKind()), new PathLevelFilter(mPathSummaryReader, cloned.getLevel()));
if (axis.hasNext()) {
axis.next();
// Set new reference count.
if (type != OPType.MOVEDSAMELEVEL) {
final PathNode currNode = (PathNode) mPageWriteTrx.prepareEntryForModification(mPathSummaryReader.getNodeKey(), PageKind.PATHSUMMARYPAGE, 0, Optional.<UnorderedKeyValuePage>empty());
currNode.setReferenceCount(currNode.getReferences() + cloned.getReferences());
}
} else {
// Insert new node.
insertPathAsFirstChild(cloned.getName(), cloned.getPathKind(), mPathSummaryReader.getLevel() + 1);
// Set new reference count.
final PathNode currNode = (PathNode) mPageWriteTrx.prepareEntryForModification(mPathSummaryReader.getNodeKey(), PageKind.PATHSUMMARYPAGE, 0, Optional.<UnorderedKeyValuePage>empty());
currNode.setReferenceCount(cloned.getReferences());
}
mPathSummaryReader.moveTo(newPathNodeKey);
}
// Set new path nodes of the changed nodes, that is set their PCR
// references.
mPathSummaryReader.moveTo(newPathNodeKey);
mNodeRtx.moveTo(oldNodeKey);
boolean first = true;
for (final Axis axis = new DescendantAxis(mNodeRtx, IncludeSelf.YES); axis.hasNext(); ) {
axis.next();
if (first && type == OPType.SETNAME) {
first = false;
} else if (mNodeRtx.getNode() instanceof ImmutableNameNode) {
cloned.moveTo(((NameNode) mNodeRtx.getCurrentNode()).getPathNodeKey());
resetPath(newPathNodeKey, cloned.getLevel());
if (mNodeRtx.getNode().getKind() == Kind.ELEMENT) {
final ElementNode element = (ElementNode) mNodeRtx.getCurrentNode();
for (int i = 0, nspCount = element.getNamespaceCount(); i < nspCount; i++) {
mNodeRtx.moveToNamespace(i);
cloned.moveTo(((NameNode) mNodeRtx.getCurrentNode()).getPathNodeKey());
resetPath(newPathNodeKey, cloned.getLevel());
mNodeRtx.moveToParent();
}
for (int i = 0, attCount = element.getAttributeCount(); i < attCount; i++) {
mNodeRtx.moveToAttribute(i);
cloned.moveTo(((NameNode) mNodeRtx.getCurrentNode()).getPathNodeKey());
resetPath(newPathNodeKey, cloned.getLevel());
mNodeRtx.moveToParent();
}
}
}
}
// Then: Remove old nodes.
if (remove == Remove.YES) {
mPathSummaryReader.moveTo(oldPathNodeKey);
removePathSummaryNode(remove);
}
}
use of org.sirix.axis.DescendantAxis in project sirix by sirixdb.
the class FMSE method emitInsert.
/**
* Emit an insert operation.
*
* @param parent parent of the current {@link Node} implementation reference to insert
* @param child the current node to insert
* @param pos position of the insert
* @param wtx {@link XdmNodeWriteTrx} implementation reference on old revision
* @param rtx {@link XdmNodeReadTrx} implementation reference on new revision
* @return inserted {@link Node} implementation reference
* @throws SirixException if anything in sirix fails
*/
private long emitInsert(final long child, final long parent, final int pos, final XdmNodeWriteTrx wtx, final XdmNodeReadTrx rtx) {
assert child >= 0;
assert parent >= 0;
assert wtx != null;
assert rtx != null;
// Determines if node has been already inserted (for subtrees).
if (mAlreadyInserted.get(child) != null) {
// actually child'
return child;
}
wtx.moveTo(parent);
rtx.moveTo(child);
try {
switch(rtx.getKind()) {
case ATTRIBUTE:
try {
wtx.insertAttribute(rtx.getName(), rtx.getValue());
} catch (final SirixUsageException e) {
mTotalMatching.remove(wtx.getNodeKey());
wtx.setValue(rtx.getValue());
}
process(wtx.getNodeKey(), rtx.getNodeKey());
break;
case NAMESPACE:
// Note that the insertion is right (localPart as prefix).
try {
wtx.insertNamespace(new QNm(rtx.getName().getNamespaceURI(), rtx.getName().getLocalName(), ""));
} catch (final SirixUsageException e) {
mTotalMatching.remove(wtx.getNodeKey());
}
process(wtx.getNodeKey(), rtx.getNodeKey());
break;
default:
// In case of other node types.
long oldKey = 0;
if (pos == 0) {
switch(rtx.getKind()) {
case ELEMENT:
oldKey = wtx.copySubtreeAsFirstChild(rtx).getNodeKey();
break;
case TEXT:
// is inserted.
if (wtx.hasFirstChild()) {
wtx.moveToFirstChild();
if (wtx.getKind() == Kind.TEXT) {
mTotalMatching.remove(wtx.getNodeKey());
wtx.remove();
}
wtx.moveTo(parent);
}
oldKey = wtx.insertTextAsFirstChild(rtx.getValue()).getNodeKey();
break;
default:
}
} else {
assert wtx.hasFirstChild();
wtx.moveToFirstChild();
for (int i = 0; i < pos - 1; i++) {
assert wtx.hasRightSibling();
wtx.moveToRightSibling();
}
// Remove right sibl. text node if a text node already exists.
removeRightSiblingTextNode(wtx);
switch(rtx.getKind()) {
case ELEMENT:
oldKey = wtx.copySubtreeAsRightSibling(rtx).getNodeKey();
break;
case TEXT:
oldKey = wtx.insertTextAsRightSibling(rtx.getValue()).getNodeKey();
break;
default:
// Already inserted.
throw new IllegalStateException("Child should be already inserted!");
}
}
// Mark all nodes in subtree as inserted.
wtx.moveTo(oldKey);
rtx.moveTo(child);
for (final Axis oldAxis = new DescendantAxis(wtx, IncludeSelf.YES), newAxis = new DescendantAxis(rtx, IncludeSelf.YES); oldAxis.hasNext() && newAxis.hasNext(); ) {
oldAxis.next();
newAxis.next();
final XdmNodeReadTrx oldRtx = oldAxis.getTrx();
final XdmNodeReadTrx newRtx = newAxis.getTrx();
process(oldRtx.getNodeKey(), newRtx.getNodeKey());
final long newNodeKey = newRtx.getNodeKey();
final long oldNodeKey = oldRtx.getNodeKey();
if (newRtx.getKind() == Kind.ELEMENT) {
assert newRtx.getKind() == oldRtx.getKind();
if (newRtx.getAttributeCount() > 0) {
for (int i = 0, attCount = newRtx.getAttributeCount(); i < attCount; i++) {
rtx.moveToAttribute(i);
for (int j = 0, oldAttCount = oldRtx.getAttributeCount(); i < oldAttCount; j++) {
wtx.moveToAttribute(j);
if (wtx.getName().equals(rtx.getName())) {
process(oldAxis.getTrx().getNodeKey(), newAxis.getTrx().getNodeKey());
break;
}
oldAxis.getTrx().moveTo(oldNodeKey);
}
newAxis.getTrx().moveTo(newNodeKey);
}
}
if (newRtx.getNamespaceCount() > 0) {
for (int i = 0, nspCount = newRtx.getNamespaceCount(); i < nspCount; i++) {
rtx.moveToNamespace(i);
for (int j = 0, oldNspCount = oldRtx.getNamespaceCount(); j < oldNspCount; j++) {
wtx.moveToNamespace(j);
if (wtx.getName().getNamespaceURI().equals(rtx.getName().getNamespaceURI()) && wtx.getName().getPrefix().equals(wtx.getName().getPrefix())) {
process(wtx.getNodeKey(), rtx.getNodeKey());
break;
}
oldAxis.getTrx().moveTo(oldNodeKey);
}
newAxis.getTrx().moveTo(newNodeKey);
}
}
}
newAxis.getTrx().moveTo(newNodeKey);
}
}
} catch (final SirixException e) {
LOGWRAPPER.error(e.getMessage(), e);
}
return wtx.getNodeKey();
}
Aggregations