Search in sources :

Example 21 with Collection

use of org.exist.collections.Collection in project exist by eXist-db.

the class EmbeddedOutputStream method uploadToDb.

private static void uploadToDb(final BrokerPool pool, final XmldbURL url, final Path tempFile) throws IOException {
    try (final DBBroker broker = pool.getBroker()) {
        final XmldbURI collectionUri = XmldbURI.create(url.getCollection());
        final XmldbURI documentUri = XmldbURI.create(url.getDocumentName());
        try (final Collection collection = broker.openCollection(collectionUri, Lock.LockMode.WRITE_LOCK)) {
            if (collection == null) {
                throw new IOException("Resource " + collectionUri.toString() + " is not a collection.");
            }
            if (collection.hasChildCollection(broker, documentUri)) {
                throw new IOException("Resource " + documentUri.toString() + " is a collection.");
            }
            final MimeType mime = MimeTable.getInstance().getContentTypeFor(documentUri);
            final TransactionManager transact = pool.getTransactionManager();
            try (final Txn txn = transact.beginTransaction()) {
                broker.storeDocument(txn, documentUri, new FileInputSource(tempFile), mime, collection);
                txn.commit();
            }
        }
    } catch (final EXistException | PermissionDeniedException | LockException | SAXException e) {
        LOG.error(e);
        throw new IOException(e.getMessage(), e);
    } finally {
        if (LOG.isDebugEnabled()) {
            LOG.debug("End document upload");
        }
    }
}
Also used : Txn(org.exist.storage.txn.Txn) EXistException(org.exist.EXistException) SAXException(org.xml.sax.SAXException) DBBroker(org.exist.storage.DBBroker) TransactionManager(org.exist.storage.txn.TransactionManager) Collection(org.exist.collections.Collection) PermissionDeniedException(org.exist.security.PermissionDeniedException) XmldbURI(org.exist.xmldb.XmldbURI)

Example 22 with Collection

use of org.exist.collections.Collection in project exist by eXist-db.

the class NativeBroker method reindexCollection.

@Override
public void reindexCollection(final Txn transaction, final XmldbURI collectionUri) throws PermissionDeniedException, IOException, LockException {
    if (isReadOnly()) {
        throw new IOException(DATABASE_IS_READ_ONLY);
    }
    final XmldbURI fqUri = prepend(collectionUri.toCollectionPathURI());
    final long start = System.currentTimeMillis();
    try (final Collection collection = openCollection(fqUri, LockMode.READ_LOCK)) {
        if (collection == null) {
            LOG.warn("Collection {} not found!", fqUri);
            return;
        }
        LOG.info("Start indexing collection {}", collection.getURI().toString());
        pool.getProcessMonitor().startJob(ProcessMonitor.ACTION_REINDEX_COLLECTION, collection.getURI());
        reindexCollection(transaction, collection, IndexMode.STORE);
    } catch (final PermissionDeniedException | IOException e) {
        LOG.error("An error occurred during reindex: {}", e.getMessage(), e);
    } finally {
        pool.getProcessMonitor().endJob();
        LOG.info("Finished indexing collection {} in {} ms.", fqUri, System.currentTimeMillis() - start);
    }
}
Also used : Collection(org.exist.collections.Collection) XmldbURI(org.exist.xmldb.XmldbURI)

Example 23 with Collection

use of org.exist.collections.Collection in project exist by eXist-db.

the class NativeBroker method lockDescendantDocuments.

/**
 * Acquires locks on all descendant Collections of a specific Collection
 *
 * Locks are acquired in a top-down, left-to-right order
 *
 * NOTE: It is assumed that the caller holds a lock on the
 *     `collection` of the same mode as those that we should acquire on the descendants
 *
 * @param collection The Collection whose descendant locks should be acquired
 * @param lockFn A function for acquiring a lock
 *
 * @return A list of locks in the same order as collectionUris. Note that these should be released in reverse order
 */
