Search in sources :

Example 26 with XmldbURI

use of org.exist.xmldb.XmldbURI in project exist by eXist-db.

the class XMLDBMove method evalWithCollection.

/* (non-Javadoc)
     * @see org.exist.xquery.BasicFunction#eval(org.exist.xquery.value.Sequence[], org.exist.xquery.value.Sequence)
     */
public Sequence evalWithCollection(Collection collection, Sequence[] args, Sequence contextSequence) throws XPathException {
    final XmldbURI destination = new AnyURIValue(args[1].itemAt(0).getStringValue()).toXmldbURI();
    if (getSignature().getArgumentCount() == 3) {
        final XmldbURI doc = new AnyURIValue(args[2].itemAt(0).getStringValue()).toXmldbURI();
        try {
            final Resource resource = collection.getResource(doc.toString());
            if (resource == null) {
                logger.error("Resource {} not found", doc);
                throw new XPathException(this, "Resource " + doc + " not found");
            }
            final EXistCollectionManagementService service = (EXistCollectionManagementService) collection.getService("CollectionManagementService", "1.0");
            service.moveResource(doc, destination, null);
        } catch (final XMLDBException e) {
            logger.error(e.getMessage());
            throw new XPathException(this, "XMLDB exception caught: " + e.getMessage(), e);
        }
    } else {
        try {
            final EXistCollectionManagementService service = (EXistCollectionManagementService) collection.getService("CollectionManagementService", "1.0");
            service.move(XmldbURI.xmldbUriFor(collection.getName()), destination, null);
        } catch (final XMLDBException e) {
            logger.error(e.getMessage());
            throw new XPathException(this, "Cannot move collection: " + e.getMessage(), e);
        } catch (final URISyntaxException e) {
            logger.error(e.getMessage());
            throw new XPathException(this, "URI exception: " + e.getMessage(), e);
        }
    }
    return Sequence.EMPTY_SEQUENCE;
}
Also used : XPathException(org.exist.xquery.XPathException) EXistCollectionManagementService(org.exist.xmldb.EXistCollectionManagementService) AnyURIValue(org.exist.xquery.value.AnyURIValue) Resource(org.xmldb.api.base.Resource) XMLDBException(org.xmldb.api.base.XMLDBException) URISyntaxException(java.net.URISyntaxException) XmldbURI(org.exist.xmldb.XmldbURI)

Example 27 with XmldbURI

use of org.exist.xmldb.XmldbURI in project exist by eXist-db.

the class AuditTrailSessionListenerTest method sessionDestroyed.

/**
 * Ensures that AuditTrailSessionListener releases any locks
 * on the XQuery document when destroying a session
 */
@Test
public void sessionDestroyed() throws EXistException, PermissionDeniedException {
    final HttpSessionEvent httpSessionEvent = createMock(HttpSessionEvent.class);
    final HttpSession httpSession = createMock(HttpSession.class);
    expect(httpSessionEvent.getSession()).andReturn(httpSession);
    expect(httpSession.getId()).andReturn("mock-session");
    replay(httpSessionEvent, httpSession);
    final AuditTrailSessionListener listener = new AuditTrailSessionListener();
    listener.sessionDestroyed(httpSessionEvent);
    verify(httpSessionEvent, httpSession);
    final XmldbURI docUri = XmldbURI.create(DESTROYED_SCRIPT_PATH);
    try (final DBBroker broker = existEmbeddedServer.getBrokerPool().getBroker();
        final LockedDocument lockedResource = broker.getXMLResource(docUri, Lock.LockMode.NO_LOCK)) {
        // ensure that AuditTrailSessionListener released the lock
        final LockManager lockManager = broker.getBrokerPool().getLockManager();
        assertFalse(lockManager.isDocumentLockedForRead(docUri));
        assertFalse(lockManager.isDocumentLockedForWrite(docUri));
    }
}
Also used : LockManager(org.exist.storage.lock.LockManager) DBBroker(org.exist.storage.DBBroker) HttpSession(javax.servlet.http.HttpSession) HttpSessionEvent(javax.servlet.http.HttpSessionEvent) LockedDocument(org.exist.dom.persistent.LockedDocument) XmldbURI(org.exist.xmldb.XmldbURI) Test(org.junit.Test)

Example 28 with XmldbURI

use of org.exist.xmldb.XmldbURI in project exist by eXist-db.

the class AuditTrailSessionListenerTest method sessionCreated.

/**
 * Ensures that AuditTrailSessionListener releases any locks
 * on the XQuery document when creating a session
 */
