Search in sources :

Example 6 with ElementNode

use of org.sirix.node.ElementNode in project sirix by sirixdb.

the class XdmNodeWriterTrxImpl method insertAttribute.

@Override
public XdmNodeWriteTrx insertAttribute(final QNm name, final String value, final Movement move) throws SirixException {
    checkNotNull(value);
    if (!XMLToken.isValidQName(checkNotNull(name))) {
        throw new IllegalArgumentException("The QName is not valid!");
    }
    acquireLock();
    try {
        if (getCurrentNode().getKind() == Kind.ELEMENT) {
            checkAccessAndCommit();
            /*
         * Update value in case of the same attribute name is found but the attribute to insert has
         * a different value (otherwise an exception is thrown because of a duplicate attribute
         * which would otherwise be inserted!).
         */
            final ElementNode element = (ElementNode) getCurrentNode();
            final Optional<Long> attKey = element.getAttributeKeyByName(name);
            if (attKey.isPresent()) {
                moveTo(attKey.get());
                final QNm qName = getName();
                if (name.equals(qName)) {
                    if (getValue().equals(value)) {
                        throw new SirixUsageException("Duplicate attribute!");
                    } else {
                        setValue(value);
                    }
                }
                moveToParent();
            }
            // Get the path node key.
            final long pathNodeKey = mNodeReader.mResourceManager.getResourceConfig().mPathSummary ? mPathSummaryWriter.getPathNodeKey(name, Kind.ATTRIBUTE) : 0;
            final byte[] attValue = getBytes(value);
            final Optional<SirixDeweyID> id = newAttributeID();
            final long elementKey = getCurrentNode().getNodeKey();
            final AttributeNode node = mNodeFactory.createAttributeNode(elementKey, name, attValue, pathNodeKey, id);
            final Node parentNode = (Node) getPageTransaction().prepareEntryForModification(node.getParentKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
            ((ElementNode) parentNode).insertAttribute(node.getNodeKey(), node.getPrefixKey() + node.getLocalNameKey());
            mNodeReader.setCurrentNode(node);
            adaptHashesWithAdd();
            // Index text value.
            mIndexController.notifyChange(ChangeType.INSERT, node, pathNodeKey);
            if (move == Movement.TOPARENT) {
                moveToParent();
            }
            return this;
        } else {
            throw new SirixUsageException("Insert is not allowed if current node is not an ElementNode!");
        }
    } finally {
        unLock();
    }
}
Also used : AttributeNode(org.sirix.node.AttributeNode) 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) ElementNode(org.sirix.node.ElementNode) SirixUsageException(org.sirix.exception.SirixUsageException) SirixDeweyID(org.sirix.node.SirixDeweyID) QNm(org.brackit.xquery.atomic.QNm)

Example 7 with ElementNode

use of org.sirix.node.ElementNode in project sirix by sirixdb.

the class XdmNodeWriterTrxImpl method insertNamespace.

@Override
public XdmNodeWriteTrx insertNamespace(final QNm name, final Movement move) throws SirixException {
    if (!XMLToken.isValidQName(checkNotNull(name))) {
        throw new IllegalArgumentException("The QName is not valid!");
    }
    acquireLock();
    try {
        if (getCurrentNode().getKind() == Kind.ELEMENT) {
            checkAccessAndCommit();
            for (int i = 0, namespCount = ((ElementNode) getCurrentNode()).getNamespaceCount(); i < namespCount; i++) {
                moveToNamespace(i);
                final QNm qName = getName();
                if (name.getPrefix().equals(qName.getPrefix())) {
                    throw new SirixUsageException("Duplicate namespace!");
                }
                moveToParent();
            }
            final long pathNodeKey = mBuildPathSummary ? mPathSummaryWriter.getPathNodeKey(name, Kind.NAMESPACE) : 0;
            final long elementKey = getCurrentNode().getNodeKey();
            final Optional<SirixDeweyID> id = newNamespaceID();
            final NamespaceNode node = mNodeFactory.createNamespaceNode(elementKey, name, pathNodeKey, id);
            final Node parentNode = (Node) getPageTransaction().prepareEntryForModification(node.getParentKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
            ((ElementNode) parentNode).insertNamespace(node.getNodeKey());
            mNodeReader.setCurrentNode(node);
            adaptHashesWithAdd();
            if (move == Movement.TOPARENT) {
                moveToParent();
            }
            return this;
        } else {
            throw new SirixUsageException("Insert is not allowed if current node is not an ElementNode!");
        }
    } finally {
        unLock();
    }
}
Also used : QNm(org.brackit.xquery.atomic.QNm) 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) NamespaceNode(org.sirix.node.NamespaceNode) UnorderedKeyValuePage(org.sirix.page.UnorderedKeyValuePage) ElementNode(org.sirix.node.ElementNode) SirixUsageException(org.sirix.exception.SirixUsageException) SirixDeweyID(org.sirix.node.SirixDeweyID)

Example 8 with ElementNode

use of org.sirix.node.ElementNode in project sirix by sirixdb.

the class XdmNodeWriterTrxImpl method postOrderTraversalHashes.

/**
 * Modifying hashes in a postorder-traversal.
 *
 * @throws SirixIOException if an I/O error occurs
 */
