Search in sources :

Example 1 with NotificationService

use of org.exist.storage.NotificationService in project exist by eXist-db.

the class Append 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();
        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() + "'!");
            }
            node.appendChildren(transaction, children, child);
            doc.setLastModified(System.currentTimeMillis());
            modifiedDocuments.add(doc);
            broker.storeXMLResource(transaction, doc);
            notifier.notifyUpdate(doc, UpdateListener.UPDATE);
        }
        checkFragmentation(transaction, modifiedDocuments);
        return ql.length;
    } finally {
        // release all acquired locks
        unlockDocuments(transaction);
    }
}
Also used : 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 NotificationService

use of org.exist.storage.NotificationService 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 3 with NotificationService

use of org.exist.storage.NotificationService 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 4 with NotificationService

use of org.exist.storage.NotificationService in project exist by eXist-db.

the class Update method process.

@Override
public long process(Txn transaction) throws PermissionDeniedException, LockException, EXistException, XPathException, TriggerException {
    final NodeList children = content;
    if (children.getLength() == 0) {
        return 0;
    }
    int modifications = children.getLength();
    try {
        final StoredNode[] ql = selectAndLock(transaction);
        final NotificationService notifier = broker.getBrokerPool().getNotificationService();
        for (final StoredNode node : ql) {
            if (node == null) {
                LOG.warn("select {} returned empty node", selectStmt);
                continue;
            }
            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() + "'!");
            }
            switch(node.getNodeType()) {
                case Node.ELEMENT_NODE:
                    if (modifications == 0) {
                        modifications = 1;
                    }
                    ((ElementImpl) node).update(transaction, children);
                    break;
                case Node.TEXT_NODE:
                    final ElementImpl textParent = (ElementImpl) node.getParentNode();
                    final Node textTemp = children.item(0);
                    final TextImpl text = new TextImpl(textTemp.getNodeValue());
                    modifications = 1;
                    text.setOwnerDocument(doc);
                    textParent.updateChild(transaction, node, text);
                    break;
                case Node.ATTRIBUTE_NODE:
                    final ElementImpl attrParent = (ElementImpl) ((Attr) node).getOwnerElement();
                    if (attrParent == null) {
                        LOG.warn("parent node not found for {}", node.getNodeId());
                        break;
                    }
                    final AttrImpl attr = (AttrImpl) node;
                    final Node attrTemp = children.item(0);
                    final AttrImpl attribute = new AttrImpl(attr.getQName(), attrTemp.getNodeValue(), broker.getBrokerPool().getSymbols());
                    attribute.setOwnerDocument(doc);
                    attrParent.updateChild(transaction, node, attribute);
                    break;
                default:
                    throw new EXistException("unsupported node-type");
            }
            doc.setLastModified(System.currentTimeMillis());
            modifiedDocuments.add(doc);
            broker.storeXMLResource(transaction, doc);
            notifier.notifyUpdate(doc, UpdateListener.UPDATE);
        }
        checkFragmentation(transaction, modifiedDocuments);
    } finally {
        unlockDocuments(transaction);
    }
    return modifications;
}
Also used : ElementImpl(org.exist.dom.persistent.ElementImpl) NodeList(org.w3c.dom.NodeList) StoredNode(org.exist.dom.persistent.StoredNode) Node(org.w3c.dom.Node) NotificationService(org.exist.storage.NotificationService) PermissionDeniedException(org.exist.security.PermissionDeniedException) AttrImpl(org.exist.dom.persistent.AttrImpl) EXistException(org.exist.EXistException) DocumentImpl(org.exist.dom.persistent.DocumentImpl) TextImpl(org.exist.dom.persistent.TextImpl) StoredNode(org.exist.dom.persistent.StoredNode)

Example 5 with NotificationService

use of org.exist.storage.NotificationService 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)

Aggregations

NotificationService (org.exist.storage.NotificationService)11 PermissionDeniedException (org.exist.security.PermissionDeniedException)10 EXistException (org.exist.EXistException)9 DocumentImpl (org.exist.dom.persistent.DocumentImpl)9 StoredNode (org.exist.dom.persistent.StoredNode)9 NodeList (org.w3c.dom.NodeList)6 TriggerException (org.exist.collections.triggers.TriggerException)5 Txn (org.exist.storage.txn.Txn)5 LockException (org.exist.util.LockException)5 Sequence (org.exist.xquery.value.Sequence)5 StringValue (org.exist.xquery.value.StringValue)5 ValueSequence (org.exist.xquery.value.ValueSequence)5 AttrImpl (org.exist.dom.persistent.AttrImpl)4 ElementImpl (org.exist.dom.persistent.ElementImpl)4 NodeImpl (org.exist.dom.persistent.NodeImpl)4 TextImpl (org.exist.dom.persistent.TextImpl)4 XPathException (org.exist.xquery.XPathException)4 Item (org.exist.xquery.value.Item)3 QName (org.exist.dom.QName)2 Node (org.w3c.dom.Node)2