Search in sources :

Example 41 with XmldbURI

use of org.exist.xmldb.XmldbURI 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)

Example 42 with XmldbURI

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

the class NativeBroker method getResource.

@Override
public DocumentImpl getResource(XmldbURI fileName, final int accessType) throws PermissionDeniedException {
    fileName = prepend(fileName.toCollectionPathURI());
    // TODO : resolve URIs !!!
    final XmldbURI collUri = fileName.removeLastSegment();
    final XmldbURI docUri = fileName.lastSegment();
    try (final Collection collection = openCollection(collUri, LockMode.READ_LOCK)) {
        if (collection == null) {
            LOG.debug("collection '{}' not found!", collUri);
            return null;
        }
        try (final LockedDocument lockedDocument = collection.getDocumentWithLock(this, docUri, LockMode.READ_LOCK)) {
            // NOTE: early release of Collection lock inline with Asymmetrical Locking scheme
            collection.close();
            if (lockedDocument == null) {
                LOG.debug("document '{}' not found!", fileName);
                return null;
            }
            final DocumentImpl doc = lockedDocument.getDocument();
            if (!doc.getPermissions().validate(getCurrentSubject(), accessType)) {
                throw new PermissionDeniedException("Account '" + getCurrentSubject().getName() + "' not allowed requested access to document '" + fileName + "'");
            }
            return doc;
        } catch (final LockException e) {
            throw new PermissionDeniedException(e);
        }
    }
}
Also used : Collection(org.exist.collections.Collection) XmldbURI(org.exist.xmldb.XmldbURI)

Example 43 with XmldbURI

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

the class NativeBroker method moveResource.

