Search in sources :

Example 1 with NodeImpl

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

the class Insert method process.

@Override
public long process(Txn transaction) throws PermissionDeniedException, LockException, EXistException, XPathException, TriggerException {
    final NodeList children = content;
    if (children.getLength() == 0) {
        return 0;
    }
    try {
        final StoredNode[] ql = selectAndLock(transaction);
        final NotificationService notifier = broker.getBrokerPool().getNotificationService();
        final int len = children.getLength();
        if (LOG.isDebugEnabled()) {
            LOG.debug("found {} nodes to insert", len);
        }
        for (final StoredNode node : ql) {
            final DocumentImpl doc = node.getOwnerDocument();
            if (!doc.getPermissions().validate(broker.getCurrentSubject(), Permission.WRITE)) {
                throw new PermissionDeniedException("permission to update document denied");
            }
            final NodeImpl parent = (NodeImpl) getParent(node);
            switch(mode) {
                case INSERT_BEFORE:
                    parent.insertBefore(transaction, children, node);
                    break;
                case INSERT_AFTER:
                    parent.insertAfter(transaction, children, node);
                    break;
            }
            doc.setLastModified(System.currentTimeMillis());
            modifiedDocuments.add(doc);
            broker.storeXMLResource(transaction, doc);
            notifier.notifyUpdate(doc, UpdateListener.UPDATE);
        }
        checkFragmentation(transaction, modifiedDocuments);
        return ql.length;
    } finally {
        unlockDocuments(transaction);
    }
}
Also used : NodeImpl(org.exist.dom.persistent.NodeImpl) NodeList(org.w3c.dom.NodeList) NotificationService(org.exist.storage.NotificationService) PermissionDeniedException(org.exist.security.PermissionDeniedException) DocumentImpl(org.exist.dom.persistent.DocumentImpl) StoredNode(org.exist.dom.persistent.StoredNode)

Example 2 with NodeImpl

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

the class Remove method process.

@Override
public long process(Txn transaction) throws PermissionDeniedException, LockException, EXistException, XPathException, TriggerException {
    try {
        final StoredNode[] ql = selectAndLock(transaction);
        final NotificationService notifier = broker.getBrokerPool().getNotificationService();
        for (final StoredNode node : ql) {
            final DocumentImpl doc = node.getOwnerDocument();
            if (!doc.getPermissions().validate(broker.getCurrentSubject(), Permission.WRITE)) {
                throw new PermissionDeniedException("User '" + broker.getCurrentSubject().getName() + "' does not have permission to write to the document '" + doc.getDocumentURI() + "'!");
            }
            final NodeImpl parent = (NodeImpl) getParent(node);
            if (parent == null || parent.getNodeType() != Node.ELEMENT_NODE) {
                throw new EXistException("you cannot remove the document element. Use update " + "instead");
            } else {
                parent.removeChild(transaction, node);
            }
            doc.setLastModified(System.currentTimeMillis());
            modifiedDocuments.add(doc);
            broker.storeXMLResource(transaction, doc);
            notifier.notifyUpdate(doc, UpdateListener.UPDATE);
        }
        checkFragmentation(transaction, modifiedDocuments);
        return ql.length;
    } finally {
        unlockDocuments(transaction);
    }
}
Also used : NodeImpl(org.exist.dom.persistent.NodeImpl) NotificationService(org.exist.storage.NotificationService) PermissionDeniedException(org.exist.security.PermissionDeniedException) EXistException(org.exist.EXistException) DocumentImpl(org.exist.dom.persistent.DocumentImpl) StoredNode(org.exist.dom.persistent.StoredNode)

Example 3 with NodeImpl

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