private void postOrderTraversalHashes() throws SirixIOException {
    new PostOrderAxis(this, IncludeSelf.YES).forEach((unused) -> {
        final StructNode node = mNodeReader.getStructuralNode();
        if (node.getKind() == Kind.ELEMENT) {
            final ElementNode element = (ElementNode) node;
            for (int i = 0, nspCount = element.getNamespaceCount(); i < nspCount; i++) {
                moveToNamespace(i);
                addHashAndDescendantCount();
                moveToParent();
            }
            for (int i = 0, attCount = element.getAttributeCount(); i < attCount; i++) {
                moveToAttribute(i);
                addHashAndDescendantCount();
                moveToParent();
            }
        }
        addHashAndDescendantCount();
    });
}
Also used : PostOrderAxis(org.sirix.axis.PostOrderAxis) ElementNode(org.sirix.node.ElementNode) StructNode(org.sirix.node.interfaces.StructNode)

Example 9 with ElementNode

use of org.sirix.node.ElementNode in project sirix by sirixdb.

the class XdmNodeWriterTrxImpl method remove.

@Override
public XdmNodeWriteTrx remove() throws SirixException {
    checkAccessAndCommit();
    acquireLock();
    try {
        if (getCurrentNode().getKind() == Kind.DOCUMENT) {
            throw new SirixUsageException("Document root can not be removed.");
        } else if (getCurrentNode() instanceof StructNode) {
            final StructNode node = (StructNode) mNodeReader.getCurrentNode();
            // Remove subtree.
            for (final Axis axis = new PostOrderAxis(this); axis.hasNext(); ) {
                axis.next();
                // Remove name.
                removeName();
                // Remove namespaces and attributes.
                removeNonStructural();
                // Remove text value.
                removeValue();
                // Then remove node.
                getPageTransaction().removeEntry(getCurrentNode().getNodeKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
            }
            // Adapt hashes and neighbour nodes as well as the name from the
            // NamePage mapping if it's not a text node.
            mNodeReader.setCurrentNode(node);
            adaptHashesWithRemove();
            adaptForRemove(node, PageKind.RECORDPAGE);
            mNodeReader.setCurrentNode(node);
            // Remove the name of subtree-root.
            if (node.getKind() == Kind.ELEMENT) {
                removeName();
            }
            // of text merges.
            if (mNodeReader.hasRightSibling() && moveTo(node.getRightSiblingKey()).hasMoved()) {
            } else if (node.hasLeftSibling()) {
                moveTo(node.getLeftSiblingKey());
            } else {
                moveTo(node.getParentKey());
            }
        } else if (getCurrentNode().getKind() == Kind.ATTRIBUTE) {
            final ImmutableNode node = mNodeReader.getCurrentNode();
            final ElementNode parent = (ElementNode) getPageTransaction().prepareEntryForModification(node.getParentKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
            parent.removeAttribute(node.getNodeKey());
            adaptHashesWithRemove();
            getPageTransaction().removeEntry(node.getNodeKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
            removeName();
            mIndexController.notifyChange(ChangeType.DELETE, getNode(), parent.getPathNodeKey());
            moveToParent();
        } else if (getCurrentNode().getKind() == Kind.NAMESPACE) {
            final ImmutableNode node = mNodeReader.getCurrentNode();
            final ElementNode parent = (ElementNode) getPageTransaction().prepareEntryForModification(node.getParentKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
            parent.removeNamespace(node.getNodeKey());
            adaptHashesWithRemove();
            getPageTransaction().removeEntry(node.getNodeKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
            removeName();
            moveToParent();
        }
        return this;
    } finally {
        unLock();
    }
}
Also used : PostOrderAxis(org.sirix.axis.PostOrderAxis) ImmutableNode(org.sirix.node.interfaces.immutable.ImmutableNode) UnorderedKeyValuePage(org.sirix.page.UnorderedKeyValuePage) SirixUsageException(org.sirix.exception.SirixUsageException) ElementNode(org.sirix.node.ElementNode) Axis(org.sirix.api.Axis) LevelOrderAxis(org.sirix.axis.LevelOrderAxis) PostOrderAxis(org.sirix.axis.PostOrderAxis) DescendantAxis(org.sirix.axis.DescendantAxis) StructNode(org.sirix.node.interfaces.StructNode)

Example 10 with ElementNode

use of org.sirix.node.ElementNode 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)

Aggregations

ElementNode (org.sirix.node.ElementNode)15 StructNode (org.sirix.node.interfaces.StructNode)10 SirixUsageException (org.sirix.exception.SirixUsageException)8 UnorderedKeyValuePage (org.sirix.page.UnorderedKeyValuePage)7 NameNode (org.sirix.node.interfaces.NameNode)6 ImmutableNode (org.sirix.node.interfaces.immutable.ImmutableNode)6 AttributeNode (org.sirix.node.AttributeNode)5 CommentNode (org.sirix.node.CommentNode)5 NamespaceNode (org.sirix.node.NamespaceNode)5 PINode (org.sirix.node.PINode)5 SirixDeweyID (org.sirix.node.SirixDeweyID)5 TextNode (org.sirix.node.TextNode)5 Node (org.sirix.node.interfaces.Node)5 ValueNode (org.sirix.node.interfaces.ValueNode)5 PostOrderAxis (org.sirix.axis.PostOrderAxis)4 QNm (org.brackit.xquery.atomic.QNm)3 Axis (org.sirix.api.Axis)3 DescendantAxis (org.sirix.axis.DescendantAxis)3 LevelOrderAxis (org.sirix.axis.LevelOrderAxis)3 Optional (java.util.Optional)2