Search in sources :

Example 11 with ElementImpl

use of org.exist.dom.persistent.ElementImpl in project exist by eXist-db.

the class FunInScopePrefixes method collectNamespacePrefixes.

public static void collectNamespacePrefixes(final Element element, final Map<String, String> prefixes) {
    final String namespaceURI = element.getNamespaceURI();
    if (namespaceURI != null && !namespaceURI.isEmpty()) {
        final String prefix = element.getPrefix();
        prefixes.put(prefix == null ? XMLConstants.DEFAULT_NS_PREFIX : prefix, namespaceURI);
    }
    if (element instanceof org.exist.dom.memtree.ElementImpl) {
        ((org.exist.dom.memtree.ElementImpl) element).getNamespaceMap(prefixes);
    } else {
        final ElementImpl elementImpl = (org.exist.dom.persistent.ElementImpl) element;
        if (elementImpl.declaresNamespacePrefixes()) {
            for (final Iterator<String> i = elementImpl.getPrefixes(); i.hasNext(); ) {
                final String prefix = i.next();
                prefixes.put(prefix, elementImpl.getNamespaceForPrefix(prefix));
            }
        }
    }
    if (namespaceURI != null && namespaceURI.isEmpty()) {
        final String prefix = element.getPrefix();
        prefixes.remove(prefix == null ? XMLConstants.DEFAULT_NS_PREFIX : prefix);
    }
}
Also used : ElementImpl(org.exist.dom.persistent.ElementImpl)

Example 12 with ElementImpl

use of org.exist.dom.persistent.ElementImpl in project exist by eXist-db.

the class Indexer method comment.

@Override
public void comment(final char[] ch, final int start, final int length) {
    if (insideDTD) {
        return;
    }
    final CommentImpl comment = new CommentImpl(ch, start, length);
    comment.setOwnerDocument(document);
    if (stack.isEmpty()) {
        comment.setNodeId(broker.getBrokerPool().getNodeFactory().createInstance(nodeFactoryInstanceCnt++));
        if (!validate) {
            broker.storeNode(transaction, comment, currentPath, indexSpec);
        }
        document.appendChild((NodeHandle) comment);
    } else {
        final ElementImpl last = stack.peek();
        processText(last, ProcessTextParent.COMMENT);
        last.appendChildInternal(prevNode, comment);
        setPrevious(comment);
        if (!validate) {
            broker.storeNode(transaction, comment, currentPath, indexSpec);
        }
    }
}
Also used : ElementImpl(org.exist.dom.persistent.ElementImpl) CommentImpl(org.exist.dom.persistent.CommentImpl)

Example 13 with ElementImpl

use of org.exist.dom.persistent.ElementImpl in project exist by eXist-db.

the class Indexer method processingInstruction.

@Override
public void processingInstruction(final String target, final String data) {
    final ProcessingInstructionImpl pi = new ProcessingInstructionImpl(target, data);
    pi.setOwnerDocument(document);
    if (stack.isEmpty()) {
        pi.setNodeId(broker.getBrokerPool().getNodeFactory().createInstance(nodeFactoryInstanceCnt++));
        if (!validate)
            broker.storeNode(transaction, pi, currentPath, indexSpec);
        document.appendChild((NodeHandle) pi);
    } else {
        final ElementImpl last = stack.peek();
        processText(last, ProcessTextParent.PI);
        last.appendChildInternal(prevNode, pi);
        setPrevious(pi);
        if (!validate)
            broker.storeNode(transaction, pi, currentPath, indexSpec);
    }
}
Also used : ElementImpl(org.exist.dom.persistent.ElementImpl) ProcessingInstructionImpl(org.exist.dom.persistent.ProcessingInstructionImpl)

Example 14 with ElementImpl

use of org.exist.dom.persistent.ElementImpl in project exist by eXist-db.

the class Indexer method startElement.

