/** A LockException is thrown if a lock prevents the copy. */ public void testMoveNodesLocked() throws RepositoryException { // we assume repository supports locking String dstAbsPath = node2.getPath() + "/" + node1.getName(); // get other session Session otherSession = helper.getReadWriteSession(); try { // get lock target node in destination wsp through other session Node lockTarget = (Node) otherSession.getItem(node2.getPath()); // add mixin "lockable" to be able to lock the node if (!lockTarget.getPrimaryNodeType().isNodeType(mixLockable)) { lockTarget.addMixin(mixLockable); lockTarget.getParent().save(); } // lock dst parent node using other session lockTarget.lock(true, true); try { workspace.move(node1.getPath(), dstAbsPath); fail("LockException was expected."); } catch (LockException e) { // successful } finally { lockTarget.unlock(); } } finally { otherSession.logout(); } }
@Override public void execute(Context ctx) throws RepositoryException { Node node = (Node) ctx.get("node"); if (node.canAddMixin("mix:lockable")) node.addMixin("mix:lockable"); node.getSession().save(); node.lock(true, true); // node.getSession().save(); }
/** * This will use the give node (which must be lockable) as a container for a unique id. The id * will be stored in a property. Before accessing it, the node will be locked or it will wait for * taking the lock. After a successful lock, it will return the latest id + 1, this will also be * stored as the new value in the property of the node. */ private long atomicLockNodeAndGetNextID(Session session, Node node, String jcrPath) throws IDException { // we need to synchronize the access to the node which holds the // unique id; thus we lock it before reading and modifying it; if // locking is not possible because the node is locked, // loop until node.lock() was successful while (true) { try { // the lock must be session scoped (2nd arg == true) so that it // does not persist if something fails before we manually // unlock it (eg. JVM crash or fatal RepositoryException) node.lock(false, true); break; } catch (LockException e) { try { Thread.sleep(LOCK_SLEEP_MILLIS); } catch (InterruptedException e1) { // just ignore and go to the beginning of the loop } } catch (RepositoryException e) { // forward any exception throw new IDException("Cannot lock unique id node for " + jcrPath, e); } } // the node is now locked long resultID; try { // atomic increment access due to lock Property idProp = node.getProperty(ID_PROPERTY); resultID = idProp.getLong(); resultID++; idProp.setValue(resultID); // persist id value changes node.save(); } catch (RepositoryException e) { // forward any exception throw new IDException("Cannot modify unique id for " + jcrPath, e); } finally { // ensure the lock is removed try { node.unlock(); } catch (RepositoryException e) { // forward any exception throw new IDException("Cannot unlock unique id node for " + jcrPath, e); } } return resultID; }