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);
}
}
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);
}
}
}
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);
}
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;
}
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();
}
}
Aggregations