Search in sources :

Example 11 with Lock

use of javax.jcr.lock.Lock in project jackrabbit by apache.

the class Locked method with.

/**
     * Executes the method {@link #run} within the scope of a lock held on
     * <code>lockable</code>.
     *
     * @param lockable the node where the lock is obtained from.
     * @param isDeep   <code>true</code> if <code>lockable</code> will be locked
     *                 deep.
     * @param timeout  time in milliseconds to wait at most to aquire the lock.
     * @return the object returned by {@link #run} or {@link #TIMED_OUT} if the
     *         lock on <code>lockable</code> could not be aquired within the
     *         specified timeout.
     * @throws IllegalArgumentException if <code>timeout</code> is negative or
     *                                  <code>lockable</code> is not
     *                                  <i>mix:lockable</i>.
     * @throws RepositoryException      if {@link #run} throws an exception.
     * @throws UnsupportedRepositoryOperationException
     *                                  if this repository does not support
     *                                  locking.
     * @throws InterruptedException     if this thread is interrupted while
     *                                  waiting for the lock on node
     *                                  <code>lockable</code>.
     */
public Object with(Node lockable, boolean isDeep, long timeout) throws UnsupportedRepositoryOperationException, RepositoryException, InterruptedException {
    if (timeout < 0) {
        throw new IllegalArgumentException("timeout must be >= 0");
    }
    Session session = lockable.getSession();
    NamePathResolver resolver = new DefaultNamePathResolver(session);
    Lock lock;
    EventListener listener = null;
    try {
        // check whether the lockable can be locked at all
        if (!lockable.isNodeType(resolver.getJCRName(NameConstants.MIX_LOCKABLE))) {
            throw new IllegalArgumentException("Node is not lockable");
        }
        lock = tryLock(lockable, isDeep);
        if (lock != null) {
            return runAndUnlock(lock);
        }
        if (timeout == 0) {
            return TIMED_OUT;
        }
        long timelimit;
        if (timeout == Long.MAX_VALUE) {
            timelimit = Long.MAX_VALUE;
        } else {
            timelimit = System.currentTimeMillis() + timeout;
        }
        // node is locked by other session -> register event listener if possible
        if (isObservationSupported(session)) {
            ObservationManager om = session.getWorkspace().getObservationManager();
            listener = new EventListener() {

                public void onEvent(EventIterator events) {
                    synchronized (this) {
                        this.notify();
                    }
                }
            };
            om.addEventListener(listener, Event.PROPERTY_REMOVED, lockable.getPath(), false, null, null, true);
        }
        // the current thread when the lockable node is possibly unlocked
        for (; ; ) {
            synchronized (this) {
                lock = tryLock(lockable, isDeep);
                if (lock != null) {
                    return runAndUnlock(lock);
                } else {
                    // check timeout
                    if (System.currentTimeMillis() > timelimit) {
                        return TIMED_OUT;
                    }
                    if (listener != null) {
                        // event listener *should* wake us up, however
                        // there is a chance that removal of the lockOwner
                        // property is notified before the node is acutally
                        // unlocked. therefore we use a safety net to wait
                        // at most 1000 millis.
                        this.wait(Math.min(1000, timeout));
                    } else {
                        // repository does not support observation
                        // wait at most 50 millis then retry
                        this.wait(Math.min(50, timeout));
                    }
                }
            }
        }
    } catch (NameException e) {
        throw new RepositoryException(e);
    } finally {
        if (listener != null) {
            session.getWorkspace().getObservationManager().removeEventListener(listener);
        }
    }
}
Also used : NamePathResolver(org.apache.jackrabbit.spi.commons.conversion.NamePathResolver) DefaultNamePathResolver(org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver) NameException(org.apache.jackrabbit.spi.commons.conversion.NameException) DefaultNamePathResolver(org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver) ObservationManager(javax.jcr.observation.ObservationManager) RepositoryException(javax.jcr.RepositoryException) EventListener(javax.jcr.observation.EventListener) EventIterator(javax.jcr.observation.EventIterator) Session(javax.jcr.Session) Lock(javax.jcr.lock.Lock)

Example 12 with Lock

use of javax.jcr.lock.Lock in project jackrabbit by apache.

the class ConcurrentLockingWithTransactionsTest method testConcurrentCreateAndLockUnLockInTransaction.

