Class Locked

  • Direct Known Subclasses:
    LockedWrapper

    public abstract class Locked
    extends java.lang.Object
    Locked is a utility to synchronize modifications on a lockable node. The modification is applied while the lock on the node is held, thus ensuring that the modification will never fail with an InvalidItemStateException. This utility can be used with any JCR Repository, not just Jackrabbit.

    The following example shows how this utility can be used to implement a persistent counter:

     Node counter = ...;
     long nextValue = ((Long) new Locked() {
         protected Object run(Node counter) throws RepositoryException {
             Property seqProp = counter.getProperty("value");
             long value = seqProp.getLong();
             seqProp.setValue(++value);
             seqProp.save();
             return new Long(value);
         }
     }.with(counter, false)).longValue();
     
    If you specify a timeout you need to check the return value whether the run method could be executed within the timeout period:
     Node counter = ...;
     Object ret = new Locked() {
         protected Object run(Node counter) throws RepositoryException {
             Property seqProp = counter.getProperty("value");
             long value = seqProp.getLong();
             seqProp.setValue(++value);
             seqProp.save();
             return new Long(value);
         }
     }.with(counter, false);
     if (ret == Locked.TIMED_OUT) {
         // do whatever you think is appropriate in this case
     } else {
         // get the value
         long nextValue = ((Long) ret).longValue();
     }
     
    • Field Summary

      Fields 
      Modifier and Type Field Description
      static java.lang.Object TIMED_OUT
      Object returned when timeout is reached without being able to call run(javax.jcr.Node) while holding the lock.
    • Constructor Summary

      Constructors 
      Constructor Description
      Locked()  
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      java.lang.Object with​(Node lockable, boolean isDeep)
      Executes run(javax.jcr.Node) while the lock on lockable is held.
      java.lang.Object with​(Node lockable, boolean isDeep, boolean isSessionScoped)
      Executes run(javax.jcr.Node) while the lock on lockable is held.
      java.lang.Object with​(Node lockable, boolean isDeep, long timeout)
      Executes the method run(javax.jcr.Node) within the scope of a lock held on lockable.
      java.lang.Object with​(Node lockable, boolean isDeep, long timeout, boolean isSessionScoped)
      Executes the method run(javax.jcr.Node) within the scope of a lock held on lockable.
      • Methods inherited from class java.lang.Object

        equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • TIMED_OUT

        public static final java.lang.Object TIMED_OUT
        Object returned when timeout is reached without being able to call run(javax.jcr.Node) while holding the lock.
    • Constructor Detail

      • Locked

        public Locked()
    • Method Detail

      • with

        public java.lang.Object with​(Node lockable,
                                     boolean isDeep)
                              throws RepositoryException,
                                     java.lang.InterruptedException
        Executes run(javax.jcr.Node) while the lock on lockable is held. This method will block until run(javax.jcr.Node) is executed while holding the lock on node lockable.
        Parameters:
        lockable - a lockable node.
        isDeep - true if lockable will be locked deep.
        Returns:
        the object returned by run(javax.jcr.Node).
        Throws:
        java.lang.IllegalArgumentException - if lockable is not mix:lockable.
        RepositoryException - if run(javax.jcr.Node) throws an exception.
        java.lang.InterruptedException - if this thread is interrupted while waiting for the lock on node lockable.
      • with

        public java.lang.Object with​(Node lockable,
                                     boolean isDeep,
                                     boolean isSessionScoped)
                              throws RepositoryException,
                                     java.lang.InterruptedException
        Executes run(javax.jcr.Node) while the lock on lockable is held. This method will block until run(javax.jcr.Node) is executed while holding the lock on node lockable.
        Parameters:
        lockable - a lockable node.
        isDeep - true if lockable will be locked deep.
        isSessionScoped - true if the lock is session scoped.
        Returns:
        the object returned by run(javax.jcr.Node).
        Throws:
        java.lang.IllegalArgumentException - if lockable is not mix:lockable.
        RepositoryException - if run(javax.jcr.Node) throws an exception.
        java.lang.InterruptedException - if this thread is interrupted while waiting for the lock on node lockable.
      • with

        public java.lang.Object with​(Node lockable,
                                     boolean isDeep,
                                     long timeout)
                              throws UnsupportedRepositoryOperationException,
                                     RepositoryException,
                                     java.lang.InterruptedException
        Executes the method run(javax.jcr.Node) within the scope of a lock held on lockable.
        Parameters:
        lockable - the node where the lock is obtained from.
        isDeep - true if lockable will be locked deep.
        timeout - time in milliseconds to wait at most to acquire the lock.
        Returns:
        the object returned by run(javax.jcr.Node) or TIMED_OUT if the lock on lockable could not be acquired within the specified timeout.
        Throws:
        java.lang.IllegalArgumentException - if timeout is negative or lockable is not mix:lockable.
        RepositoryException - if run(javax.jcr.Node) throws an exception.
        UnsupportedRepositoryOperationException - if this repository does not support locking.
        java.lang.InterruptedException - if this thread is interrupted while waiting for the lock on node lockable.
      • with

        public java.lang.Object with​(Node lockable,
                                     boolean isDeep,
                                     long timeout,
                                     boolean isSessionScoped)
                              throws UnsupportedRepositoryOperationException,
                                     RepositoryException,
                                     java.lang.InterruptedException
        Executes the method run(javax.jcr.Node) within the scope of a lock held on lockable.
        Parameters:
        lockable - the node where the lock is obtained from.
        isDeep - true if lockable will be locked deep.
        timeout - time in milliseconds to wait at most to acquire the lock.
        isSessionScoped - true if the lock is session scoped.
        Returns:
        the object returned by run(javax.jcr.Node) or TIMED_OUT if the lock on lockable could not be acquired within the specified timeout.
        Throws:
        java.lang.IllegalArgumentException - if timeout is negative or lockable is not mix:lockable.
        RepositoryException - if run(javax.jcr.Node) throws an exception.
        UnsupportedRepositoryOperationException - if this repository does not support locking.
        java.lang.InterruptedException - if this thread is interrupted while waiting for the lock on node lockable.