Search in sources :

Example 1 with NodeId

use of org.exist.numbering.NodeId in project exist by eXist-db.

the class SystemExport method writeXML.

/**
 * Serialize a document to XML, based on {@link XMLStreamReader}.
 *
 * @param doc      the document to serialize
 * @param receiver the output handler
 */
private void writeXML(final DocumentImpl doc, final Receiver receiver) {
    try {
        char[] ch;
        int nsdecls;
        final NamespaceSupport nsSupport = new NamespaceSupport();
        final NodeList children = doc.getChildNodes();
        final DocumentType docType = doc.getDoctype();
        if (docType != null) {
            receiver.documentType(docType.getName(), docType.getPublicId(), docType.getSystemId());
        }
        for (int i = 0; i < children.getLength(); i++) {
            final StoredNode child = (StoredNode) children.item(i);
            final int thisLevel = child.getNodeId().getTreeLevel();
            final int childLevel = child.getNodeType() == Node.ELEMENT_NODE ? thisLevel + 1 : thisLevel;
            final XMLStreamReader reader = broker.getXMLStreamReader(child, false);
            while (reader.hasNext()) {
                final int status = reader.next();
                switch(status) {
                    case XMLStreamReader.START_DOCUMENT:
                    case XMLStreamReader.END_DOCUMENT:
                        break;
                    case XMLStreamReader.START_ELEMENT:
                        nsdecls = reader.getNamespaceCount();
                        for (int ni = 0; ni < nsdecls; ni++) {
                            receiver.startPrefixMapping(reader.getNamespacePrefix(ni), reader.getNamespaceURI(ni));
                        }
                        final AttrList attribs = new AttrList();
                        for (int j = 0; j < reader.getAttributeCount(); j++) {
                            final QName qn = new QName(reader.getAttributeLocalName(j), reader.getAttributeNamespace(j), reader.getAttributePrefix(j));
                            attribs.addAttribute(qn, reader.getAttributeValue(j));
                        }
                        receiver.startElement(new QName(reader.getLocalName(), reader.getNamespaceURI(), reader.getPrefix()), attribs);
                        break;
                    case XMLStreamReader.END_ELEMENT:
                        receiver.endElement(new QName(reader.getLocalName(), reader.getNamespaceURI(), reader.getPrefix()));
                        nsdecls = reader.getNamespaceCount();
                        for (int ni = 0; ni < nsdecls; ni++) {
                            receiver.endPrefixMapping(reader.getNamespacePrefix(ni));
                        }
                        final NodeId otherId = (NodeId) reader.getProperty(ExtendedXMLStreamReader.PROPERTY_NODE_ID);
                        final int otherLevel = otherId.getTreeLevel();
                        if (childLevel != thisLevel && otherLevel == thisLevel) {
                            // exit-while
                            break;
                        }
                        break;
                    case XMLStreamReader.CHARACTERS:
                        receiver.characters(reader.getText());
                        break;
                    case XMLStreamReader.CDATA:
                        ch = reader.getTextCharacters();
                        receiver.cdataSection(ch, 0, ch.length);
                        break;
                    case XMLStreamReader.COMMENT:
                        ch = reader.getTextCharacters();
                        receiver.comment(ch, 0, ch.length);
                        break;
                    case XMLStreamReader.PROCESSING_INSTRUCTION:
                        receiver.processingInstruction(reader.getPITarget(), reader.getPIData());
                        break;
                }
                if (child.getNodeType() == Node.COMMENT_NODE || child.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
                    break;
                }
            }
            nsSupport.reset();
        }
    } catch (final IOException | SAXException | XMLStreamException e) {
        e.printStackTrace();
    }
}
Also used : XMLStreamReader(javax.xml.stream.XMLStreamReader) ExtendedXMLStreamReader(org.exist.stax.ExtendedXMLStreamReader) QName(org.exist.dom.QName) NodeList(org.w3c.dom.NodeList) NamespaceSupport(org.xml.sax.helpers.NamespaceSupport) DocumentType(org.w3c.dom.DocumentType) SAXException(org.xml.sax.SAXException) AttrList(org.exist.util.serializer.AttrList) XMLStreamException(javax.xml.stream.XMLStreamException) NodeId(org.exist.numbering.NodeId)

Example 2 with NodeId

use of org.exist.numbering.NodeId 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 3 with NodeId

use of org.exist.numbering.NodeId in project exist by eXist-db.

the class NodeImpl method selectPreceding.

public void selectPreceding(final NodeTest test, final Sequence result, final int position) throws XPathException {
    final NodeId myNodeId = getNodeId();
    int count = 0;
    for (int i = nodeNumber - 1; i > 0; i--) {
        final NodeImpl n = document.getNode(i);
        if (!myNodeId.isDescendantOf(n.getNodeId()) && test.matches(n)) {
            if ((position < 0) || (++count == position)) {
                result.add(n);
            }
            if (count == position) {
                break;
            }
        }
    }
}
Also used : NodeId(org.exist.numbering.NodeId)

Example 4 with NodeId

use of org.exist.numbering.NodeId in project exist by eXist-db.

the class ElementImpl method getChildren.