the class Insert 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();
    }
    Sequence contentSeq = value.eval(contextSequence);
    if (contentSeq.isEmpty()) {
        throw new XPathException(this, Messages.getMessage(Error.UPDATE_EMPTY_CONTENT));
    }
    final Sequence inSeq = select.eval(contextSequence);
    /* If we try and Insert 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 insert 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;
        }
    }
    if (!inSeq.isEmpty()) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Found: {} nodes", inSeq.getItemCount());
        }
        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();
            final NodeList contentList = seq2nodeList(contentSeq);
            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
                if (mode == INSERT_APPEND) {
                    node.appendChildren(transaction, contentList, -1);
                } else {
                    final NodeImpl parent = (NodeImpl) getParent(node);
                    switch(mode) {
                        case INSERT_BEFORE:
                            parent.insertBefore(transaction, contentList, node);
                            break;
                        case INSERT_AFTER:
                            parent.insertAfter(transaction, contentList, node);
                            break;
                    }
                }
                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 PermissionDeniedException | EXistException | LockException | 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 : NodeImpl(org.exist.dom.persistent.NodeImpl) XPathException(org.exist.xquery.XPathException) NodeList(org.w3c.dom.NodeList) NotificationService(org.exist.storage.NotificationService) ValueSequence(org.exist.xquery.value.ValueSequence) Sequence(org.exist.xquery.value.Sequence) Txn(org.exist.storage.txn.Txn) EXistException(org.exist.EXistException) DocumentImpl(org.exist.dom.persistent.DocumentImpl) 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)

Example 4 with NodeImpl

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

the class Delete 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 we try and Delete 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 delete 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;
        }
    }
    if (!inSeq.isEmpty()) {
        // start a transaction
        try (final Txn transaction = getTransaction()) {
            final NotificationService notifier = context.getBroker().getBrokerPool().getNotificationService();
            final StoredNode[] ql = selectAndLock(transaction, inSeq);
            for (final StoredNode node : ql) {
                final DocumentImpl doc = node.getOwnerDocument();
                if (!doc.getPermissions().validate(context.getSubject(), Permission.WRITE)) {
                    // transact.abort(transaction);
                    throw new PermissionDeniedException("User '" + context.getSubject().getName() + "' does not have permission to write to the document '" + doc.getDocumentURI() + "'!");
                }
                // update the document
                final NodeImpl parent = (NodeImpl) getParent(node);
                if (parent == null) {
                    LOG.debug("Cannot remove the document element (no parent node)");
                    throw new XPathException(this, "It is not possible to remove the document element.");
                } else if (parent.getNodeType() != Node.ELEMENT_NODE) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("parent = {}; {}", parent.getNodeType(), parent.getNodeName());
                    }
                    // transact.abort(transaction);
                    throw new XPathException(this, "you cannot remove the document element. Use update " + "instead");
                } else {
                    parent.removeChild(transaction, node);
                }
                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 EXistException | PermissionDeniedException | LockException | TriggerException e) {
            throw new XPathException(this, e.getMessage(), e);
        } finally {
            unlockDocuments();
        }
    }
    if (context.getProfiler().isEnabled()) {
        context.getProfiler().end(this, "", Sequence.EMPTY_SEQUENCE);
    }
    return Sequence.EMPTY_SEQUENCE;
}
Also used : NodeImpl(org.exist.dom.persistent.NodeImpl) 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) EXistException(org.exist.EXistException) DocumentImpl(org.exist.dom.persistent.DocumentImpl) 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

DocumentImpl (org.exist.dom.persistent.DocumentImpl)4 NodeImpl (org.exist.dom.persistent.NodeImpl)4 StoredNode (org.exist.dom.persistent.StoredNode)4 PermissionDeniedException (org.exist.security.PermissionDeniedException)4 NotificationService (org.exist.storage.NotificationService)4 EXistException (org.exist.EXistException)3 TriggerException (org.exist.collections.triggers.TriggerException)2 Txn (org.exist.storage.txn.Txn)2 LockException (org.exist.util.LockException)2 XPathException (org.exist.xquery.XPathException)2 Sequence (org.exist.xquery.value.Sequence)2 StringValue (org.exist.xquery.value.StringValue)2 ValueSequence (org.exist.xquery.value.ValueSequence)2 NodeList (org.w3c.dom.NodeList)2