private List<ManagedDocumentLock> lockDescendantDocuments(final Collection collection, final FunctionE<XmldbURI, ManagedDocumentLock, LockException> lockFn) throws LockException, PermissionDeniedException {
    final List<ManagedDocumentLock> locks = new ArrayList<>();
    try {
        final Iterator<DocumentImpl> itDoc = collection.iteratorNoLock(this);
        while (itDoc.hasNext()) {
            final DocumentImpl doc = itDoc.next();
            final ManagedDocumentLock docLock = lockFn.apply(doc.getURI());
            locks.add(docLock);
        }
        final XmldbURI collectionUri = collection.getURI();
        // NOTE: we should already have a lock on collection
        final Iterator<XmldbURI> it = collection.collectionIteratorNoLock(this);
        while (it.hasNext()) {
            final XmldbURI childCollectionName = it.next();
            final XmldbURI childCollectionUri = collectionUri.append(childCollectionName);
            // NOTE: we don't need to lock the collection as we should already implicitly have a lock on the collection sub-tree
            final Collection childCollection = getCollection(childCollectionUri);
            final List<ManagedDocumentLock> descendantLocks = lockDescendantDocuments(childCollection, lockFn);
            locks.addAll(descendantLocks);
        }
    } catch (final PermissionDeniedException | LockException e) {
        // unlock in reverse order
        try {
            ManagedLocks.closeAll(locks);
        } catch (final RuntimeException re) {
            LOG.error(re);
        }
        throw e;
    }
    return locks;
}
Also used : Collection(org.exist.collections.Collection) XmldbURI(org.exist.xmldb.XmldbURI)

Example 24 with Collection

use of org.exist.collections.Collection in project exist by eXist-db.

the class NativeBroker method copyResource.

@Override
public void copyResource(final Txn transaction, final DocumentImpl sourceDocument, final Collection targetCollection, final XmldbURI newDocName, final PreserveType preserve) throws PermissionDeniedException, LockException, IOException, TriggerException, EXistException {
    assert (sourceDocument != null);
    assert (targetCollection != null);
    assert (newDocName != null);
    if (isReadOnly()) {
        throw new IOException(DATABASE_IS_READ_ONLY);
    }
    if (newDocName.numSegments() != 1) {
        throw new IOException("newName name must be just a name i.e. an XmldbURI with one segment!");
    }
    final XmldbURI sourceDocumentUri = sourceDocument.getURI();
    final XmldbURI targetCollectionUri = targetCollection.getURI();
    final XmldbURI targetDocumentUri = targetCollectionUri.append(newDocName);
    if (!sourceDocument.getPermissions().validate(getCurrentSubject(), Permission.READ)) {
        throw new PermissionDeniedException("Account '" + getCurrentSubject().getName() + "' has insufficient privileges to copy the resource '" + sourceDocumentUri + "'.");
    }
    // we assume the caller holds a READ_LOCK (or better) on sourceDocument#getCollection()
    final Collection sourceCollection = sourceDocument.getCollection();
    if (!sourceCollection.getPermissions().validate(getCurrentSubject(), Permission.EXECUTE)) {
        throw new PermissionDeniedException("Account '" + getCurrentSubject().getName() + "' has insufficient privileges to copy the resource '" + sourceDocumentUri + "'.");
    }
    if (!targetCollection.getPermissionsNoLock().validate(getCurrentSubject(), Permission.EXECUTE)) {
        throw new PermissionDeniedException("Account '" + getCurrentSubject().getName() + "' does not have execute access on the destination collection '" + targetCollectionUri + "'.");
    }
    if (targetCollection.hasChildCollection(this, newDocName.lastSegment())) {
        throw new EXistException("The collection '" + targetCollectionUri + "' already has a sub-collection named '" + newDocName.lastSegment() + "', you cannot create a Document with the same name as an existing collection.");
    }
    try (final LockedDocument oldLockedDoc = targetCollection.getDocumentWithLock(this, newDocName, LockMode.WRITE_LOCK)) {
        final DocumentTrigger trigger = new DocumentTriggers(this, transaction, targetCollection);
        final DocumentImpl oldDoc = oldLockedDoc == null ? null : oldLockedDoc.getDocument();
        if (oldDoc == null) {
            if (!targetCollection.getPermissionsNoLock().validate(getCurrentSubject(), Permission.WRITE)) {
                throw new PermissionDeniedException("Account '" + getCurrentSubject().getName() + "' does not have write access on the destination collection '" + targetCollectionUri + "'.");
            }
        } else {
            if (sourceDocument.getDocId() == oldDoc.getDocId()) {
                throw new PermissionDeniedException("Cannot copy resource to itself '" + sourceDocumentUri + "'.");
            }
            if (!oldDoc.getPermissions().validate(getCurrentSubject(), Permission.WRITE)) {
                throw new PermissionDeniedException("A resource with the same name already exists in the target collection '" + oldDoc.getURI() + "', and you do not have write access on that resource.");
            }
            trigger.beforeDeleteDocument(this, transaction, oldDoc);
            trigger.afterDeleteDocument(this, transaction, targetDocumentUri);
        }
        doCopyDocument(transaction, trigger, sourceDocument, targetCollection, newDocName, oldDoc, preserve);
    }
}
Also used : Collection(org.exist.collections.Collection) EXistException(org.exist.EXistException) XmldbURI(org.exist.xmldb.XmldbURI)