@Override
public void startElement(final String namespace, final String name, final String qname, final Attributes attributes) throws SAXException {
    // calculate number of real attributes:
    // don't store namespace declarations
    int attrLength = attributes.getLength();
    for (int i = 0; i < attributes.getLength(); i++) {
        final String attrNS = attributes.getURI(i);
        final String attrQName = attributes.getQName(i);
        if (attrQName.startsWith("xmlns") || attrNS.equals(Namespaces.EXIST_NS)) {
            --attrLength;
        }
    }
    ElementImpl node;
    int p = qname.indexOf(':');
    final String prefix = (p != Constants.STRING_NOT_FOUND) ? qname.substring(0, p) : "";
    final QName qn = broker.getBrokerPool().getSymbols().getQName(Node.ELEMENT_NODE, namespace, name, prefix);
    if (!stack.isEmpty()) {
        final ElementImpl last = stack.peek();
        processText(last, ProcessTextParent.ELEMENT_START);
        try {
            if (!usedElements.isEmpty()) {
                node = usedElements.pop();
                node.setNodeName(qn, broker.getBrokerPool().getSymbols());
            } else {
                node = new ElementImpl(qn, broker.getBrokerPool().getSymbols());
            }
        } catch (final DOMException e) {
            throw new SAXException(e.getMessage(), e);
        }
        // copy xml:space setting
        node.setPreserveSpace(last.preserveSpace());
        // append the node to its parent
        // (computes the node id and updates the parent's child count)
        last.appendChildInternal(prevNode, node);
        setPrevious(null);
        node.setOwnerDocument(document);
        node.setAttributes((short) attrLength);
        if (nsMappings != null && nsMappings.size() > 0) {
            node.setNamespaceMappings(nsMappings);
            nsMappings.clear();
        }
        stack.push(node);
        currentPath.addNode(node, attributes);
        node.setPosition(elementCnt++);
        if (!validate) {
            if (childCnt != null) {
                node.setChildCount(childCnt[node.getPosition()]);
            }
            storeElement(node);
        }
    } else {
        try {
            node = new ElementImpl(qn, broker.getBrokerPool().getSymbols());
        } catch (final DOMException e) {
            throw new SAXException(e.getMessage(), e);
        }
        rootNode = node;
        setPrevious(null);
        node.setOwnerDocument(document);
        node.setNodeId(broker.getBrokerPool().getNodeFactory().createInstance(nodeFactoryInstanceCnt++));
        node.setAttributes((short) attrLength);
        if (nsMappings != null && nsMappings.size() > 0) {
            node.setNamespaceMappings(nsMappings);
            nsMappings.clear();
        }
        stack.push(node);
        currentPath.addNode(node, attributes);
        node.setPosition(elementCnt++);
        if (!validate) {
            if (childCnt != null) {
                node.setChildCount(childCnt[node.getPosition()]);
            }
            storeElement(node);
        }
        document.appendChild((NodeHandle) node);
    }
    level++;
    for (int i = 0; i < attributes.getLength(); i++) {
        final String attrNS = attributes.getURI(i);
        final String attrLocalName = attributes.getLocalName(i);
        final String attrQName = attributes.getQName(i);
        // skip xmlns-attributes and attributes in eXist's namespace
        if (attrQName.startsWith("xmlns") || attrNS.equals(Namespaces.EXIST_NS)) {
            --attrLength;
        } else {
            p = attrQName.indexOf(':');
            final String attrPrefix = (p != Constants.STRING_NOT_FOUND) ? attrQName.substring(0, p) : null;
            final AttrImpl attr = (AttrImpl) NodePool.getInstance().borrowNode(Node.ATTRIBUTE_NODE);
            final QName attrQN = broker.getBrokerPool().getSymbols().getQName(Node.ATTRIBUTE_NODE, attrNS, attrLocalName, attrPrefix);
            try {
                attr.setNodeName(attrQN, broker.getBrokerPool().getSymbols());
            } catch (final DOMException e) {
                throw new SAXException(e.getMessage(), e);
            }
            attr.setValue(attributes.getValue(i));
            attr.setOwnerDocument(document);
            if (attributes.getType(i).equals(ATTR_ID_TYPE)) {
                attr.setType(AttrImpl.ID);
            } else if (attributes.getType(i).equals(ATTR_IDREF_TYPE)) {
                attr.setType(AttrImpl.IDREF);
            } else if (attributes.getType(i).equals(ATTR_IDREFS_TYPE)) {
                attr.setType(AttrImpl.IDREFS);
            } else if (attr.getQName().equals(Namespaces.XML_ID_QNAME)) {
                // an xml:id attribute. Normalize the attribute and set its
                // type to ID
                attr.setValue(StringValue.trimWhitespace(StringValue.collapseWhitespace(attr.getValue())));
                attr.setType(AttrImpl.ID);
            } else if (attr.getQName().equals(Namespaces.XML_SPACE_QNAME)) {
                node.setPreserveSpace("preserve".equals(attr.getValue()));
            }
            node.appendChildInternal(prevNode, attr);
            setPrevious(attr);
            if (!validate) {
                broker.storeNode(transaction, attr, currentPath, indexSpec);
                if (indexListener != null) {
                    indexListener.attribute(transaction, attr, currentPath);
                }
            }
        }
    }
    if (attrLength > 0) {
        node.setAttributes((short) attrLength);
    }
    // notify observers about progress every 100 lines
    if (locator != null) {
        currentLine = locator.getLineNumber();
        if (!validate) {
            progress.setValue(currentLine);
        }
    }
    docSize++;
}
Also used : DOMException(org.w3c.dom.DOMException) ElementImpl(org.exist.dom.persistent.ElementImpl) QName(org.exist.dom.QName) XMLString(org.exist.util.XMLString) AttrImpl(org.exist.dom.persistent.AttrImpl) SAXException(org.xml.sax.SAXException)

