AbstractLockInfo internalLock(NodeImpl node, boolean isDeep,
boolean isSessionScoped, long timeoutHint,
String ownerInfo)
throws LockException, RepositoryException {
SessionImpl session = (SessionImpl) node.getSession();
String lockOwner = (ownerInfo != null) ? ownerInfo : session.getUserID();
LockInfo info = new LockInfo(new LockToken(node.getNodeId()),
isSessionScoped, isDeep, lockOwner, timeoutHint);
ClusterOperation operation = null;
boolean successful = false;
// Cluster is only informed about open-scoped locks
if (eventChannel != null && !isSessionScoped) {
operation = eventChannel.create(node.getNodeId(), isDeep, lockOwner);
}
acquire();
try {
// check whether node is already locked
Path path = getPath(session, node.getId());
PathMap.Element element = lockMap.map(path, false);
LockInfo other = (LockInfo) element.get();
if (other != null) {
if (element.hasPath(path)) {
throw new LockException("Node already locked: " + node);
} else if (other.deep) {
throw new LockException(
"Parent node has a deep lock: " + node);
}
}
if (info.deep && element.hasPath(path)
&& element.getChildrenCount() > 0) {
throw new LockException("Some child node is locked.");
}
// create lock token
info.setLockHolder(session);
info.setLive(true);
session.addListener(info);
if (!info.isSessionScoped()) {
getSessionLockManager(session).lockTokenAdded(info.lockToken.toString());
}
lockMap.put(path, info);