Search in sources :

Example 96 with XmldbURI

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.");
    }
}
Also used : MethodSignature(org.aspectj.lang.reflect.MethodSignature) Method(java.lang.reflect.Method) XmldbURI(org.exist.xmldb.XmldbURI)

Example 97 with XmldbURI

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.");
        }
    }
}
Also used : MethodSignature(org.aspectj.lang.reflect.MethodSignature) Method(java.lang.reflect.Method) JoinPoint(org.aspectj.lang.JoinPoint) Nullable(javax.annotation.Nullable) XmldbURI(org.exist.xmldb.XmldbURI)

Example 98 with XmldbURI

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.");
    }
}
Also used : MethodSignature(org.aspectj.lang.reflect.MethodSignature) Method(java.lang.reflect.Method) XmldbURI(org.exist.xmldb.XmldbURI)

Example 99 with XmldbURI

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();
}
Also used : TransformerConfigurationException(javax.xml.transform.TransformerConfigurationException) ReceiverToSAX(org.exist.util.serializer.ReceiverToSAX) StreamSource(javax.xml.transform.stream.StreamSource) Receiver(org.exist.util.serializer.Receiver) TemplatesHandler(javax.xml.transform.sax.TemplatesHandler) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) XmldbURI(org.exist.xmldb.XmldbURI) DocumentImpl(org.exist.dom.persistent.DocumentImpl) SAXException(org.xml.sax.SAXException) PermissionDeniedException(org.exist.security.PermissionDeniedException) XmldbURI(org.exist.xmldb.XmldbURI)

Example 100 with XmldbURI

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);
        });
    }
}
Also used : Tuple3(com.evolvedbinary.j8fu.tuple.Tuple3) Consumer(java.util.function.Consumer) Arrays(java.util.Arrays) Logger(org.apache.logging.log4j.Logger) ReentrantLock(java.util.concurrent.locks.ReentrantLock) WeakLazyStripes(org.exist.util.WeakLazyStripes) LockException(org.exist.util.LockException) XmldbURI(org.exist.xmldb.XmldbURI) LockType(org.exist.storage.lock.Lock.LockType) Configuration(org.exist.util.Configuration) MultiLock(uk.ac.ic.doc.slurp.multilock.MultiLock) LogManager(org.apache.logging.log4j.LogManager) LockException(org.exist.util.LockException) Tuple3(com.evolvedbinary.j8fu.tuple.Tuple3) MultiLock(uk.ac.ic.doc.slurp.multilock.MultiLock)

Aggregations

XmldbURI (org.exist.xmldb.XmldbURI)260 Collection (org.exist.collections.Collection)100 PermissionDeniedException (org.exist.security.PermissionDeniedException)69 Test (org.junit.Test)56 Txn (org.exist.storage.txn.Txn)55 EXistException (org.exist.EXistException)42 URISyntaxException (java.net.URISyntaxException)39 LockedDocument (org.exist.dom.persistent.LockedDocument)39 IOException (java.io.IOException)38 DBBroker (org.exist.storage.DBBroker)38 DocumentImpl (org.exist.dom.persistent.DocumentImpl)34 SAXException (org.xml.sax.SAXException)33 Permission (org.exist.security.Permission)30 LockException (org.exist.util.LockException)27 Path (java.nio.file.Path)22 XPathException (org.exist.xquery.XPathException)22 BrokerPool (org.exist.storage.BrokerPool)21 TransactionManager (org.exist.storage.txn.TransactionManager)20 Subject (org.exist.security.Subject)19 StringInputSource (org.exist.util.StringInputSource)17