Example 15 with ElementImpl

use of org.exist.dom.persistent.ElementImpl in project exist by eXist-db.

the class Replace method eval.

/* (non-Javadoc)
     * @see org.exist.xquery.AbstractExpression#eval(org.exist.xquery.value.Sequence, org.exist.xquery.value.Item)
     */
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().start(this);
        context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
        if (contextSequence != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
        }
        if (contextItem != null) {
            context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT ITEM", contextItem.toSequence());
        }
    }
    if (contextItem != null) {
        contextSequence = contextItem.toSequence();
    }
    final Sequence inSeq = select.eval(contextSequence);
    if (inSeq.isEmpty()) {
        return Sequence.EMPTY_SEQUENCE;
    }
    /* If we try and Replace a node at an invalid location,
         * trap the error in a context variable,
         * this is then accessible from xquery via. the context extension module - deliriumsky
         * TODO: This trapping could be expanded further - basically where XPathException is thrown from thiss class
         * TODO: Maybe we could provide more detailed messages in the trap, e.g. couldnt replace node `xyz` into `abc` becuase... this would be nicer for the end user of the xquery application
         */
    if (!Type.subTypeOf(inSeq.getItemType(), Type.NODE)) {
        // Indicate the failure to perform this update by adding it to the sequence in the context variable XQueryContext.XQUERY_CONTEXTVAR_XQUERY_UPDATE_ERROR
        ValueSequence prevUpdateErrors = null;
        final XPathException xpe = new XPathException(this, Messages.getMessage(Error.UPDATE_SELECT_TYPE));
        final Object ctxVarObj = context.getAttribute(XQueryContext.XQUERY_CONTEXTVAR_XQUERY_UPDATE_ERROR);
        if (ctxVarObj == null) {
            prevUpdateErrors = new ValueSequence();
        } else {
            prevUpdateErrors = (ValueSequence) XPathUtil.javaObjectToXPath(ctxVarObj, context);
        }
        prevUpdateErrors.add(new StringValue(xpe.getMessage()));
        context.setAttribute(XQueryContext.XQUERY_CONTEXTVAR_XQUERY_UPDATE_ERROR, prevUpdateErrors);
        if (!inSeq.isEmpty()) {
            // TODO: should we trap this instead of throwing an exception - deliriumsky?
            throw xpe;
        }
    }
    // END trap Replace failure
    Sequence contentSeq = value.eval(contextSequence);
    if (contentSeq.isEmpty()) {
        throw new XPathException(this, Messages.getMessage(Error.UPDATE_EMPTY_CONTENT));
    }
    context.pushInScopeNamespaces();
    contentSeq = deepCopy(contentSeq);
    // start a transaction
    try (final Txn transaction = getTransaction()) {
        final StoredNode[] ql = selectAndLock(transaction, inSeq);
        final NotificationService notifier = context.getBroker().getBrokerPool().getNotificationService();
        Item temp;
        TextImpl text;
        AttrImpl attribute;
        ElementImpl parent;
        for (final StoredNode node : ql) {
            final DocumentImpl doc = node.getOwnerDocument();
            if (!doc.getPermissions().validate(context.getSubject(), Permission.WRITE)) {
                throw new PermissionDeniedException("User '" + context.getSubject().getName() + "' does not have permission to write to the document '" + doc.getDocumentURI() + "'!");
            }
            // update the document
            parent = (ElementImpl) node.getParentStoredNode();
            if (parent == null) {
                throw new XPathException(this, "The root element of a document can not be replaced with 'update replace'. " + "Please consider removing the document or use 'update value' to just replace the children of the root.");
            }
            switch(node.getNodeType()) {
                case Node.ELEMENT_NODE:
                    temp = contentSeq.itemAt(0);
                    if (!Type.subTypeOf(temp.getType(), Type.NODE)) {
                        throw new XPathException(this, Messages.getMessage(Error.UPDATE_REPLACE_ELEM_TYPE, Type.getTypeName(temp.getType())));
                    }
                    parent.replaceChild(transaction, ((NodeValue) temp).getNode(), node);
                    break;
                case Node.TEXT_NODE:
                    text = new TextImpl(contentSeq.getStringValue());
                    text.setOwnerDocument(doc);
                    parent.updateChild(transaction, node, text);
                    break;
                case Node.ATTRIBUTE_NODE:
                    final AttrImpl attr = (AttrImpl) node;
                    attribute = new AttrImpl(attr.getQName(), contentSeq.getStringValue(), context.getBroker().getBrokerPool().getSymbols());
                    attribute.setOwnerDocument(doc);
                    parent.updateChild(transaction, node, attribute);
                    break;
                default:
                    throw new EXistException("unsupported node-type");
            }
            doc.setLastModified(System.currentTimeMillis());
            modifiedDocuments.add(doc);
            context.getBroker().storeXMLResource(transaction, doc);
            notifier.notifyUpdate(doc, UpdateListener.UPDATE);
        }
        finishTriggers(transaction);
        // commit the transaction
        transaction.commit();
    } catch (final LockException | PermissionDeniedException | EXistException | TriggerException e) {
        throw new XPathException(this, e.getMessage(), e);
    } finally {
        unlockDocuments();
        context.popInScopeNamespaces();
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", Sequence.EMPTY_SEQUENCE);
    }
    return Sequence.EMPTY_SEQUENCE;
}
Also used : XPathException(org.exist.xquery.XPathException) NotificationService(org.exist.storage.NotificationService) ValueSequence(org.exist.xquery.value.ValueSequence) Sequence(org.exist.xquery.value.Sequence) Txn(org.exist.storage.txn.Txn) AttrImpl(org.exist.dom.persistent.AttrImpl) EXistException(org.exist.EXistException) DocumentImpl(org.exist.dom.persistent.DocumentImpl) TextImpl(org.exist.dom.persistent.TextImpl) Item(org.exist.xquery.value.Item) ElementImpl(org.exist.dom.persistent.ElementImpl) LockException(org.exist.util.LockException) ValueSequence(org.exist.xquery.value.ValueSequence) PermissionDeniedException(org.exist.security.PermissionDeniedException) StringValue(org.exist.xquery.value.StringValue) TriggerException(org.exist.collections.triggers.TriggerException) StoredNode(org.exist.dom.persistent.StoredNode)

Aggregations

ElementImpl (org.exist.dom.persistent.ElementImpl)15 AttrImpl (org.exist.dom.persistent.AttrImpl)5 EXistException (org.exist.EXistException)4 DocumentImpl (org.exist.dom.persistent.DocumentImpl)4 StoredNode (org.exist.dom.persistent.StoredNode)4 TextImpl (org.exist.dom.persistent.TextImpl)4 NotificationService (org.exist.storage.NotificationService)4 QName (org.exist.dom.QName)3 PermissionDeniedException (org.exist.security.PermissionDeniedException)3 XMLString (org.exist.util.XMLString)3 XPathException (org.exist.xquery.XPathException)3 Sequence (org.exist.xquery.value.Sequence)3 TriggerException (org.exist.collections.triggers.TriggerException)2 CDATASectionImpl (org.exist.dom.persistent.CDATASectionImpl)2 CommentImpl (org.exist.dom.persistent.CommentImpl)2 NodePath (org.exist.storage.NodePath)2 Txn (org.exist.storage.txn.Txn)2 LockException (org.exist.util.LockException)2 Item (org.exist.xquery.value.Item)2 StringValue (org.exist.xquery.value.StringValue)2