Search in sources :

Example 36 with DescendantAxis

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;
}
Also used : XdmNodeReadTrx(org.sirix.api.XdmNodeReadTrx) DescendantAxis(org.sirix.axis.DescendantAxis) Axis(org.sirix.api.Axis) DescendantAxis(org.sirix.axis.DescendantAxis)

Example 37 with DescendantAxis

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());
}
Also used : TextFilter(org.sirix.axis.filter.TextFilter) XdmNodeReadTrx(org.sirix.api.XdmNodeReadTrx) XMLStreamException(javax.xml.stream.XMLStreamException) DescendantAxis(org.sirix.axis.DescendantAxis) FilterAxis(org.sirix.axis.filter.FilterAxis)

Example 38 with DescendantAxis

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;
}
Also used : NameFilter(org.sirix.axis.filter.NameFilter) BitSet(java.util.BitSet) DescendantAxis(org.sirix.axis.DescendantAxis) FilterAxis(org.sirix.axis.filter.FilterAxis)

Example 39 with DescendantAxis

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);
    }
}
Also used : ImmutableNameNode(org.sirix.node.interfaces.immutable.ImmutableNameNode) NameNode(org.sirix.node.interfaces.NameNode) PathLevelFilter(org.sirix.axis.filter.PathLevelFilter) UnorderedKeyValuePage(org.sirix.page.UnorderedKeyValuePage) ElementNode(org.sirix.node.ElementNode) FilterAxis(org.sirix.axis.filter.FilterAxis) NameFilter(org.sirix.axis.filter.NameFilter) ImmutableNameNode(org.sirix.node.interfaces.immutable.ImmutableNameNode) DescendantAxis(org.sirix.axis.DescendantAxis) Axis(org.sirix.api.Axis) ChildAxis(org.sirix.axis.ChildAxis) PostOrderAxis(org.sirix.axis.PostOrderAxis) FilterAxis(org.sirix.axis.filter.FilterAxis) DescendantAxis(org.sirix.axis.DescendantAxis) LevelOrderAxis(org.sirix.axis.LevelOrderAxis) PathKindFilter(org.sirix.axis.filter.PathKindFilter)

Example 40 with DescendantAxis

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();
}
Also used : QNm(org.brackit.xquery.atomic.QNm) XdmNodeReadTrx(org.sirix.api.XdmNodeReadTrx) SirixException(org.sirix.exception.SirixException) SirixUsageException(org.sirix.exception.SirixUsageException) VisitorDescendantAxis(org.sirix.axis.visitor.VisitorDescendantAxis) DescendantAxis(org.sirix.axis.DescendantAxis) Axis(org.sirix.api.Axis) VisitorDescendantAxis(org.sirix.axis.visitor.VisitorDescendantAxis) AbstractAxis(org.sirix.axis.AbstractAxis) ChildAxis(org.sirix.axis.ChildAxis) PostOrderAxis(org.sirix.axis.PostOrderAxis) DescendantAxis(org.sirix.axis.DescendantAxis) LevelOrderAxis(org.sirix.axis.LevelOrderAxis)

Aggregations

DescendantAxis (org.sirix.axis.DescendantAxis)44 Axis (org.sirix.api.Axis)27 Test (org.junit.Test)18 XdmNodeReadTrx (org.sirix.api.XdmNodeReadTrx)17 FilterAxis (org.sirix.axis.filter.FilterAxis)16 ChildAxis (org.sirix.axis.ChildAxis)14 QNm (org.brackit.xquery.atomic.QNm)7 XdmNodeWriteTrx (org.sirix.api.XdmNodeWriteTrx)7 NonStructuralWrapperAxis (org.sirix.axis.NonStructuralWrapperAxis)7 NameFilter (org.sirix.axis.filter.NameFilter)7 NestedAxis (org.sirix.axis.NestedAxis)6 PostOrderAxis (org.sirix.axis.PostOrderAxis)6 PathSummaryReader (org.sirix.index.path.summary.PathSummaryReader)6 AbstractAxis (org.sirix.axis.AbstractAxis)5 AncestorAxis (org.sirix.axis.AncestorAxis)5 FollowingAxis (org.sirix.axis.FollowingAxis)5 FollowingSiblingAxis (org.sirix.axis.FollowingSiblingAxis)5 LevelOrderAxis (org.sirix.axis.LevelOrderAxis)5 ParentAxis (org.sirix.axis.ParentAxis)5 PrecedingAxis (org.sirix.axis.PrecedingAxis)5