@Test
public void sessionCreated() throws EXistException, PermissionDeniedException {
    final HttpSessionEvent httpSessionEvent = createMock(HttpSessionEvent.class);
    final HttpSession httpSession = createMock(HttpSession.class);
    expect(httpSessionEvent.getSession()).andReturn(httpSession);
    expect(httpSession.getId()).andReturn("mock-session");
    replay(httpSessionEvent, httpSession);
    final AuditTrailSessionListener listener = new AuditTrailSessionListener();
    listener.sessionCreated(httpSessionEvent);
    verify(httpSessionEvent, httpSession);
    final XmldbURI docUri = XmldbURI.create(CREATE_SCRIPT_PATH);
    try (final DBBroker broker = existEmbeddedServer.getBrokerPool().getBroker();
        final LockedDocument lockedResource = broker.getXMLResource(docUri, Lock.LockMode.NO_LOCK)) {
        // ensure that AuditTrailSessionListener released the lock
        final LockManager lockManager = broker.getBrokerPool().getLockManager();
        assertFalse(lockManager.isDocumentLockedForRead(docUri));
        assertFalse(lockManager.isDocumentLockedForWrite(docUri));
    }
}
Also used : LockManager(org.exist.storage.lock.LockManager) DBBroker(org.exist.storage.DBBroker) HttpSession(javax.servlet.http.HttpSession) HttpSessionEvent(javax.servlet.http.HttpSessionEvent) LockedDocument(org.exist.dom.persistent.LockedDocument) XmldbURI(org.exist.xmldb.XmldbURI) Test(org.junit.Test)

Example 29 with XmldbURI

use of org.exist.xmldb.XmldbURI in project exist by eXist-db.

the class NativeBroker method moveCollectionRecursive.

// TODO bug the trigger param is reused as this is a recursive method, but in the current design triggers are only meant to be called once for each action and then destroyed!
/**
 * Recursive-descent Collection move, only meant to be
 * called from {@link #moveCollection(Txn, Collection, Collection, XmldbURI)}
 *
 * @param transaction The current transaction
 * @param trigger The trigger to fire on Collection events
 * @param sourceCollection The Collection to move
 * @param targetCollection The target Collection to move the sourceCollection into
 * @param newName The new name the sourceCollection should have in the targetCollection
 * @param fireTrigger Indicates whether the CollectionTrigger should be fired
 *     on the Collection the first time this function is called. Triggers will always
 *     be fired for recursive calls of this function.
 */
private void moveCollectionRecursive(final Txn transaction, final CollectionTrigger trigger, @Nullable @EnsureLocked(mode = LockMode.WRITE_LOCK) final Collection sourceCollectionParent, @EnsureLocked(mode = LockMode.WRITE_LOCK) final Collection sourceCollection, @EnsureLocked(mode = LockMode.WRITE_LOCK) final Collection targetCollection, final XmldbURI newName, final boolean fireTrigger) throws PermissionDeniedException, IOException, LockException, TriggerException {
    final XmldbURI sourceCollectionUri = sourceCollection.getURI();
    final XmldbURI destinationCollectionUri = targetCollection.getURI().append(newName);
    if (fireTrigger) {
        trigger.beforeMoveCollection(this, transaction, sourceCollection, destinationCollectionUri);
    }
    // de-reference any existing binaries in the destination from the blob store
    try (final Collection dst = openCollection(destinationCollectionUri, LockMode.WRITE_LOCK)) {
        if (dst != null) {
            final Iterator<DocumentImpl> itDoc = dst.iterator(this);
            while (itDoc.hasNext()) {
                final DocumentImpl dstDoc = itDoc.next();
                if (dstDoc instanceof BinaryDocument) {
                    final BinaryDocument binDstDoc = (BinaryDocument) dstDoc;
                    try (final ManagedDocumentLock dstDocLock = lockManager.acquireDocumentWriteLock(dstDoc.getURI())) {
                        removeBinaryResource(transaction, binDstDoc);
                        binDstDoc.setBlobId(null);
                    }
                }
            }
        }
    }
    // remove source from parent
    if (sourceCollectionParent != null) {
        final XmldbURI sourceCollectionName = sourceCollectionUri.lastSegment();
        sourceCollectionParent.removeCollection(this, sourceCollectionName);
        // if this is a rename, the save will happen after we "add the destination to the target" below...
        if (!sourceCollectionParent.getURI().equals(targetCollection)) {
            saveCollection(transaction, sourceCollectionParent);
        }
    }
    // remove source from cache
    final CollectionCache collectionsCache = pool.getCollectionsCache();
    collectionsCache.invalidate(sourceCollection.getURI());
    // remove source from disk
    try (final ManagedLock<ReentrantLock> collectionsDbLock = lockManager.acquireBtreeWriteLock(collectionsDb.getLockName())) {
        final Value key = new CollectionStore.CollectionKey(sourceCollectionUri.toString());
        collectionsDb.remove(transaction, key);
    }
    // set source path to destination... source is now the destination
    sourceCollection.setPath(destinationCollectionUri, true);
    saveCollection(transaction, sourceCollection);
    // add destination to target
    targetCollection.addCollection(this, sourceCollection);
    saveCollection(transaction, targetCollection);
    if (fireTrigger) {
        trigger.afterMoveCollection(this, transaction, sourceCollection, sourceCollectionUri);
    }
    // move the descendants
    for (final Iterator<XmldbURI> i = sourceCollection.collectionIteratorNoLock(this); i.hasNext(); ) {
        // NOTE: we already have a WRITE lock on sourceCollection
        final XmldbURI childName = i.next();
        final XmldbURI childUri = sourceCollectionUri.append(childName);
        // NOTE: we have a write lock on the sourceCollection, which means we don't need to lock sub-collections in the tree
        final Collection child = getCollectionForOpen(collectionsCache, childUri);
        if (child == null) {
            throw new IOException("Child collection " + childUri + " not found");
        } else {
            moveCollectionRecursive(transaction, trigger, null, child, sourceCollection, childName, true);
        }
    }
}
Also used : ReentrantLock(java.util.concurrent.locks.ReentrantLock) Collection(org.exist.collections.Collection) XmldbURI(org.exist.xmldb.XmldbURI)

