SessionImpl session = (SessionImpl) node.getSession();
String lockOwner = (ownerInfo != null) ? ownerInfo : session.getUserID();
InternalLockInfo info = new InternalLockInfo(
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<LockInfo> element = lockMap.map(path, false);
LockInfo other = element.get();
if (other != null) {
if (element.hasPath(path)) {
other.throwLockException(
"Node already locked: " + node, session);
} else if (other.isDeep()) {
other.throwLockException(
"Parent node has a deep lock: " + node, session);
}
}
if (info.isDeep() && element.hasPath(path)
&& element.getChildrenCount() > 0) {
info.throwLockException("Some child node is locked", session);
}
// create lock token
info.setLockHolder(session);
info.setLive(true);
session.addListener(info);
if (!info.isSessionScoped()) {
getSessionLockManager(session).lockTokenAdded(info.getLockToken());
}
lockMap.put(path, info);
if (!info.isSessionScoped()) {
save();
successful = true;
}
return info;
} finally {
release();
if (operation != null) {
operation.ended(successful);
}
}
}