use of org.exist.storage.txn.TransactionManager in project exist by eXist-db.
the class ExistDocument method resourceCopyMove.
/**
* Copy document or collection in database.
*/
void resourceCopyMove(XmldbURI destCollectionUri, String newName, Mode mode) throws EXistException {
if (LOG.isDebugEnabled()) {
LOG.debug("{} {} to {} named {}", String.valueOf(mode), xmldbUri, destCollectionUri, newName);
}
XmldbURI newNameUri = null;
try {
newNameUri = XmldbURI.xmldbUriFor(newName);
} catch (URISyntaxException ex) {
LOG.error(ex);
throw new EXistException(ex.getMessage());
}
// use WRITE_LOCK if moving or if src and dest collection are the same
final LockMode srcCollectionLockMode = mode == Mode.MOVE || destCollectionUri.equals(xmldbUri.removeLastSegment()) ? LockMode.WRITE_LOCK : LockMode.READ_LOCK;
DocumentImpl srcDocument = null;
// Need to split path into collection and document name
final XmldbURI srcCollectionUri = xmldbUri.removeLastSegment();
final XmldbURI srdDocumentUri = xmldbUri.lastSegment();
final TransactionManager txnManager = brokerPool.getTransactionManager();
try (final DBBroker broker = brokerPool.get(Optional.ofNullable(subject));
final Txn txn = txnManager.beginTransaction();
final Collection srcCollection = broker.openCollection(srcCollectionUri, srcCollectionLockMode)) {
// Open collection if possible, else abort
if (srcCollection == null) {
txnManager.abort(txn);
// TODO throw
return;
}
// Open document if possible, else abort
srcDocument = srcCollection.getDocument(broker, srdDocumentUri);
if (srcDocument == null) {
LOG.debug("No resource found for path: {}", xmldbUri);
txnManager.abort(txn);
return;
}
// Open collection if possible, else abort
try (final Collection destCollection = broker.openCollection(destCollectionUri, LockMode.WRITE_LOCK)) {
if (destCollection == null) {
LOG.debug("Destination collection {} does not exist.", xmldbUri);
txnManager.abort(txn);
return;
}
// Perform actial move/copy
if (mode == Mode.COPY) {
broker.copyResource(txn, srcDocument, destCollection, newNameUri);
} else {
broker.moveResource(txn, srcDocument, destCollection, newNameUri);
}
// Commit change
txnManager.commit(txn);
if (LOG.isDebugEnabled()) {
LOG.debug("Document {}d successfully", mode);
}
}
} catch (LockException e) {
LOG.error("Resource is locked.", e);
throw new EXistException(e.getMessage());
} catch (EXistException e) {
LOG.error(e);
throw e;
} catch (IOException | PermissionDeniedException | TriggerException e) {
LOG.error(e);
throw new EXistException(e.getMessage());
} finally {
if (LOG.isDebugEnabled()) {
LOG.debug("Finished {}", mode);
}
}
}
use of org.exist.storage.txn.TransactionManager in project exist by eXist-db.
the class ExistDocument method refreshLock.
public LockToken refreshLock(String token) throws PermissionDeniedException, DocumentAlreadyLockedException, EXistException, DocumentNotLockedException {
if (LOG.isDebugEnabled()) {
LOG.debug("refresh lock {} lock={}", xmldbUri, token);
}
if (token == null) {
if (LOG.isDebugEnabled()) {
LOG.debug("token is null");
}
throw new EXistException("token is null");
}
// Try to get document
try (final DBBroker broker = brokerPool.get(Optional.ofNullable(subject));
final LockedDocument lockedDocument = broker.getXMLResource(xmldbUri, LockMode.WRITE_LOCK)) {
final DocumentImpl document = lockedDocument.getDocument();
if (document == null) {
if (LOG.isDebugEnabled()) {
LOG.debug("No resource found for path: {}", xmldbUri);
}
// return null; // throw exception?
throw new EXistException("No resource found.");
}
// Get current userlock
Account userLock = document.getUserLock();
// Check if Resource is already locked.
if (userLock == null) {
final String msg = "Resource was not locked.";
if (LOG.isDebugEnabled()) {
LOG.debug(msg);
}
throw new DocumentNotLockedException(msg);
}
if (userLock.getName() != null && !userLock.getName().equals(subject.getName()) && !subject.hasDbaRole()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Resource is locked by {}", userLock.getName());
}
throw new PermissionDeniedException(userLock.getName());
}
LockToken lockToken = document.getLockToken();
if (!token.equals(lockToken.getOpaqueLockToken())) {
if (LOG.isDebugEnabled()) {
LOG.debug("Token does not match");
}
throw new PermissionDeniedException(String.format("Token %s does not match %s", token, lockToken.getOpaqueLockToken()));
}
lockToken.setTimeOut(LockToken.LOCK_TIMEOUT_INFINITE);
// Make token persistant
final TransactionManager txnManager = brokerPool.getTransactionManager();
try (final Txn txn = txnManager.beginTransaction()) {
broker.storeXMLResource(txn, document);
txnManager.commit(txn);
}
if (LOG.isDebugEnabled()) {
LOG.debug("Successfully retrieved token");
}
return lockToken;
} catch (EXistException | PermissionDeniedException e) {
LOG.error(e);
throw e;
} finally {
if (LOG.isDebugEnabled()) {
LOG.debug("Finished create lock");
}
}
}
use of org.exist.storage.txn.TransactionManager in project exist by eXist-db.
the class ExistCollection method resourceCopyMove.
void resourceCopyMove(XmldbURI destCollectionUri, String newName, Mode mode) throws EXistException {
if (LOG.isDebugEnabled()) {
LOG.debug("{} '{}' to '{}' named '{}'", String.valueOf(mode), xmldbUri, destCollectionUri, newName);
}
XmldbURI newNameUri = null;
try {
newNameUri = XmldbURI.xmldbUriFor(newName);
} catch (URISyntaxException ex) {
LOG.error(ex);
throw new EXistException(ex.getMessage());
}
// This class contains already the URI of the resource that shall be moved/copied
XmldbURI srcCollectionUri = xmldbUri;
// use WRITE_LOCK if moving or if src and dest collection are the same
final LockMode srcCollectionLockMode = mode == Mode.MOVE || destCollectionUri.equals(srcCollectionUri) ? LockMode.WRITE_LOCK : LockMode.READ_LOCK;
final TransactionManager txnManager = brokerPool.getTransactionManager();
try (final DBBroker broker = brokerPool.get(Optional.ofNullable(subject));
final Txn txn = txnManager.beginTransaction();
final Collection srcCollection = broker.openCollection(srcCollectionUri, srcCollectionLockMode)) {
// Open collection if possible, else abort
if (srcCollection == null) {
txnManager.abort(txn);
// TODO throw
return;
}
// Open collection if possible, else abort
try (final Collection destCollection = broker.openCollection(destCollectionUri, LockMode.WRITE_LOCK)) {
if (destCollection == null) {
LOG.debug("Destination collection {} does not exist.", xmldbUri);
txnManager.abort(txn);
// TODO throw?
return;
}
// Perform actial move/copy
if (mode == Mode.COPY) {
broker.copyCollection(txn, srcCollection, destCollection, newNameUri);
} else {
broker.moveCollection(txn, srcCollection, destCollection, newNameUri);
}
// Commit change
txnManager.commit(txn);
if (LOG.isDebugEnabled()) {
LOG.debug("Collection {}d successfully", mode);
}
}
} catch (LockException e) {
LOG.error("Resource is locked.", e);
throw new EXistException(e.getMessage());
} catch (EXistException e) {
LOG.error(e);
throw e;
} catch (IOException | PermissionDeniedException | TriggerException e) {
LOG.error(e);
throw new EXistException(e.getMessage());
} finally {
if (LOG.isDebugEnabled()) {
LOG.debug("Finished {}", mode);
}
}
}
use of org.exist.storage.txn.TransactionManager in project exist by eXist-db.
the class ExistCollection method createFile.
public XmldbURI createFile(String newName, InputStream is, Long length, String contentType) throws IOException, PermissionDeniedException, CollectionDoesNotExistException {
if (LOG.isDebugEnabled())
LOG.debug("Create '{}' in '{}'", newName, xmldbUri);
XmldbURI newNameUri = XmldbURI.create(newName);
// Get mime, or NULL when not available
MimeType mime = MimeTable.getInstance().getContentTypeFor(newName);
if (mime == null) {
mime = MimeType.BINARY_TYPE;
}
// XML documents are not supported a small file will be created.
if (mime.isXMLType() && length == 0) {
if (LOG.isDebugEnabled()) {
LOG.debug("Creating dummy XML file for null resource lock '{}'", newNameUri);
}
is = new UnsynchronizedByteArrayInputStream("<null_resource/>".getBytes(StandardCharsets.UTF_8));
}
final TransactionManager txnManager = brokerPool.getTransactionManager();
try (final DBBroker broker = brokerPool.get(Optional.ofNullable(subject));
final Txn txn = txnManager.beginTransaction();
final Collection collection = broker.openCollection(xmldbUri, LockMode.WRITE_LOCK)) {
// by ResourceFactory
if (collection == null) {
LOG.debug("Collection {} does not exist", xmldbUri);
txnManager.abort(txn);
throw new CollectionDoesNotExistException(xmldbUri + "");
}
if (LOG.isDebugEnabled()) {
if (mime.isXMLType()) {
LOG.debug("Inserting XML document '{}'", mime.getName());
} else {
LOG.debug("Inserting BINARY document '{}'", mime.getName());
}
}
// Stream into database
try (final FilterInputStreamCache cache = FilterInputStreamCacheFactory.getCacheInstance(() -> (String) broker.getConfiguration().getProperty(Configuration.BINARY_CACHE_CLASS_PROPERTY), is);
final CachingFilterInputStream cfis = new CachingFilterInputStream(cache);
final EXistInputSource eis = new CachingFilterInputStreamInputSource(cfis)) {
broker.storeDocument(txn, newNameUri, eis, mime, collection);
}
// Commit change
txnManager.commit(txn);
if (LOG.isDebugEnabled()) {
LOG.debug("Document created successfully");
}
} catch (EXistException | SAXException e) {
LOG.error(e);
throw new IOException(e);
} catch (LockException e) {
LOG.error(e);
throw new PermissionDeniedException(xmldbUri + "");
} catch (IOException | PermissionDeniedException e) {
LOG.error(e);
throw e;
} finally {
if (LOG.isDebugEnabled()) {
LOG.debug("Finished creation");
}
}
// Send the result back to the client
XmldbURI newResource = xmldbUri.append(newName);
return newResource;
}
use of org.exist.storage.txn.TransactionManager in project exist by eXist-db.
the class DLNStorageTest method tearDown.
@AfterClass
public static void tearDown() throws EXistException, PermissionDeniedException, IOException, TriggerException {
final BrokerPool pool = existEmbeddedServer.getBrokerPool();
final TransactionManager transact = pool.getTransactionManager();
try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()));
final Txn transaction = transact.beginTransaction()) {
final Collection root = broker.getOrCreateCollection(transaction, XmldbURI.create(XmldbURI.ROOT_COLLECTION + TEST_COLLECTION));
assertNotNull(root);
broker.removeCollection(transaction, root);
transact.commit(transaction);
}
}
Aggregations