The concept of locking relates to locking a content node for exclusive modification, meaning only one user can modify a locked node. It is analogous to the locking semantics provided by most software versioning systems (except for subversion, of course, which strictly follows a non-locking model). Locking is an optional feature in the JCR and whether the repository implementation at hand supports this feature can be determined via the following call: Repository.getDescriptor( “OPTION_LOCKING_SUPPORTED”).

It is important to point out at this point that locking is not identical to check-in/check-out. The check-in/check-out semantics are a feature of versioning and are enabled by adding the mixin mix:versionable to the node type definition. A checked out node, however, is not locked and can be modified by another user.

To add locking support to a node, the mixin mix:lockable needs to be added to the node type definition. A node can then be locked via the Node.lock() method, and unlocked via the Node.unlock() method. Via a parameter of the lock() method, the locking operation can be defined to be deep or shallow – a shallow lock applies only to the node the lock operation is called on. A deep lock applies to all child node of the node also, in disregard of whether the child nodes are lockable or note. Deep locks are, for example, desired when the child nodes are owned by the parent node, i.e. a composition relationship.

The API provides two methods to determine whether nodes are locked: The method Node.isLocked() provides the locking status either by a direct lock or by a parent node’s deep lock. The method Node.holdsLock() returns whether the node itself holds a lock directly, i.e. does not include parent node’s deep locks in the result.

The lock method returns a Lock object which in returns contains a lock token. The concept of lock tokens might sound counter-intuitive at first. The JCR does not use the user who placed a lock on a node (also known as the lock owner) to determine whether the current session may modify a node. Instead, the lock token must be registered in the current session. When the Node.lock() method is called, the lock is automatically added to the session. The lock token can be removed from the session and registered within another session, allowing the other session to modify the node. A token can only be registered with one session of a given repository, only giving one session per time access to the node. The application code built on top of the content repository may implement a custom locking/unlocking strategy since it must maintain these tokens separately (the repository does not manage them).

Locks can further be limited to the current session, automatically expiring when the session terminates (session-scoped lock):

// isLocked returns whether a lock applies to the node // either by directly being locked or by a parent node’s deep // lock if(!node.isLocked()) { node.lock(false /* isDeep */ , false /* isSessionScoped */); } else { System.out.println(“Node is already locked by ” + node.getProperty(“jcr:lockOwner”)); }

The repository restricts the following operations on a lockable node only when it is locked and the current user does not hold the lock token:

  • Adding and removing properties
  • Changing property values
  • Adding or removing child nodes
  • Adding or removing mixin types

The repository will not prevent deletion or moving of a lockable node as these are strictly seen as operations of the parent node – both operations only change the child nodes of the parent node.

Pages: 1 2 3 4 5 6 7 8 9 10 11