use of org.exist.xmldb.XmldbURI in project exist by eXist-db.
the class EnsureLockingAspect method enforceEnsureUnlockedContainer.
/**
* Ensures that the no locks are held on the container
* object which houses the method before the method is called.
* @param joinPoint the join point of the aspect
* @param container the object containing the instrumented method
*
* @throws LockException if any locks are held and
* the System property `exist.ensurelocking.enforce=true` is set.
*/
@Before("methodWithEnsureContainerUnlocked() && target(container)")
public void enforceEnsureUnlockedContainer(final JoinPoint joinPoint, final Object container) throws LockException {
if (DISABLED) {
return;
}
final MethodSignature ms = (MethodSignature) joinPoint.getSignature();
final Method method = ms.getMethod();
final AnnotatedMethodConstraint<EnsureContainerUnlocked> ensureContainerUnlockedConstraint = getMethodAnnotation(method, EnsureContainerUnlocked.class);
final Lock.LockType lockType = resolveContainerLockDetail(ensureContainerUnlockedConstraint);
traceln(() -> "Checking: " + toAnnotationString(EnsureContainerUnlocked.class, lockType) + " method=" + ms.getDeclaringType().getName() + "#" + ms.getName() + " ...");
// check the lock constraint holds
boolean failed = false;
final LockManager lockManager = getLockManager();
if (lockManager != null) {
switch(lockType) {
case COLLECTION:
final XmldbURI collectionUri;
if (Collection.class.isAssignableFrom(container.getClass())) {
collectionUri = ((Collection) container).getURI();
} else {
throw new IllegalArgumentException("Container type was identified as Collection, but the container is not an implementation of Collection");
}
if (!hasNoCollectionLocks(lockManager, collectionUri)) {
report("FAILED: Constraint to require no locks on Collection: " + collectionUri);
failed = true;
}
break;
case DOCUMENT:
final XmldbURI documentUri;
if (DocumentImpl.class.isAssignableFrom(container.getClass())) {
documentUri = ((DocumentImpl) container).getURI();
} else {
throw new IllegalArgumentException("Container type was identified as Document, but the container is not an implementation of DocumentImpl");
}
if (!hasNoDocumentLocks(lockManager, documentUri)) {
report("FAILED: Constraint to require no locks on Document: " + documentUri + " FAILED");
failed = true;
}
break;
default:
throw new UnsupportedOperationException("Currently only Collection or Document container locks are supported");
}
}
if (!failed) {
traceln(() -> "PASSED.");
}
}
use of org.exist.xmldb.XmldbURI in project exist by eXist-db.
the class EnsureLockingAspect method enforceEnsureLockedParameters.
/**
* Ensures that the parameters to a method
* annotated by {@link EnsureLocked} hold
* the indicated locks.
*
* @param joinPoint the join point of the aspect
*
* @throws LockException if the appropriate locks are not held and
* the System property `exist.ensurelocking.enforce=true` is set.
*/
@Before("methodWithEnsureLockedParameters()")
public void enforceEnsureLockedParameters(final JoinPoint joinPoint) throws LockException {
if (DISABLED) {
return;
}
final MethodSignature ms = (MethodSignature) joinPoint.getSignature();
final Method method = ms.getMethod();
final Object[] args = joinPoint.getArgs();
final List<AnnotatedParameterConstraint<EnsureLocked>> ensureLockedParameters = getAllParameterAnnotations(method, EnsureLocked.class);
for (final AnnotatedParameterConstraint<EnsureLocked> ensureLockedConstraint : ensureLockedParameters) {
// check the lock constraint holds
final LockManager lockManager = getLockManager();
boolean failed = false;
if (lockManager != null) {
final int idx = ensureLockedConstraint.getParameterIndex();
final Object arg = args[idx];
// if the argument is null, and annotated @Nullable, we can skip the check
if (arg == null && !getAllParameterAnnotations(method, Nullable.class).isEmpty()) {
traceln(() -> "Skipping method=" + ms.getDeclaringType().getName() + "#" + ms.getName() + " for null argument(idx=" + idx + ") with @EnsureLocked @Nullable");
continue;
}
final EnsureLockDetail ensureLockDetail = resolveLockDetail(ensureLockedConstraint, args);
traceln(() -> "Checking: method=" + ms.getDeclaringType().getName() + "#" + ms.getName() + "( " + toAnnotationString(EnsureLocked.class, ensureLockDetail) + " " + ensureLockedConstraint.getParameter().getName() + ") ...");
switch(ensureLockDetail.type) {
case COLLECTION:
final XmldbURI collectionUri;
if (XmldbURI.class.isAssignableFrom(arg.getClass())) {
collectionUri = (XmldbURI) arg;
} else {
collectionUri = ((Collection) arg).getURI();
}
if (!hasCollectionLock(lockManager, collectionUri, ensureLockDetail)) {
report("FAILED: Constraint to require lock mode " + ensureLockDetail.mode + " on Collection: " + collectionUri + " FAILED");
failed = true;
}
break;
case DOCUMENT:
final XmldbURI documentUri;
if (XmldbURI.class.isAssignableFrom(arg.getClass())) {
documentUri = (XmldbURI) arg;
} else {
documentUri = ((DocumentImpl) arg).getURI();
}
if (!hasDocumentLock(lockManager, documentUri, ensureLockDetail)) {
report("FAILED: Constraint to require lock mode " + ensureLockDetail.mode + " on Document: " + documentUri + " FAILED");
failed = true;
}
break;
default:
throw new UnsupportedOperationException("Currently only Collection or Document locks are supported");
}
}
if (!failed) {
traceln(() -> "PASSED.");
}
}
}
use of org.exist.xmldb.XmldbURI in project exist by eXist-db.
the class EnsureLockingAspect method enforceEnsureUnlockedReturnType.
/**
* Ensures that the object returned by a method
* has no lock held upon it before it is returned.
* @param joinPoint the join point of the aspect
* @param result the result of the instrumented method
* @throws LockException if any locks are held and
* the System property `exist.ensurelocking.enforce=true` is set.
*/
@AfterReturning(value = "methodWithEnsureUnlockedReturnType()", returning = "result")
public void enforceEnsureUnlockedReturnType(final JoinPoint joinPoint, final Object result) throws Throwable {
if (DISABLED) {
return;
}
final MethodSignature ms = (MethodSignature) joinPoint.getSignature();
final Method method = ms.getMethod();
final AnnotatedMethodConstraint<EnsureUnlocked> ensureUnlockedConstraint = getMethodAnnotation(method, EnsureUnlocked.class);
final Lock.LockType lockType = resolveLockDetail(ensureUnlockedConstraint);
traceln(() -> "Checking: " + toAnnotationString(EnsureUnlocked.class, lockType) + " method=" + ms.getDeclaringType().getName() + "#" + ms.getName() + " ...");
// check the lock constraint holds
boolean failed = false;
if (result != null) {
final LockManager lockManager = getLockManager();
if (lockManager != null) {
switch(lockType) {
case COLLECTION:
final XmldbURI collectionUri;
if (XmldbURI.class.isAssignableFrom(result.getClass())) {
collectionUri = (XmldbURI) result;
} else {
collectionUri = ((Collection) result).getURI();
}
if (!hasNoCollectionLocks(lockManager, collectionUri)) {
report("FAILED: Constraint to require no locks on Collection: " + collectionUri + " FAILED");
failed = true;
}
break;
case DOCUMENT:
final XmldbURI documentUri;
if (XmldbURI.class.isAssignableFrom(result.getClass())) {
documentUri = (XmldbURI) result;
} else {
documentUri = ((DocumentImpl) result).getURI();
}
if (!hasNoDocumentLocks(lockManager, documentUri)) {
report("FAILED: Constraint to require no locks on Document: " + documentUri + " FAILED");
failed = true;
}
break;
default:
throw new UnsupportedOperationException("Currently only Collection or Document locks are supported");
}
}
} else {
traceln(() -> "Unable to check return type as value is null!");
}
if (!failed) {
traceln(() -> "PASSED.");
}
}
use of org.exist.xmldb.XmldbURI in project exist by eXist-db.
the class Serializer method setStylesheet.
/**
* Plug an XSL stylesheet into the processing pipeline.
* All output will be passed to this stylesheet.
*
* @param doc the document
* @param stylesheet the stylesheet
*
* @throws TransformerConfigurationException if the stylesheet cannot be set
*/
public void setStylesheet(Document doc, String stylesheet) throws TransformerConfigurationException {
if (stylesheet == null) {
templates = null;
return;
}
final long start = System.currentTimeMillis();
xslHandler = null;
XmldbURI stylesheetUri = null;
URI externalUri = null;
try {
stylesheetUri = XmldbURI.xmldbUriFor(stylesheet);
if (!stylesheetUri.toCollectionPathURI().equals(stylesheetUri)) {
externalUri = stylesheetUri.getXmldbURI();
}
} catch (final URISyntaxException e) {
// could be an external URI!
try {
externalUri = new URI(stylesheet);
} catch (final URISyntaxException ee) {
throw new IllegalArgumentException("Stylesheet URI could not be parsed: " + ee.getMessage());
}
}
// does stylesheet point to an external resource?
if (externalUri != null) {
final StreamSource source = new StreamSource(externalUri.toString());
this.templates = factory.get().newTemplates(source);
// read stylesheet from the database
} else {
// current collection and normalize
if (doc != null && doc instanceof DocumentImpl) {
stylesheetUri = ((DocumentImpl) doc).getCollection().getURI().resolveCollectionPath(stylesheetUri).normalizeCollectionPath();
}
// load stylesheet from eXist
DocumentImpl xsl = null;
try {
xsl = broker.getResource(stylesheetUri, Permission.READ);
} catch (final PermissionDeniedException e) {
throw new TransformerConfigurationException("permission denied to read " + stylesheetUri);
}
if (xsl == null) {
throw new TransformerConfigurationException("stylesheet not found: " + stylesheetUri);
}
// TODO: use xmldbURI
if (xsl.getCollection() != null) {
factory.get().setURIResolver(new InternalURIResolver(xsl.getCollection().getURI().toString()));
}
// save handlers
Receiver oldReceiver = receiver;
// compile stylesheet
factory.get().setErrorListener(new ErrorListener());
final TemplatesHandler handler = factory.get().newTemplatesHandler();
receiver = new ReceiverToSAX(handler);
try {
this.serializeToReceiver(xsl, true);
templates = handler.getTemplates();
} catch (final SAXException e) {
throw new TransformerConfigurationException(e.getMessage(), e);
}
// restore handlers
receiver = oldReceiver;
factory.get().setURIResolver(null);
}
LOG.debug("compiling stylesheet took {}", System.currentTimeMillis() - start);
if (templates != null) {
xslHandler = factory.get().newTransformerHandler(templates);
try {
xslHandler.startDocument();
documentStarted = true;
} catch (final SAXException e) {
throw new TransformerConfigurationException(e.getMessage(), e);
}
}
// xslHandler.getTransformer().setOutputProperties(outputProperties);
checkStylesheetParams();
}
use of org.exist.xmldb.XmldbURI in project exist by eXist-db.
the class LockManager method acquireDocumentWriteLock.
/**
* Acquire a WRITE_LOCK on a Document
*
* @param documentPath The URI of the Document within the database
*
* @return the lock for the Document
*
* @throws LockException if the lock could not be acquired
*/
public ManagedDocumentLock acquireDocumentWriteLock(final XmldbURI documentPath) throws LockException {
if (usePathLocksForDocuments) {
final LockGroup lockGroup = acquirePathWriteLock(LockType.DOCUMENT, documentPath, false);
return new ManagedDocumentLock(documentPath, Arrays.stream(lockGroup.locks).map(Tuple3::get_1).toArray(MultiLock[]::new), () -> unlockAll(lockGroup.locks, l -> lockTable.released(lockGroup.groupId, l._3, LockType.DOCUMENT, l._2)));
} else {
final long groupId = System.nanoTime();
final String path = documentPath.toString();
final MultiLock lock = getDocumentLock(path);
lockTable.attempt(groupId, path, LockType.DOCUMENT, Lock.LockMode.WRITE_LOCK);
if (lock(lock, Lock.LockMode.WRITE_LOCK)) {
lockTable.acquired(groupId, path, LockType.DOCUMENT, Lock.LockMode.WRITE_LOCK);
} else {
lockTable.attemptFailed(groupId, path, LockType.DOCUMENT, Lock.LockMode.WRITE_LOCK);
throw new LockException("Unable to acquire WRITE_LOCK for: " + path);
}
return new ManagedDocumentLock(documentPath, lock, () -> {
lock.asWriteLock().unlock();
lockTable.released(groupId, path, LockType.DOCUMENT, Lock.LockMode.WRITE_LOCK);
});
}
}
Aggregations