private void getChildren(final boolean includeAttributes, final org.exist.dom.NodeListImpl childList) {
    try (final DBBroker broker = ownerDocument.getBrokerPool().getBroker()) {
        final int thisLevel = nodeId.getTreeLevel();
        final int childLevel = thisLevel + 1;
        for (final IEmbeddedXMLStreamReader reader = broker.getXMLStreamReader(this, includeAttributes); reader.hasNext(); ) {
            final int status = reader.next();
            final NodeId otherId = (NodeId) reader.getProperty(ExtendedXMLStreamReader.PROPERTY_NODE_ID);
            final int otherLevel = otherId.getTreeLevel();
            // skip descendants
            if (otherLevel > childLevel) {
                continue;
            }
            if (status == XMLStreamConstants.END_ELEMENT) {
                if (otherLevel == thisLevel) {
                    // exit-for
                    break;
                }
            // skip over any other END_ELEMENT(s)
            } else {
                if (otherLevel == childLevel) {
                    // child
                    childList.add(reader.getNode());
                }
            }
        }
    } catch (final IOException | XMLStreamException | EXistException e) {
        LOG.warn("Internal error while reading child nodes: {}", e.getMessage(), e);
    }
}
Also used : XMLStreamException(javax.xml.stream.XMLStreamException) NodeId(org.exist.numbering.NodeId) IOException(java.io.IOException) EXistException(org.exist.EXistException) IEmbeddedXMLStreamReader(org.exist.stax.IEmbeddedXMLStreamReader)

Example 5 with NodeId

use of org.exist.numbering.NodeId in project exist by eXist-db.

the class ElementImpl method deserialize.

public static StoredNode deserialize(final byte[] data, final int start, final int len, final DocumentImpl doc, final boolean pooled) {
    final int end = start + len;
    int pos = start;
    final byte idSizeType = (byte) (data[pos] & 0x03);
    boolean isDirty = (data[pos] & 0x8) == 0x8;
    final boolean hasNamespace = (data[pos] & 0x10) == 0x10;
    pos += StoredNode.LENGTH_SIGNATURE_LENGTH;
    final int children = ByteConversion.byteToInt(data, pos);
    pos += LENGTH_ELEMENT_CHILD_COUNT;
    final int dlnLen = ByteConversion.byteToShort(data, pos);
    pos += NodeId.LENGTH_NODE_ID_UNITS;
    final NodeId dln = doc.getBrokerPool().getNodeFactory().createFromData(dlnLen, data, pos);
    pos += dln.size();
    final short attributes = ByteConversion.byteToShort(data, pos);
    pos += LENGTH_ATTRIBUTES_COUNT;
    final short id = (short) Signatures.read(idSizeType, data, pos);
    pos += Signatures.getLength(idSizeType);
    short nsId = 0;
    String prefix = null;
    if (hasNamespace) {
        nsId = ByteConversion.byteToShort(data, pos);
        pos += LENGTH_NS_ID;
        int prefixLen = ByteConversion.byteToShort(data, pos);
        pos += LENGTH_PREFIX_LENGTH;
        if (prefixLen > 0) {
            prefix = UTF8.decode(data, pos, prefixLen).toString();
        }
        pos += prefixLen;
    }
    final String name = doc.getBrokerPool().getSymbols().getName(id);
    String namespace = XMLConstants.NULL_NS_URI;
    if (nsId != 0) {
        namespace = doc.getBrokerPool().getSymbols().getNamespace(nsId);
    }
    final ElementImpl node;
    if (pooled) {
        node = (ElementImpl) NodePool.getInstance().borrowNode(Node.ELEMENT_NODE);
    } else {
        node = new ElementImpl();
    }
    node.setNodeId(dln);
    node.nodeName = doc.getBrokerPool().getSymbols().getQName(Node.ELEMENT_NODE, namespace, name, prefix);
    node.children = children;
    node.attributes = attributes;
    node.isDirty = isDirty;
    node.setOwnerDocument(doc);
    // TO UNDERSTAND : why is this code here ?
    if (end > pos) {
        final byte[] pfxData = new byte[end - pos];
        System.arraycopy(data, pos, pfxData, 0, end - pos);
        final InputStream bin = new UnsynchronizedByteArrayInputStream(pfxData);
        final DataInputStream in = new DataInputStream(bin);
        try {
            final short prefixCount = in.readShort();
            for (int i = 0; i < prefixCount; i++) {
                prefix = in.readUTF();
                nsId = in.readShort();
                node.addNamespaceMapping(prefix, doc.getBrokerPool().getSymbols().getNamespace(nsId));
            }
        } catch (final IOException e) {
            LOG.error(e);
        }
    }
    return node;
}
Also used : DataInputStream(java.io.DataInputStream) UnsynchronizedByteArrayInputStream(org.apache.commons.io.input.UnsynchronizedByteArrayInputStream) InputStream(java.io.InputStream) NodeId(org.exist.numbering.NodeId) UnsynchronizedByteArrayInputStream(org.apache.commons.io.input.UnsynchronizedByteArrayInputStream) IOException(java.io.IOException) DataInputStream(java.io.DataInputStream)

Aggregations

NodeId (org.exist.numbering.NodeId)86 IOException (java.io.IOException)21 XMLStreamException (javax.xml.stream.XMLStreamException)17 EXistException (org.exist.EXistException)15 PermissionDeniedException (org.exist.security.PermissionDeniedException)13 NodeProxy (org.exist.dom.persistent.NodeProxy)12 ReentrantLock (java.util.concurrent.locks.ReentrantLock)11 DocumentImpl (org.exist.dom.persistent.DocumentImpl)10 Value (org.exist.storage.btree.Value)8 QName (org.exist.dom.QName)7 ExtendedXMLStreamReader (org.exist.stax.ExtendedXMLStreamReader)6 IEmbeddedXMLStreamReader (org.exist.stax.IEmbeddedXMLStreamReader)6 NodeImpl (org.exist.dom.memtree.NodeImpl)5 Txn (org.exist.storage.txn.Txn)5 DatabaseConfigurationException (org.exist.util.DatabaseConfigurationException)5 LockException (org.exist.util.LockException)5 URISyntaxException (java.net.URISyntaxException)4 IndexController (org.exist.indexing.IndexController)4 StreamListener (org.exist.indexing.StreamListener)4 DBBroker (org.exist.storage.DBBroker)4