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