Search in sources :

Example 1 with EmbeddedXMLStreamReader

use of org.exist.stax.EmbeddedXMLStreamReader in project exist by eXist-db.

the class ConsistencyCheck method checkXMLTree.

/**
 * Check the persistent DOM of a document. The method traverses the entire node tree and checks it for consistency, including node relationships,
 * child and attribute counts etc.
 *
 * @param doc the document to check
 * @return null if the document is consistent, an error report otherwise.
 */
public ErrorReport checkXMLTree(final DocumentImpl doc) {
    final DOMFile domDb = ((NativeBroker) broker).getDOMFile();
    return new DOMTransaction<ErrorReport>(this, domDb, () -> broker.getBrokerPool().getLockManager().acquireBtreeWriteLock(domDb.getLockName()), doc) {

        public ErrorReport start() {
            EmbeddedXMLStreamReader reader = null;
            try {
                final Node root = doc.getFirstChild();
                reader = (EmbeddedXMLStreamReader) broker.getXMLStreamReader((NodeHandle) root, true);
                boolean attribsAllowed = false;
                int expectedAttribs = 0;
                int attributeCount = 0;
                while (reader.hasNext()) {
                    final int status = reader.next();
                    final NodeId nodeId = (NodeId) reader.getProperty(EmbeddedXMLStreamReader.PROPERTY_NODE_ID);
                    if ((status != XMLStreamReader.END_ELEMENT) && !elementStack.isEmpty()) {
                        final ElementNode parent = elementStack.peek();
                        parent.childCount++;
                        // test parent-child relation
                        if (!nodeId.isChildOf(parent.elem.getNodeId())) {
                            return new ErrorReport.ResourceError(ErrorReport.NODE_HIERARCHY, "Node " + nodeId + " is not a child of " + parent.elem.getNodeId());
                        }
                        // test sibling relation
                        if ((parent.prevSibling != null) && !(nodeId.isSiblingOf(parent.prevSibling) && (nodeId.compareTo(parent.prevSibling) > 0))) {
                            return new ErrorReport.ResourceError(ErrorReport.INCORRECT_NODE_ID, "Node " + nodeId + " is not a sibling of " + parent.prevSibling);
                        }
                        parent.prevSibling = nodeId;
                    }
                    switch(status) {
                        case XMLStreamReader.ATTRIBUTE:
                            {
                                attributeCount++;
                                break;
                            }
                        case XMLStreamReader.END_ELEMENT:
                            {
                                if (elementStack.isEmpty()) {
                                    return new org.exist.backup.ErrorReport.ResourceError(ErrorReport.NODE_HIERARCHY, "Error in node hierarchy: received END_ELEMENT event " + "but stack was empty!");
                                }
                                final ElementNode lastElem = elementStack.pop();
                                if (lastElem.childCount != lastElem.elem.getChildCount()) {
                                    return new ErrorReport.ResourceError(org.exist.backup.ErrorReport.NODE_HIERARCHY, "Element reports incorrect child count: expected " + lastElem.elem.getChildCount() + " but found " + lastElem.childCount);
                                }
                                break;
                            }
                        case XMLStreamReader.START_ELEMENT:
                            {
                                if (nodeId.getTreeLevel() <= defaultIndexDepth) {
                                    // check dom.dbx btree, which maps the node
                                    // id to the node's storage address
                                    // look up the node id and check if the
                                    // returned storage address is correct
                                    final NativeBroker.NodeRef nodeRef = new NativeBroker.NodeRef(doc.getDocId(), nodeId);
                                    try {
                                        final long p = domDb.findValue(nodeRef);
                                        if (p != reader.getCurrentPosition()) {
                                            final Value v = domDb.get(p);
                                            if (v == null) {
                                                return new ErrorReport.IndexError(ErrorReport.DOM_INDEX, "Failed to access node " + nodeId + " through dom.dbx index. Wrong storage address. Expected: " + p + "; got: " + reader.getCurrentPosition() + " - ", doc.getDocId());
                                            }
                                        }
                                    } catch (final Exception e) {
                                        e.printStackTrace();
                                        return new ErrorReport.IndexError(ErrorReport.DOM_INDEX, "Failed to access node " + nodeId + " through dom.dbx index.", e, doc.getDocId());
                                    }
                                }
                                final IStoredNode node = reader.getNode();
                                if (node.getNodeType() != Node.ELEMENT_NODE) {
                                    return new org.exist.backup.ErrorReport.ResourceError(ErrorReport.INCORRECT_NODE_TYPE, "Expected an element node, received node of type " + node.getNodeType());
                                }
                                elementStack.push(new ElementNode((ElementImpl) node));
                                attribsAllowed = true;
                                attributeCount = 0;
                                expectedAttribs = reader.getAttributeCount();
                                break;
                            }
                        default:
                            {
                                if (attribsAllowed) {
                                    if (attributeCount != expectedAttribs) {
                                        return new org.exist.backup.ErrorReport.ResourceError(ErrorReport.INCORRECT_NODE_TYPE, "Wrong number of attributes. Expected: " + expectedAttribs + "; found: " + attributeCount);
                                    }
                                }
                                attribsAllowed = false;
                                break;
                            }
                    }
                }
                if (!elementStack.isEmpty()) {
                    return new org.exist.backup.ErrorReport.ResourceError(ErrorReport.NODE_HIERARCHY, "Error in node hierarchy: reached end of tree but " + "stack was not empty!");
                }
                return null;
            } catch (final IOException | XMLStreamException e) {
                e.printStackTrace();
                return new org.exist.backup.ErrorReport.ResourceError(ErrorReport.RESOURCE_ACCESS_FAILED, e.getMessage(), e);
            } finally {
                elementStack.clear();
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (final XMLStreamException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }.run();
}
Also used : Node(org.w3c.dom.Node) EmbeddedXMLStreamReader(org.exist.stax.EmbeddedXMLStreamReader) DOMFile(org.exist.storage.dom.DOMFile) NativeBroker(org.exist.storage.NativeBroker) PermissionDeniedException(org.exist.security.PermissionDeniedException) TerminatedException(org.exist.xquery.TerminatedException) XMLStreamException(javax.xml.stream.XMLStreamException) IOException(java.io.IOException) XMLStreamException(javax.xml.stream.XMLStreamException) NodeId(org.exist.numbering.NodeId) Value(org.exist.storage.btree.Value)

Example 2 with EmbeddedXMLStreamReader

use of org.exist.stax.EmbeddedXMLStreamReader in project exist by eXist-db.

the class DOMFile method findValue.

/**
 * Retrieve node at virtual address.
 *
 * @param broker the database broker
 * @param node The virtual address
 * @return The reference of the node
 * @throws IOException if an I/O error occurs
 * @throws BTreeException if an error occurs reading the tree
 */
protected long findValue(final DBBroker broker, final NodeProxy node) throws IOException, BTreeException {
    if (LOG.isDebugEnabled() && !lockManager.isBtreeLocked(getLockName())) {
        LOG.debug("The file doesn't own a lock");
    }
    final DocumentImpl doc = node.getOwnerDocument();
    final NodeRef nodeRef = new NativeBroker.NodeRef(doc.getDocId(), node.getNodeId());
    // first try to find the node in the index
    final long pointer = findValue(nodeRef);
    if (pointer == KEY_NOT_FOUND) {
        // node not found in index: try to find the nearest available
        // ancestor and traverse it
        NodeId nodeID = node.getNodeId();
        long parentPointer = KEY_NOT_FOUND;
        do {
            nodeID = nodeID.getParentId();
            if (nodeID == null) {
                SanityCheck.TRACE("Node " + node.getOwnerDocument().getDocId() + ":<null nodeID> not found.");
                throw new BTreeException("Node not found.");
            }
            if (nodeID == NodeId.DOCUMENT_NODE) {
                SanityCheck.TRACE("Node " + node.getOwnerDocument().getDocId() + ":" + nodeID + " not found.");
                return KEY_NOT_FOUND;
            }
            final NativeBroker.NodeRef parentRef = new NativeBroker.NodeRef(doc.getDocId(), nodeID);
            try {
                parentPointer = findValue(parentRef);
            } catch (final BTreeException bte) {
                LOG.error("report me", bte);
            }
        } while (parentPointer == KEY_NOT_FOUND);
        try {
            final int thisLevel = nodeID.getTreeLevel();
            // lazily initialized below
            Integer childLevel = null;
            final NodeProxy parent = new NodeProxy(doc, nodeID, parentPointer);
            final EmbeddedXMLStreamReader reader = (EmbeddedXMLStreamReader) broker.getXMLStreamReader(parent, true);
            while (reader.hasNext()) {
                final int status = reader.next();
                if (status != XMLStreamReader.END_ELEMENT) {
                    if (childLevel == null) {
                        childLevel = reader.getNode().getNodeType() == Node.ELEMENT_NODE ? thisLevel + 1 : thisLevel;
                    }
                    final NodeId otherId = (NodeId) reader.getProperty(ExtendedXMLStreamReader.PROPERTY_NODE_ID);
                    if (otherId.equals(node.getNodeId())) {
                        return reader.getCurrentPosition();
                    }
                }
                if (status == XMLStreamConstants.END_ELEMENT) {
                    final NodeId otherId = (NodeId) reader.getProperty(ExtendedXMLStreamReader.PROPERTY_NODE_ID);
                    final int otherLevel = otherId.getTreeLevel();
                    if (childLevel != null && childLevel != otherLevel && otherLevel == thisLevel) {
                        // exit-while
                        break;
                    }
                }
            }
            if (LOG.isDebugEnabled()) {
                LOG.debug("Node {} could not be found. Giving up. This is usually not an error.", node.getNodeId());
            }
            return KEY_NOT_FOUND;
        } catch (final XMLStreamException e) {
            SanityCheck.TRACE("Node " + node.getOwnerDocument().getDocId() + ":" + node.getNodeId() + " not found.");
            throw new BTreeException("Node " + node.getNodeId() + " not found.");
        }
    } else {
        return pointer;
    }
}
Also used : NodeRef(org.exist.storage.NativeBroker.NodeRef) BTreeException(org.exist.storage.btree.BTreeException) XMLStreamException(javax.xml.stream.XMLStreamException) NodeId(org.exist.numbering.NodeId) EmbeddedXMLStreamReader(org.exist.stax.EmbeddedXMLStreamReader) NativeBroker(org.exist.storage.NativeBroker) NodeRef(org.exist.storage.NativeBroker.NodeRef) DocumentImpl(org.exist.dom.persistent.DocumentImpl) NodeProxy(org.exist.dom.persistent.NodeProxy)

Example 3 with EmbeddedXMLStreamReader

use of org.exist.stax.EmbeddedXMLStreamReader in project exist by eXist-db.

the class NativeBroker method getXMLStreamReader.

@Override
public IEmbeddedXMLStreamReader getXMLStreamReader(final NodeHandle node, final boolean reportAttributes) throws IOException, XMLStreamException {
    if (streamReader == null) {
        final RawNodeIterator iterator = new RawNodeIterator(this, domDb, node);
        streamReader = new EmbeddedXMLStreamReader(this, node.getOwnerDocument(), iterator, node, reportAttributes);
    } else {
        streamReader.reposition(this, node, reportAttributes);
    }
    return streamReader;
}
Also used : RawNodeIterator(org.exist.storage.dom.RawNodeIterator) IEmbeddedXMLStreamReader(org.exist.stax.IEmbeddedXMLStreamReader) EmbeddedXMLStreamReader(org.exist.stax.EmbeddedXMLStreamReader)

Example 4 with EmbeddedXMLStreamReader

use of org.exist.stax.EmbeddedXMLStreamReader in project exist by eXist-db.

the class VirtualNodeSet method addChildren.

private void addChildren(final NodeProxy contextNode, final NodeSet result) {
    try {
        final EmbeddedXMLStreamReader reader = (EmbeddedXMLStreamReader) broker.getXMLStreamReader(contextNode, true);
        int status = reader.next();
        if (status != XMLStreamConstants.START_ELEMENT) {
            return;
        }
        int level = 0;
        while (reader.hasNext()) {
            status = reader.next();
            if (axis == Constants.ATTRIBUTE_AXIS && status != XMLStreamConstants.ATTRIBUTE) {
                break;
            }
            switch(status) {
                case XMLStreamConstants.END_ELEMENT:
                    if (--level < 0) {
                        return;
                    }
                    break;
                case XMLStreamConstants.ATTRIBUTE:
                    if ((axis == Constants.ATTRIBUTE_AXIS && level == 0) || axis == Constants.DESCENDANT_ATTRIBUTE_AXIS) {
                        final AttrImpl attr = (AttrImpl) reader.getNode();
                        if (test.matches(attr)) {
                            final NodeProxy p = new NodeProxy(attr);
                            p.deepCopyContext(contextNode);
                            if (useSelfAsContext && inPredicate) {
                                p.addContextNode(contextId, p);
                            } else if (inPredicate) {
                                p.addContextNode(contextId, contextNode);
                            }
                            result.add(p);
                        }
                    }
                    break;
                default:
                    if (((axis == Constants.CHILD_AXIS && level == 0) || axis == Constants.DESCENDANT_AXIS || axis == Constants.DESCENDANT_SELF_AXIS) && test.matches(reader)) {
                        final NodeId nodeId = (NodeId) reader.getProperty(ExtendedXMLStreamReader.PROPERTY_NODE_ID);
                        final NodeProxy p = new NodeProxy(contextNode.getOwnerDocument(), nodeId, reader.getNodeType(), reader.getCurrentPosition());
                        p.deepCopyContext(contextNode);
                        if (useSelfAsContext && inPredicate) {
                            p.addContextNode(contextId, p);
                        } else if (inPredicate) {
                            p.addContextNode(contextId, contextNode);
                        }
                        result.add(p);
                    }
                    break;
            }
            if (status == XMLStreamConstants.START_ELEMENT) {
                ++level;
            }
        }
    } catch (final IOException | XMLStreamException e) {
        LOG.error(e);
    // TODO : throw exception ,
    }
// TODO : throw exception ? -pb
}
Also used : XMLStreamException(javax.xml.stream.XMLStreamException) NodeId(org.exist.numbering.NodeId) EmbeddedXMLStreamReader(org.exist.stax.EmbeddedXMLStreamReader) IOException(java.io.IOException)

Aggregations

EmbeddedXMLStreamReader (org.exist.stax.EmbeddedXMLStreamReader)4 XMLStreamException (javax.xml.stream.XMLStreamException)3 NodeId (org.exist.numbering.NodeId)3 IOException (java.io.IOException)2 NativeBroker (org.exist.storage.NativeBroker)2 DocumentImpl (org.exist.dom.persistent.DocumentImpl)1 NodeProxy (org.exist.dom.persistent.NodeProxy)1 PermissionDeniedException (org.exist.security.PermissionDeniedException)1 IEmbeddedXMLStreamReader (org.exist.stax.IEmbeddedXMLStreamReader)1 NodeRef (org.exist.storage.NativeBroker.NodeRef)1 BTreeException (org.exist.storage.btree.BTreeException)1 Value (org.exist.storage.btree.Value)1 DOMFile (org.exist.storage.dom.DOMFile)1 RawNodeIterator (org.exist.storage.dom.RawNodeIterator)1 TerminatedException (org.exist.xquery.TerminatedException)1 Node (org.w3c.dom.Node)1