Example 25 with Collection

use of org.exist.collections.Collection in project exist by eXist-db.

the class NativeBroker method readCollectionEntry.

@Override
public void readCollectionEntry(final SubCollectionEntry entry) throws IOException, LockException {
    final XmldbURI uri = prepend(entry.getUri().toCollectionPathURI());
    final CollectionCache collectionsCache = pool.getCollectionsCache();
    final Collection collection = collectionsCache.getIfPresent(uri);
    if (collection == null) {
        try (final ManagedLock<ReentrantLock> collectionsDbLock = lockManager.acquireBtreeReadLock(collectionsDb.getLockName())) {
            final Value key = new CollectionStore.CollectionKey(uri.toString());
            final VariableByteInput is = collectionsDb.getAsStream(key);
            if (is == null) {
                throw new IOException("Could not find collection entry for: " + uri);
            }
            // read the entry details
            entry.read(is);
        }
    } else {
        if (!collection.getURI().equalsInternal(uri)) {
            throw new IOException(String.format("readCollectionEntry: The Collection received from the cache: %s is not the requested: %s", collection.getURI(), uri));
        }
        entry.read(collection);
    }
}
Also used : ReentrantLock(java.util.concurrent.locks.ReentrantLock) VariableByteInput(org.exist.storage.io.VariableByteInput) Collection(org.exist.collections.Collection) XmldbURI(org.exist.xmldb.XmldbURI)

Aggregations

Collection (org.exist.collections.Collection)297 Txn (org.exist.storage.txn.Txn)160 XmldbURI (org.exist.xmldb.XmldbURI)99 DBBroker (org.exist.storage.DBBroker)89 TransactionManager (org.exist.storage.txn.TransactionManager)86 BrokerPool (org.exist.storage.BrokerPool)69 StringInputSource (org.exist.util.StringInputSource)57 Test (org.junit.Test)57 EXistException (org.exist.EXistException)43 PermissionDeniedException (org.exist.security.PermissionDeniedException)43 DocumentImpl (org.exist.dom.persistent.DocumentImpl)42 IOException (java.io.IOException)33 LockedDocument (org.exist.dom.persistent.LockedDocument)31 SAXException (org.xml.sax.SAXException)26 InputStream (java.io.InputStream)19 Path (java.nio.file.Path)19 Permission (org.exist.security.Permission)19 LockException (org.exist.util.LockException)16 TriggerException (org.exist.collections.triggers.TriggerException)15 BinaryDocument (org.exist.dom.persistent.BinaryDocument)15