Example 30 with XmldbURI

use of org.exist.xmldb.XmldbURI in project exist by eXist-db.

the class NativeBroker method lockTargetDocuments.

/**
 * Locks target documents (useful for copy/move operations).
 *
 * @param sourceCollectionUri The source collection URI root of the copy/move operation
 * @param sourceDocumentLocks Locks on the source documents, for which target document locks should be acquired
 * @param targetCollectionUri The target collection URI root of the copy/move operation
 * @param lockFn The function for locking the target document.
 *
 * @return A list of locks on the target documents.
 */
private List<ManagedDocumentLock> lockTargetDocuments(final XmldbURI sourceCollectionUri, final ManagedLocks<ManagedDocumentLock> sourceDocumentLocks, final XmldbURI targetCollectionUri, final FunctionE<XmldbURI, ManagedDocumentLock, LockException> lockFn) throws LockException {
    final List<ManagedDocumentLock> locks = new ArrayList<>();
    try {
        for (final ManagedDocumentLock sourceDocumentLock : sourceDocumentLocks) {
            final XmldbURI sourceDocumentUri = sourceDocumentLock.getPath();
            final URI relativeDocumentUri = sourceCollectionUri.relativizeCollectionPath(sourceDocumentUri.getURI());
            final XmldbURI targetDocumentUri = XmldbURI.create(targetCollectionUri.resolveCollectionPath(relativeDocumentUri));
            final ManagedDocumentLock documentLock = lockFn.apply(targetDocumentUri);
            locks.add(documentLock);
        }
    } catch (final LockException e) {
        // unlock in reverse order
        try {
            ManagedLocks.closeAll(locks);
        } catch (final RuntimeException re) {
            LOG.error(re);
        }
        throw e;
    }
    return locks;
}
Also used : URI(java.net.URI) XmldbURI(org.exist.xmldb.XmldbURI) XmldbURI(org.exist.xmldb.XmldbURI)

Aggregations

XmldbURI (org.exist.xmldb.XmldbURI)260 Collection (org.exist.collections.Collection)100 PermissionDeniedException (org.exist.security.PermissionDeniedException)69 Test (org.junit.Test)56 Txn (org.exist.storage.txn.Txn)55 EXistException (org.exist.EXistException)42 URISyntaxException (java.net.URISyntaxException)39 LockedDocument (org.exist.dom.persistent.LockedDocument)39 IOException (java.io.IOException)38 DBBroker (org.exist.storage.DBBroker)38 DocumentImpl (org.exist.dom.persistent.DocumentImpl)34 SAXException (org.xml.sax.SAXException)33 Permission (org.exist.security.Permission)30 LockException (org.exist.util.LockException)27 Path (java.nio.file.Path)22 XPathException (org.exist.xquery.XPathException)22 BrokerPool (org.exist.storage.BrokerPool)21 TransactionManager (org.exist.storage.txn.TransactionManager)20 Subject (org.exist.security.Subject)19 StringInputSource (org.exist.util.StringInputSource)17