use of com.evolvedbinary.j8fu.tuple.Tuple2 in project exist by eXist-db.
the class NativeBroker method getOrCreateCollectionExplicit.
/**
* Gets the database Collection identified by the specified path.
* If the Collection does not yet exist, it is created - including all ancestors.
* The Collection is identified by its absolute path, e.g. /db/shakespeare.
* The returned Collection will NOT HAVE a lock.
*
* The caller should take care to release any associated resource by
* calling {@link Collection#close()}
*
* @param transaction The current transaction
* @param path The Collection's URI
* @param creationAttributes the attributes to use if the collection needs to be created, the first item is a Permission (or null for default), the second item is a Creation Date.
*
* @return A tuple whose first boolean value is set to true if the
* collection was created, or false if the collection already existed. The
* second value is the existing or created Collection
*
* @throws PermissionDeniedException If the current user does not have appropriate permissions
* @throws IOException If an error occurs whilst reading (get) or writing (create) a Collection to disk
* @throws TriggerException If a CollectionTrigger throws an exception
*/
private Tuple2<Boolean, Collection> getOrCreateCollectionExplicit(final Txn transaction, final XmldbURI path, final Optional<Tuple2<Permission, Long>> creationAttributes) throws PermissionDeniedException, IOException, TriggerException {
final XmldbURI collectionUri = prepend(path.toCollectionPathURI().normalizeCollectionPath());
final XmldbURI parentCollectionUri = collectionUri.removeLastSegment();
final CollectionCache collectionsCache = pool.getCollectionsCache();
try {
// 1) optimize for the existence of the Collection in the cache
try (final ManagedCollectionLock collectionLock = readLockCollection(collectionUri)) {
final Collection collection = collectionsCache.getIfPresent(collectionUri);
if (collection != null) {
return new Tuple2<>(false, collection);
}
}
// 2) try and read the Collection from disk, if not on disk then create it
try (final ManagedCollectionLock parentCollectionLock = writeLockCollection(parentCollectionUri.numSegments() == 0 ? XmldbURI.ROOT_COLLECTION_URI : parentCollectionUri)) {
// we write lock the parent (as we may need to add a new Collection to it)
// check for preemption between READ -> WRITE lock, is the Collection now in the cache?
final Collection collection = collectionsCache.getIfPresent(collectionUri);
if (collection != null) {
return new Tuple2<>(false, collection);
}
// is the parent Collection in the cache?
if (parentCollectionUri == XmldbURI.EMPTY_URI) {
// no parent... so, this is the root collection!
return getOrCreateCollectionExplicit_rootCollection(transaction, collectionUri, collectionsCache);
} else {
final Collection parentCollection = collectionsCache.getIfPresent(parentCollectionUri);
if (parentCollection != null) {
// parent collection is in cache, is our Collection present on disk?
final Collection loadedCollection = loadCollection(collectionUri);
if (loadedCollection != null) {
// loaded it from disk
// add it to the cache and return it
collectionsCache.put(loadedCollection);
return new Tuple2<>(false, loadedCollection);
} else {
// not on disk, create the collection
return new Tuple2<>(true, createCollection(transaction, parentCollection, collectionUri, collectionsCache, creationAttributes));
}
} else {
/*
* No parent Collection in the cache so that needs to be loaded/created
* (or will be read from cache if we are pre-empted) before we can create this Collection.
* However to do this, we need to yield the collectionLock, so we will continue outside
* the ManagedCollectionLock at (3)
*/
}
}
}
// TODO(AR) below, should we just fall back to recursive descent creating the collection hierarchy in the same manner that getOrCreateCollection used to do?
// 3) No parent collection was previously found in cache so we need to call this function for the parent Collection and then ourselves
final Tuple2<Boolean, Collection> newOrExistingParentCollection = getOrCreateCollectionExplicit(transaction, parentCollectionUri, creationAttributes);
return getOrCreateCollectionExplicit(transaction, collectionUri, creationAttributes);
} catch (final ReadOnlyException e) {
throw new PermissionDeniedException(DATABASE_IS_READ_ONLY);
} catch (final LockException e) {
throw new IOException(e);
}
}
use of com.evolvedbinary.j8fu.tuple.Tuple2 in project exist by eXist-db.
the class FluentBrokerAPITest method all.
@Test
public void all() throws PermissionDeniedException, EXistException, LockException {
final XmldbURI docUri = uri("all-test.xml");
final long collectionCreated = 1234;
final long docLastModified = 5678;
final IMocksControl ctrl = createStrictControl();
ctrl.checkOrder(true);
final BrokerPool mockBrokerPool = ctrl.createMock(BrokerPool.class);
final DBBroker mockBroker = ctrl.createMock(DBBroker.class);
final Collection mockCollection = ctrl.createMock(Collection.class);
final LockedDocument mockLockedDocument = ctrl.createMock(LockedDocument.class);
final DocumentImpl mockDocument = ctrl.createMock(DocumentImpl.class);
expect(mockBrokerPool.getBroker()).andReturn(mockBroker);
expect(mockBroker.openCollection(TEST_COLLECTION_URI, READ_LOCK)).andReturn(mockCollection);
expect(mockCollection.getCreated()).andReturn(collectionCreated);
expect(mockCollection.getDocumentWithLock(mockBroker, docUri, READ_LOCK)).andReturn(mockLockedDocument);
expect(mockLockedDocument.getDocument()).andReturn(mockDocument);
expect(mockCollection.getURI()).andReturn(TEST_COLLECTION_URI);
expect(mockDocument.getFileURI()).andReturn(docUri);
// NOTE: checks that Collection lock is release before Document lock
mockCollection.close();
expect(mockDocument.getLastModified()).andReturn(docLastModified);
mockLockedDocument.close();
mockBroker.close();
ctrl.replay();
final Function<Collection, Long> collectionOp = collection -> collection.getCreated();
final BiFunction<Collection, DocumentImpl, String> collectionDocOp = (collection, doc) -> collection.getURI().append(doc.getFileURI()).toString();
final Function<DocumentImpl, Long> documentOp = document -> document.getLastModified();
final Tuple3<Long, String, Long> result = FluentBrokerAPI.builder(mockBrokerPool).withCollection(TEST_COLLECTION_URI, READ_LOCK).execute(collectionOp).withDocument(collection -> new Tuple2<>(docUri, READ_LOCK)).execute(collectionDocOp).withoutCollection().execute(documentOp).doAll();
assertEquals(collectionCreated, result._1.longValue());
assertEquals(TEST_COLLECTION_URI.append(docUri), result._2);
assertEquals(docLastModified, result._3.longValue());
ctrl.verify();
}
use of com.evolvedbinary.j8fu.tuple.Tuple2 in project exist by eXist-db.
the class FluentBrokerAPITest method collectionAndDocThenDoc.
@Test
public void collectionAndDocThenDoc() throws PermissionDeniedException, EXistException, LockException {
final XmldbURI docUri = uri("all-test.xml");
final long docLastModified = 5678;
final IMocksControl ctrl = createStrictControl();
ctrl.checkOrder(true);
final BrokerPool mockBrokerPool = ctrl.createMock(BrokerPool.class);
final DBBroker mockBroker = ctrl.createMock(DBBroker.class);
final Collection mockCollection = ctrl.createMock(Collection.class);
final LockedDocument mockLockedDocument = ctrl.createMock(LockedDocument.class);
final DocumentImpl mockDocument = ctrl.createMock(DocumentImpl.class);
expect(mockBrokerPool.getBroker()).andReturn(mockBroker);
expect(mockBroker.openCollection(TEST_COLLECTION_URI, READ_LOCK)).andReturn(mockCollection);
expect(mockCollection.getDocumentWithLock(mockBroker, docUri, READ_LOCK)).andReturn(mockLockedDocument);
expect(mockLockedDocument.getDocument()).andReturn(mockDocument);
expect(mockCollection.getURI()).andReturn(TEST_COLLECTION_URI);
expect(mockDocument.getFileURI()).andReturn(docUri);
// NOTE: checks that Collection lock is release before Document lock
mockCollection.close();
expect(mockDocument.getLastModified()).andReturn(docLastModified);
mockLockedDocument.close();
mockBroker.close();
ctrl.replay();
final BiFunction<Collection, DocumentImpl, String> collectionDocOp = (collection, doc) -> collection.getURI().append(doc.getFileURI()).toString();
final Function<DocumentImpl, Long> documentOp = document -> document.getLastModified();
final Tuple2<String, Long> result = FluentBrokerAPI.builder(mockBrokerPool).withCollection(TEST_COLLECTION_URI, READ_LOCK).withDocument(collection -> new Tuple2<>(docUri, READ_LOCK)).execute(collectionDocOp).withoutCollection().execute(documentOp).doAll();
assertEquals(TEST_COLLECTION_URI.append(docUri), result._1);
assertEquals(docLastModified, result._2.longValue());
ctrl.verify();
}
use of com.evolvedbinary.j8fu.tuple.Tuple2 in project exist by eXist-db.
the class FluentBrokerAPITest method collectionAndDocOnly.
@Test
public void collectionAndDocOnly() throws PermissionDeniedException, EXistException, LockException {
final XmldbURI docUri = uri("all-test.xml");
final IMocksControl ctrl = createStrictControl();
ctrl.checkOrder(true);
final BrokerPool mockBrokerPool = ctrl.createMock(BrokerPool.class);
final DBBroker mockBroker = ctrl.createMock(DBBroker.class);
final Collection mockCollection = ctrl.createMock(Collection.class);
final LockedDocument mockLockedDocument = ctrl.createMock(LockedDocument.class);
final DocumentImpl mockDocument = ctrl.createMock(DocumentImpl.class);
final Lock mockDocumentLock = ctrl.createMock(Lock.class);
expect(mockBrokerPool.getBroker()).andReturn(mockBroker);
expect(mockBroker.openCollection(TEST_COLLECTION_URI, READ_LOCK)).andReturn(mockCollection);
expect(mockCollection.getDocumentWithLock(mockBroker, docUri, READ_LOCK)).andReturn(mockLockedDocument);
expect(mockLockedDocument.getDocument()).andReturn(mockDocument);
expect(mockCollection.getURI()).andReturn(TEST_COLLECTION_URI);
expect(mockDocument.getFileURI()).andReturn(docUri);
// NOTE: checks that Collection lock is release before Document lock
mockCollection.close();
mockLockedDocument.close();
mockBroker.close();
ctrl.replay();
final BiFunction<Collection, DocumentImpl, String> collectionDocOp = (collection, doc) -> collection.getURI().append(doc.getFileURI()).toString();
final String result = FluentBrokerAPI.builder(mockBrokerPool).withCollection(TEST_COLLECTION_URI, READ_LOCK).withDocument(collection -> new Tuple2<>(docUri, READ_LOCK)).execute(collectionDocOp).doAll();
assertEquals(TEST_COLLECTION_URI.append(docUri), result);
ctrl.verify();
}
use of com.evolvedbinary.j8fu.tuple.Tuple2 in project exist by eXist-db.
the class FluentBrokerAPITest method docOnly.
@Test
public void docOnly() throws PermissionDeniedException, EXistException, LockException {
final XmldbURI docUri = uri("all-test.xml");
final long docLastModified = 5678;
final IMocksControl ctrl = createStrictControl();
ctrl.checkOrder(true);
final BrokerPool mockBrokerPool = ctrl.createMock(BrokerPool.class);
final DBBroker mockBroker = ctrl.createMock(DBBroker.class);
final Collection mockCollection = ctrl.createMock(Collection.class);
final LockedDocument mockLockedDocument = ctrl.createMock(LockedDocument.class);
final DocumentImpl mockDocument = ctrl.createMock(DocumentImpl.class);
expect(mockBrokerPool.getBroker()).andReturn(mockBroker);
expect(mockBroker.openCollection(TEST_COLLECTION_URI, READ_LOCK)).andReturn(mockCollection);
expect(mockCollection.getDocumentWithLock(mockBroker, docUri, READ_LOCK)).andReturn(mockLockedDocument);
expect(mockLockedDocument.getDocument()).andReturn(mockDocument);
// NOTE: checks that Collection lock is release before Document lock
mockCollection.close();
expect(mockDocument.getLastModified()).andReturn(docLastModified);
mockLockedDocument.close();
mockBroker.close();
ctrl.replay();
final Function<DocumentImpl, Long> documentOp = document -> document.getLastModified();
final long result = FluentBrokerAPI.builder(mockBrokerPool).withCollection(TEST_COLLECTION_URI, READ_LOCK).withDocument(collection -> new Tuple2<>(docUri, READ_LOCK)).withoutCollection().execute(documentOp).doAll();
assertEquals(docLastModified, result);
ctrl.verify();
}
Aggregations