public void testConcurrentCreateAndLockUnLockInTransaction() throws RepositoryException {
    runTask(new Task() {

        public void execute(Session session, Node test) throws RepositoryException {
            // add versionable nodes
            for (int i = 0; i < NUM_OPERATIONS / CONCURRENCY; i++) {
                try {
                    final UserTransaction utx = new UserTransactionImpl(test.getSession());
                    utx.begin();
                    Node n = test.addNode("test" + i);
                    n.addMixin(mixLockable);
                    session.save();
                    Lock l = n.lock(false, true);
                    n.unlock();
                    utx.commit();
                } catch (Exception e) {
                    final String threadName = Thread.currentThread().getName();
                    final Throwable deepCause = getLevel2Cause(e);
                    if (deepCause != null && deepCause instanceof StaleItemStateException) {
                    // ignore
                    } else {
                        throw new RepositoryException(threadName + ", i=" + i + ":" + e.getClass().getName(), e);
                    }
                }
            }
        }
    }, CONCURRENCY);
}
Also used : UserTransaction(javax.transaction.UserTransaction) StaleItemStateException(org.apache.jackrabbit.core.state.StaleItemStateException) Node(javax.jcr.Node) UserTransactionImpl(org.apache.jackrabbit.core.UserTransactionImpl) RepositoryException(javax.jcr.RepositoryException) RepositoryException(javax.jcr.RepositoryException) StaleItemStateException(org.apache.jackrabbit.core.state.StaleItemStateException) Session(javax.jcr.Session) Lock(javax.jcr.lock.Lock)

Example 13 with Lock

use of javax.jcr.lock.Lock in project jackrabbit by apache.

the class LockTimeoutTest method testExpired.

private void testExpired(boolean xa) throws Exception {
    Session s = testRootNode.getSession();
    Node n = testRootNode.addNode(nodeName1);
    n.addMixin(mixLockable);
    s.save();
    UserTransaction utx = null;
    if (xa) {
        utx = new UserTransactionImpl(s);
        utx.begin();
    }
    javax.jcr.lock.LockManager lm = s.getWorkspace().getLockManager();
    boolean isDeep;
    boolean isSessionScoped;
    long timeoutHint;
    String ownerInfo;
    isDeep = false;
    isSessionScoped = false;
    timeoutHint = 1;
    ownerInfo = "";
    Session s2 = getHelper().getSuperuserSession();
    Lock l = lm.lock(n.getPath(), isDeep, isSessionScoped, timeoutHint, ownerInfo);
    // this works only for timeout = 1,
    // as getSecondsRemaining always returns a positive value
    assertEquals(timeoutHint, l.getSecondsRemaining());
    assertTrue(l.isLive());
    if (xa) {
        utx.commit();
    }
    long start = System.currentTimeMillis();
    while (true) {
        Thread.sleep(100);
        long now = System.currentTimeMillis();
        boolean success;
        try {
            s2.getNode(n.getPath()).setProperty("x", 1);
            s2.save();
            success = true;
        } catch (Exception e) {
            success = false;
        }
        long t = now - start;
        if (t > timeoutHint + 3000) {
            assertTrue(success);
            break;
        } else if (t < timeoutHint) {
            assertFalse(success);
        }
    }
    n.remove();
    s.save();
}
Also used : UserTransaction(javax.transaction.UserTransaction) Node(javax.jcr.Node) UserTransactionImpl(org.apache.jackrabbit.core.UserTransactionImpl) Session(javax.jcr.Session) Lock(javax.jcr.lock.Lock)

Example 14 with Lock

use of javax.jcr.lock.Lock in project jackrabbit by apache.

the class XATest method testCreateLockUnlockInDifferentTransactions.

/**
     * Test locking and unlocking behavior in transaction
     * (see JCR-2356)
     * @throws Exception
     */
