Search in sources :

Example 31 with StructNode

use of org.sirix.node.interfaces.StructNode in project sirix by sirixdb.

the class XdmNodeWriterTrxImpl method moveSubtreeToFirstChild.

@Override
public XdmNodeWriteTrx moveSubtreeToFirstChild(@Nonnegative final long fromKey) throws SirixException, IllegalArgumentException {
    acquireLock();
    try {
        Preconditions.checkArgument(fromKey >= 0 && fromKey <= getMaxNodeKey(), "Argument must be a valid node key!");
        Preconditions.checkArgument(fromKey != getCurrentNode().getNodeKey(), "Can't move itself to right sibling of itself!");
        @SuppressWarnings("unchecked") final Optional<? extends Node> node = (Optional<? extends Node>) getPageTransaction().getRecord(fromKey, PageKind.RECORDPAGE, -1);
        if (!node.isPresent()) {
            throw new IllegalStateException("Node to move must exist!");
        }
        final Node nodeToMove = node.get();
        if (nodeToMove instanceof StructNode && getCurrentNode().getKind() == Kind.ELEMENT) {
            // Safe to cast (because IStructNode is a subtype of INode).
            checkAncestors(nodeToMove);
            checkAccessAndCommit();
            final ElementNode nodeAnchor = (ElementNode) getCurrentNode();
            // Check that it's not already the first child.
            if (nodeAnchor.getFirstChildKey() != nodeToMove.getNodeKey()) {
                final StructNode toMove = (StructNode) nodeToMove;
                // Adapt index-structures (before move).
                adaptSubtreeForMove(toMove, ChangeType.DELETE);
                // Adapt hashes.
                adaptHashesForMove(toMove);
                // Adapt pointers and merge sibling text nodes.
                adaptForMove(toMove, nodeAnchor, InsertPos.ASFIRSTCHILD);
                mNodeReader.moveTo(toMove.getNodeKey());
                adaptHashesWithAdd();
                // Adapt path summary.
                if (mBuildPathSummary && toMove instanceof NameNode) {
                    final NameNode moved = (NameNode) toMove;
                    mPathSummaryWriter.adaptPathForChangedNode(moved, getName(), moved.getURIKey(), moved.getPrefixKey(), moved.getLocalNameKey(), OPType.MOVED);
                }
                // Adapt index-structures (after move).
                adaptSubtreeForMove(toMove, ChangeType.INSERT);
                // Compute and assign new DeweyIDs.
                if (mDeweyIDsStored) {
                    computeNewDeweyIDs();
                }
            }
            return this;
        } else {
            throw new SirixUsageException("Move is not allowed if moved node is not an ElementNode and the node isn't inserted at an element node!");
        }
    } finally {
        unLock();
    }
}
Also used : NameNode(org.sirix.node.interfaces.NameNode) Optional(java.util.Optional) TextNode(org.sirix.node.TextNode) CommentNode(org.sirix.node.CommentNode) PINode(org.sirix.node.PINode) Node(org.sirix.node.interfaces.Node) ValueNode(org.sirix.node.interfaces.ValueNode) AttributeNode(org.sirix.node.AttributeNode) ImmutableNode(org.sirix.node.interfaces.immutable.ImmutableNode) StructNode(org.sirix.node.interfaces.StructNode) ElementNode(org.sirix.node.ElementNode) NamespaceNode(org.sirix.node.NamespaceNode) NameNode(org.sirix.node.interfaces.NameNode) ElementNode(org.sirix.node.ElementNode) SirixUsageException(org.sirix.exception.SirixUsageException) StructNode(org.sirix.node.interfaces.StructNode)

Example 32 with StructNode

use of org.sirix.node.interfaces.StructNode in project sirix by sirixdb.

the class XdmNodeWriterTrxImpl method computeNewDeweyIDs.

/**
 * Compute the new DeweyIDs.
 *
 * @throws SirixException if anything went wrong
 */