@Override
public void moveResource(final Txn transaction, final DocumentImpl sourceDocument, final Collection targetCollection, final XmldbURI newName) throws PermissionDeniedException, LockException, IOException, TriggerException {
    assert (sourceDocument != null);
    assert (targetCollection != null);
    assert (newName != null);
    if (isReadOnly()) {
        throw new IOException(DATABASE_IS_READ_ONLY);
    }
    if (newName.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 destinationDocumentUri = targetCollectionUri.append(newName);
    final Account docUser = sourceDocument.getUserLock();
    if (docUser != null) {
        if (!getCurrentSubject().getName().equals(docUser.getName())) {
            throw new PermissionDeniedException("Cannot move '" + sourceDocumentUri + " because is locked by getUser() '" + docUser.getName() + "'");
        }
    }
    /**
     * As per the rules of Linux -
     *
     * mv is NOT a copy operation unless we are traversing filesystems.
     * We consider eXist to be a single filesystem, so we only need
     * WRITE and EXECUTE access on the source and destination collections
     * as we are effectively just re-linking the file.
     *
     * - Adam 2013-03-26
     */
    // we assume the caller holds a WRITE_LOCK on sourceDocument#getCollection()
    final Collection sourceCollection = sourceDocument.getCollection();
    if (!sourceCollection.getPermissionsNoLock().validate(getCurrentSubject(), Permission.WRITE | Permission.EXECUTE)) {
        throw new PermissionDeniedException("Account " + getCurrentSubject().getName() + " have insufficient privileges on source Collection to move resource: " + sourceDocumentUri);
    }
    if (!targetCollection.getPermissionsNoLock().validate(getCurrentSubject(), Permission.WRITE | Permission.EXECUTE)) {
        throw new PermissionDeniedException("Account " + getCurrentSubject().getName() + " have insufficient privileges on destination Collection '" + targetCollectionUri + "' to move resource: " + sourceDocumentUri);
    }
    if (targetCollection.hasChildCollection(this, newName.lastSegment())) {
        throw new PermissionDeniedException("The Collection '" + targetCollectionUri + "' has a sub-collection '" + newName + "'; cannot create a Document with the same name!");
    }
    final DocumentTrigger trigger = new DocumentTriggers(this, transaction, sourceCollection);
    // check if the move would overwrite a document
    final DocumentImpl oldDoc = targetCollection.getDocument(this, newName);
    if (oldDoc != null) {
        if (sourceDocument.getDocId() == oldDoc.getDocId()) {
            throw new PermissionDeniedException("Cannot move resource to itself '" + sourceDocumentUri + "'.");
        }
        // GNU mv command would prompt for Confirmation here, you can say yes or pass the '-f' flag. As we cant prompt for confirmation we assume OK
        /* if(!oldDoc.getPermissions().validate(getCurrentSubject(), Permission.WRITE)) {
                throw new PermissionDeniedException("Resource with same name exists in target collection and write is denied");
            }
            */
        // remove the existing document
        removeResource(transaction, oldDoc);
    }
    final boolean renameOnly = sourceCollection.getId() == targetCollection.getId();
    trigger.beforeMoveDocument(this, transaction, sourceDocument, destinationDocumentUri);
    if (sourceDocument.getResourceType() == DocumentImpl.XML_FILE) {
        if (!renameOnly) {
            dropIndex(transaction, sourceDocument);
        }
    }
    sourceCollection.unlinkDocument(this, sourceDocument);
    if (!renameOnly) {
        saveCollection(transaction, sourceCollection);
    }
    removeResourceMetadata(transaction, sourceDocument);
    sourceDocument.setFileURI(newName);
    sourceDocument.setCollection(targetCollection);
    targetCollection.addDocument(transaction, this, sourceDocument);
    if (sourceDocument.getResourceType() == DocumentImpl.XML_FILE) {
        if (!renameOnly) {
            // reindexing
            reindexXMLResource(transaction, sourceDocument, IndexMode.REPAIR);
        }
    }
    // NOTE: nothing needs to be done for binary resources as the reference to the Blob does not change
    storeXMLResource(transaction, sourceDocument);
    saveCollection(transaction, targetCollection);
    trigger.afterMoveDocument(this, transaction, sourceDocument, sourceDocumentUri);
}
Also used : Collection(org.exist.collections.Collection) XmldbURI(org.exist.xmldb.XmldbURI)

Example 44 with XmldbURI

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

the class SourceFactory method getSource.

/**
 * Create a {@link Source} object for the given resource URL.
 *
 * As a special case, if the URL starts with "resource:", the resource
 * will be read from the current context class loader.
 *
 * @param broker the eXist-db DBBroker
 * @param contextPath the context path of the resource.
 * @param location the location of the resource (relative to the {@code contextPath}).
 * @param checkXQEncoding where we need to check the encoding of the XQuery.
 *
 * @return The Source of the resource, or null if the resource cannot be found.
 *
 * @throws PermissionDeniedException if the resource resides in the database,
 *     but the calling user does not have permission to access it.
 * @throws IOException if a general I/O error occurs whilst accessing the resource.
 */
@Nullable
public static Source getSource(final DBBroker broker, final String contextPath, final String location, final boolean checkXQEncoding) throws IOException, PermissionDeniedException {
    Source source = null;
    /* resource: */
    if (location.startsWith(ClassLoaderSource.PROTOCOL) || (contextPath != null && contextPath.startsWith(ClassLoaderSource.PROTOCOL))) {
        source = getSource_fromClasspath(contextPath, location);
    }
    /* xmldb */
    if (source == null && (location.startsWith(XmldbURI.XMLDB_URI_PREFIX) || (contextPath != null && contextPath.startsWith(XmldbURI.XMLDB_URI_PREFIX)))) {
        XmldbURI pathUri;
        try {
            if (contextPath == null) {
                pathUri = XmldbURI.create(location);
            } else {
                pathUri = XmldbURI.create(contextPath).append(location);
            }
        } catch (final IllegalArgumentException e) {
            // this is allowed if the location is already an absolute URI, below we will try using other schemes
            pathUri = null;
        }
        if (pathUri != null) {
            source = getSource_fromDb(broker, pathUri);
        }
    }
    /* /db */
    if (source == null && ((location.startsWith("/db") && !Files.exists(Paths.get(firstPathSegment(location)))) || (contextPath != null && contextPath.startsWith("/db") && !Files.exists(Paths.get(firstPathSegment(contextPath)))))) {
        final XmldbURI pathUri;
        if (contextPath == null) {
            pathUri = XmldbURI.create(location);
        } else {
            pathUri = XmldbURI.create(contextPath).append(location);
        }
        source = getSource_fromDb(broker, pathUri);
    }
    /* file:// or location without scheme (:/) is assumed to be a file */
    if (source == null && (location.startsWith("file:/") || !location.contains(":/"))) {
        source = getSource_fromFile(contextPath, location, checkXQEncoding);
    }
    /* final attempt - any other URL */
    if (source == null && !(location.startsWith(ClassLoaderSource.PROTOCOL) || location.startsWith(XmldbURI.XMLDB_URI_PREFIX) || location.startsWith("file:/"))) {
        try {
            final URL url = new URL(location);
            source = new URLSource(url);
        } catch (final MalformedURLException e) {
            return null;
        }
    }
    return source;
}
Also used : MalformedURLException(java.net.MalformedURLException) XmldbURI(org.exist.xmldb.XmldbURI) URL(java.net.URL) Nullable(javax.annotation.Nullable)

Example 45 with XmldbURI

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

the class CollectionOrderTest method assertOrderOfSubCollections.

private void assertOrderOfSubCollections(final BrokerPool pool, final List<String> subCollectionNames) throws EXistException, PermissionDeniedException, LockException {
    // iterate the collections ensuring they are in the same order as we created them
    try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()));
        final Txn transaction = pool.getTransactionManager().beginTransaction()) {
        try (final Collection testCollection = broker.openCollection(TEST_COLLECTION, Lock.LockMode.READ_LOCK)) {
            final Iterator<XmldbURI> subCollections = testCollection.collectionIterator(broker);
            int idx = 0;
            while (subCollections.hasNext()) {
                final XmldbURI subCollection = subCollections.next();
                final String subCollectionName = subCollectionNames.get(idx++);
                assertEquals("sub-Collection names are not equal at index: " + idx, subCollectionName, subCollection.lastSegment().toString());
            }
        }
        transaction.commit();
    }
}
Also used : DBBroker(org.exist.storage.DBBroker) Txn(org.exist.storage.txn.Txn) 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