public void testCreateLockUnlockInDifferentTransactions() throws Exception {
    // create new node and lock it
    UserTransaction utx = new UserTransactionImpl(superuser);
    utx.begin();
    // add node that is both lockable and referenceable, save
    Node rootNode = superuser.getRootNode();
    Node n = rootNode.addNode(nodeName1);
    n.addMixin(mixLockable);
    n.addMixin(mixReferenceable);
    rootNode.save();
    String uuid = n.getUUID();
    // commit
    utx.commit();
    // start new Transaction and try to add lock token
    utx = new UserTransactionImpl(superuser);
    utx.begin();
    n = superuser.getNodeByUUID(uuid);
    // lock this new node
    Lock lock = n.lock(true, false);
    // verify node is locked
    assertTrue("Node not locked", n.isLocked());
    String lockToken = lock.getLockToken();
    // assert: session must get a non-null lock token
    assertNotNull("session must get a non-null lock token", lockToken);
    // assert: session must hold lock token
    assertTrue("session must hold lock token", containsLockToken(superuser, lockToken));
    n.save();
    superuser.removeLockToken(lockToken);
    String nlt = lock.getLockToken();
    assertTrue("freshly obtained lock token must either be null or the same as the one returned earlier", nlt == null || nlt.equals(lockToken));
    assertFalse("session must not hold lock token", containsLockToken(superuser, lockToken));
    // commit
    utx.commit();
    nlt = lock.getLockToken();
    assertTrue("freshly obtained lock token must either be null or the same as the one returned earlier", nlt == null || nlt.equals(lockToken));
    assertFalse("session must not hold lock token", containsLockToken(superuser, lockToken));
    // start new Transaction and try to unlock
    utx = new UserTransactionImpl(superuser);
    utx.begin();
    n = superuser.getNodeByUUID(uuid);
    // verify node is locked
    assertTrue("Node not locked", n.isLocked());
    // assert: session must not hold lock token
    assertFalse("session must not hold lock token", containsLockToken(superuser, lockToken));
    superuser.addLockToken(lockToken);
    // assert: session must not hold lock token
    assertTrue("session must hold lock token", containsLockToken(superuser, lockToken));
    n.unlock();
    // commit
    utx.commit();
}
Also used : UserTransaction(javax.transaction.UserTransaction) Node(javax.jcr.Node) Lock(javax.jcr.lock.Lock)

Example 15 with Lock

use of javax.jcr.lock.Lock in project jackrabbit by apache.

the class AbstractLockManagementTest method testLockBreaking.

public void testLockBreaking() throws RepositoryException, NotExecutableException {
    String locktoken = null;
    LockManager sulm = superuser.getWorkspace().getLockManager();
    String lockedpath = null;
    try {
        Node trn = getTestNode();
        modifyPrivileges(trn.getPath(), Privilege.JCR_READ, true);
        modifyPrivileges(trn.getPath(), PrivilegeRegistry.REP_WRITE, true);
        modifyPrivileges(trn.getPath(), Privilege.JCR_LOCK_MANAGEMENT, true);
        Session lockingSession = trn.getSession();
        assertFalse("super user and test user should have different user ids: " + lockingSession.getUserID() + " vs " + superuser.getUserID(), lockingSession.getUserID().equals(superuser.getUserID()));
        trn.addNode("locktest", "nt:unstructured");
        trn.addMixin("mix:lockable");
        lockingSession.save();
        // let the "other" user lock the node
        LockManager oulm = lockingSession.getWorkspace().getLockManager();
        Lock l = oulm.lock(trn.getPath(), true, false, Long.MAX_VALUE, null);
        lockedpath = trn.getPath();
        locktoken = l.getLockToken();
        lockingSession.logout();
        // transfer the lock token to the super user and try the unlock
        Node lockednode = superuser.getNode(lockedpath);
        assertTrue(lockednode.isLocked());
        Lock sl = sulm.getLock(lockedpath);
        assertNotNull(sl.getLockToken());
        sulm.addLockToken(sl.getLockToken());
        sulm.unlock(lockedpath);
        locktoken = null;
    } finally {
        if (locktoken != null && lockedpath != null) {
            sulm.addLockToken(locktoken);
            sulm.unlock(lockedpath);
        }
    }
}
Also used : LockManager(javax.jcr.lock.LockManager) Node(javax.jcr.Node) Session(javax.jcr.Session) Lock(javax.jcr.lock.Lock)

Aggregations

Lock (javax.jcr.lock.Lock)67 Node (javax.jcr.Node)41 Session (javax.jcr.Session)20 LockException (javax.jcr.lock.LockException)13 UserTransaction (javax.transaction.UserTransaction)12 RepositoryException (javax.jcr.RepositoryException)8 LockManager (javax.jcr.lock.LockManager)7 JcrActiveLock (org.apache.jackrabbit.webdav.jcr.lock.JcrActiveLock)5 ActiveLock (org.apache.jackrabbit.webdav.lock.ActiveLock)4 UserTransactionImpl (org.apache.jackrabbit.core.UserTransactionImpl)3 DavException (org.apache.jackrabbit.webdav.DavException)3 EventIterator (javax.jcr.observation.EventIterator)2 EventListener (javax.jcr.observation.EventListener)2 ObservationManager (javax.jcr.observation.ObservationManager)2 StaleItemStateException (org.apache.jackrabbit.core.state.StaleItemStateException)2 LockInfo (org.apache.jackrabbit.spi.LockInfo)2 SupportedLock (org.apache.jackrabbit.webdav.lock.SupportedLock)2 FileInputStream (java.io.FileInputStream)1 IOException (java.io.IOException)1 URI (java.net.URI)1