private void computeNewDeweyIDs() throws SirixException {
    SirixDeweyID id = null;
    if (hasLeftSibling() && hasRightSibling()) {
        id = SirixDeweyID.newBetween(getLeftSiblingDeweyID().get(), getRightSiblingDeweyID().get());
    } else if (hasLeftSibling()) {
        id = SirixDeweyID.newBetween(getLeftSiblingDeweyID().get(), null);
    } else if (hasRightSibling()) {
        id = SirixDeweyID.newBetween(null, getRightSiblingDeweyID().get());
    } else {
        id = mNodeReader.getParentDeweyID().get().getNewChildID();
    }
    assert id != null;
    final long nodeKey = mNodeReader.getCurrentNode().getNodeKey();
    final StructNode root = (StructNode) getPageTransaction().prepareEntryForModification(nodeKey, PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
    root.setDeweyID(Optional.of(id));
    if (root.hasFirstChild()) {
        final Node firstChild = (Node) getPageTransaction().prepareEntryForModification(root.getFirstChildKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
        firstChild.setDeweyID(Optional.of(id.getNewChildID()));
        int previousLevel = getDeweyID().get().getLevel();
        mNodeReader.moveTo(firstChild.getNodeKey());
        int attributeNr = 0;
        int nspNr = 0;
        for (@SuppressWarnings("unused") final long key : LevelOrderAxis.newBuilder(this).includeNonStructuralNodes().build()) {
            Optional<SirixDeweyID> deweyID = Optional.<SirixDeweyID>empty();
            if (isAttribute()) {
                final long attNodeKey = mNodeReader.getNodeKey();
                if (attributeNr == 0) {
                    deweyID = Optional.of(mNodeReader.getParentDeweyID().get().getNewAttributeID());
                } else {
                    mNodeReader.moveTo(attributeNr - 1);
                    deweyID = Optional.of(SirixDeweyID.newBetween(mNodeReader.getNode().getDeweyID().get(), null));
                }
                mNodeReader.moveTo(attNodeKey);
                attributeNr++;
            } else if (isNamespace()) {
                final long nspNodeKey = mNodeReader.getNodeKey();
                if (nspNr == 0) {
                    deweyID = Optional.of(mNodeReader.getParentDeweyID().get().getNewNamespaceID());
                } else {
                    mNodeReader.moveTo(nspNr - 1);
                    deweyID = Optional.of(SirixDeweyID.newBetween(mNodeReader.getNode().getDeweyID().get(), null));
                }
                mNodeReader.moveTo(nspNodeKey);
                nspNr++;
            } else {
                attributeNr = 0;
                nspNr = 0;
                if (previousLevel + 1 == getDeweyID().get().getLevel()) {
                    if (mNodeReader.hasLeftSibling()) {
                        deweyID = Optional.of(SirixDeweyID.newBetween(getLeftSiblingDeweyID().get(), null));
                    } else {
                        deweyID = Optional.of(getParentDeweyID().get().getNewChildID());
                    }
                } else {
                    previousLevel++;
                    deweyID = Optional.of(getParentDeweyID().get().getNewChildID());
                }
            }
            final Node node = (Node) getPageTransaction().prepareEntryForModification(mNodeReader.getCurrentNode().getNodeKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
            node.setDeweyID(deweyID);
        }
        mNodeReader.moveTo(nodeKey);
    }
}
Also used : TextNode(org.sirix.node.TextNode) CommentNode(org.sirix.node.CommentNode) PINode(org.sirix.node.PINode) Node(org.sirix.node.interfaces.Node) ValueNode(org.sirix.node.interfaces.ValueNode) AttributeNode(org.sirix.node.AttributeNode) ImmutableNode(org.sirix.node.interfaces.immutable.ImmutableNode) StructNode(org.sirix.node.interfaces.StructNode) ElementNode(org.sirix.node.ElementNode) NamespaceNode(org.sirix.node.NamespaceNode) NameNode(org.sirix.node.interfaces.NameNode) UnorderedKeyValuePage(org.sirix.page.UnorderedKeyValuePage) SirixDeweyID(org.sirix.node.SirixDeweyID) StructNode(org.sirix.node.interfaces.StructNode)

Example 33 with StructNode

use of org.sirix.node.interfaces.StructNode in project sirix by sirixdb.

the class XdmNodeWriterTrxImpl method insertSubtree.

private XdmNodeWriteTrx insertSubtree(final XMLEventReader reader, final Insert insert) throws SirixException {
    checkNotNull(reader);
    assert insert != null;
    acquireLock();
    try {
        if (getCurrentNode() instanceof StructNode) {
            checkAccessAndCommit();
            mBulkInsert = true;
            long nodeKey = getCurrentNode().getNodeKey();
            final XMLShredder shredder = new XMLShredder.Builder(this, reader, insert).commitAfterwards().build();
            shredder.call();
            moveTo(nodeKey);
            switch(insert) {
                case ASFIRSTCHILD:
                    moveToFirstChild();
                    break;
                case ASRIGHTSIBLING:
                    moveToRightSibling();
                    break;
                case ASLEFTSIBLING:
                    moveToLeftSibling();
                    break;
            }
            nodeKey = getCurrentNode().getNodeKey();
            postOrderTraversalHashes();
            final ImmutableNode startNode = getCurrentNode();
            moveToParent();
            while (getCurrentNode().hasParent()) {
                moveToParent();
                addParentHash(startNode);
            }
            moveTo(nodeKey);
            mBulkInsert = false;
        }
    } finally {
        unLock();
    }
    return this;
}
Also used : ImmutableNode(org.sirix.node.interfaces.immutable.ImmutableNode) XMLShredder(org.sirix.service.xml.shredder.XMLShredder) StructNode(org.sirix.node.interfaces.StructNode)

Example 34 with StructNode

use of org.sirix.node.interfaces.StructNode in project sirix by sirixdb.

the class XdmNodeWriterTrxImpl method adaptForRemove.

// ////////////////////////////////////////////////////////////
// end of insert operation
// ////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////
// remove operation
// ////////////////////////////////////////////////////////////
/**
 * Adapting everything for remove operations.
 *
 * @param oldNode pointer of the old node to be replaced
 * @throws SirixException if anything weird happens
 */
private void adaptForRemove(final StructNode oldNode, final PageKind page) throws SirixException {
    assert oldNode != null;
    // Concatenate neighbor text nodes if they exist (the right sibling is
    // deleted afterwards).
    boolean concatenated = false;
    if (oldNode.hasLeftSibling() && oldNode.hasRightSibling() && moveTo(oldNode.getRightSiblingKey()).hasMoved() && getCurrentNode().getKind() == Kind.TEXT && moveTo(oldNode.getLeftSiblingKey()).hasMoved() && getCurrentNode().getKind() == Kind.TEXT) {
        final StringBuilder builder = new StringBuilder(getValue());
        moveTo(oldNode.getRightSiblingKey());
        builder.append(getValue());
        moveTo(oldNode.getLeftSiblingKey());
        setValue(builder.toString());
        concatenated = true;
    }
    // Adapt left sibling node if there is one.
    if (oldNode.hasLeftSibling()) {
        final StructNode leftSibling = (StructNode) getPageTransaction().prepareEntryForModification(oldNode.getLeftSiblingKey(), page, -1, Optional.<UnorderedKeyValuePage>empty());
        if (concatenated) {
            moveTo(oldNode.getRightSiblingKey());
            leftSibling.setRightSiblingKey(((StructNode) getCurrentNode()).getRightSiblingKey());
        } else {
            leftSibling.setRightSiblingKey(oldNode.getRightSiblingKey());
        }
    }
    // Adapt right sibling node if there is one.
    if (oldNode.hasRightSibling()) {
        StructNode rightSibling;
        if (concatenated) {
            moveTo(oldNode.getRightSiblingKey());
            moveTo(mNodeReader.getStructuralNode().getRightSiblingKey());
            rightSibling = (StructNode) getPageTransaction().prepareEntryForModification(mNodeReader.getCurrentNode().getNodeKey(), page, -1, Optional.<UnorderedKeyValuePage>empty());
            rightSibling.setLeftSiblingKey(oldNode.getLeftSiblingKey());
        } else {
            rightSibling = (StructNode) getPageTransaction().prepareEntryForModification(oldNode.getRightSiblingKey(), page, -1, Optional.<UnorderedKeyValuePage>empty());
            rightSibling.setLeftSiblingKey(oldNode.getLeftSiblingKey());
        }
    }
    // Adapt parent, if node has now left sibling it is a first child.
    StructNode parent = (StructNode) getPageTransaction().prepareEntryForModification(oldNode.getParentKey(), page, -1, Optional.<UnorderedKeyValuePage>empty());
    if (!oldNode.hasLeftSibling()) {
        parent.setFirstChildKey(oldNode.getRightSiblingKey());
    }
    parent.decrementChildCount();
    if (concatenated) {
        parent.decrementDescendantCount();
        parent.decrementChildCount();
    }
    if (concatenated) {
        // Adjust descendant count.
        moveTo(parent.getNodeKey());
        while (parent.hasParent()) {
            moveToParent();
            final StructNode ancestor = (StructNode) getPageTransaction().prepareEntryForModification(mNodeReader.getCurrentNode().getNodeKey(), page, -1, Optional.<UnorderedKeyValuePage>empty());
            ancestor.decrementDescendantCount();
            parent = ancestor;
        }
    }
    // concatenated/merged.
    if (concatenated) {
        moveTo(oldNode.getRightSiblingKey());
        getPageTransaction().removeEntry(mNodeReader.getNodeKey(), page, -1, Optional.<UnorderedKeyValuePage>empty());
    }
    // Remove non structural nodes of old node.
    if (oldNode.getKind() == Kind.ELEMENT) {
        moveTo(oldNode.getNodeKey());
        removeNonStructural();
    }
    // Remove old node.
    moveTo(oldNode.getNodeKey());
    getPageTransaction().removeEntry(oldNode.getNodeKey(), page, -1, Optional.<UnorderedKeyValuePage>empty());
}
Also used : UnorderedKeyValuePage(org.sirix.page.UnorderedKeyValuePage) StructNode(org.sirix.node.interfaces.StructNode)

Example 35 with StructNode

use of org.sirix.node.interfaces.StructNode in project sirix by sirixdb.

the class XdmNodeWriterTrxImpl method pi.

/**
 * Processing instruction.
 *
 * @param target target PI
 * @param content content of PI
 * @param insert insertion location
 * @throws SirixException if any unexpected error occurs
 */
private XdmNodeWriteTrx pi(final String target, final String content, final Insert insert) throws SirixException {
    final byte[] targetBytes = getBytes(target);
    if (!XMLToken.isNCName(checkNotNull(targetBytes))) {
        throw new IllegalArgumentException("The target is not valid!");
    }
    if (content.contains("?>-")) {
        throw new SirixUsageException("The content must not contain '?>-'");
    }
    acquireLock();
    try {
        if (getCurrentNode() instanceof StructNode) {
            checkAccessAndCommit();
            // Insert new processing instruction node.
            final byte[] processingContent = getBytes(content);
            long parentKey = 0;
            long leftSibKey = 0;
            long rightSibKey = 0;
            InsertPos pos = InsertPos.ASFIRSTCHILD;
            Optional<SirixDeweyID> id = Optional.<SirixDeweyID>empty();
            switch(insert) {
                case ASFIRSTCHILD:
                    parentKey = getCurrentNode().getNodeKey();
                    leftSibKey = Fixed.NULL_NODE_KEY.getStandardProperty();
                    rightSibKey = ((StructNode) getCurrentNode()).getFirstChildKey();
                    id = newFirstChildID();
                    break;
                case ASRIGHTSIBLING:
                    parentKey = getCurrentNode().getParentKey();
                    leftSibKey = getCurrentNode().getNodeKey();
                    rightSibKey = ((StructNode) getCurrentNode()).getRightSiblingKey();
                    pos = InsertPos.ASRIGHTSIBLING;
                    id = newRightSiblingID();
                    break;
                case ASLEFTSIBLING:
                    parentKey = getCurrentNode().getParentKey();
                    leftSibKey = ((StructNode) getCurrentNode()).getLeftSiblingKey();
                    rightSibKey = getCurrentNode().getNodeKey();
                    pos = InsertPos.ASLEFTSIBLING;
                    id = newLeftSiblingID();
                    break;
                default:
                    throw new IllegalStateException("Insert location not known!");
            }
            final QNm targetName = new QNm(target);
            final long pathNodeKey = mBuildPathSummary ? mPathSummaryWriter.getPathNodeKey(targetName, Kind.PROCESSING_INSTRUCTION) : 0;
            final PINode node = mNodeFactory.createPINode(parentKey, leftSibKey, rightSibKey, targetName, processingContent, mCompression, pathNodeKey, id);
            // Adapt local nodes and hashes.
            mNodeReader.setCurrentNode(node);
            adaptForInsert(node, pos, PageKind.RECORDPAGE);
            mNodeReader.setCurrentNode(node);
            adaptHashesWithAdd();
            return this;
        } else {
            throw new SirixUsageException("Current node must be a structural node!");
        }
    } finally {
        unLock();
    }
}
Also used : QNm(org.brackit.xquery.atomic.QNm) PINode(org.sirix.node.PINode) SirixUsageException(org.sirix.exception.SirixUsageException) SirixDeweyID(org.sirix.node.SirixDeweyID) StructNode(org.sirix.node.interfaces.StructNode)

Aggregations

StructNode (org.sirix.node.interfaces.StructNode)41 SirixDeweyID (org.sirix.node.SirixDeweyID)12 SirixUsageException (org.sirix.exception.SirixUsageException)11 ElementNode (org.sirix.node.ElementNode)10 TextNode (org.sirix.node.TextNode)8 ImmutableNode (org.sirix.node.interfaces.immutable.ImmutableNode)8 UnorderedKeyValuePage (org.sirix.page.UnorderedKeyValuePage)8 CommentNode (org.sirix.node.CommentNode)6 PINode (org.sirix.node.PINode)6 AttributeNode (org.sirix.node.AttributeNode)5 Kind (org.sirix.node.Kind)5 NamespaceNode (org.sirix.node.NamespaceNode)5 NameNode (org.sirix.node.interfaces.NameNode)5 Node (org.sirix.node.interfaces.Node)5 ValueNode (org.sirix.node.interfaces.ValueNode)5 PageKind (org.sirix.page.PageKind)5 Optional (java.util.Optional)3 PostOrderAxis (org.sirix.axis.PostOrderAxis)3 Axis (org.sirix.api.Axis)2 DescendantAxis (org.sirix.axis.DescendantAxis)2