📄 lockmanagerimpl.java
字号:
save(); successful = true; } } finally { release(); if (operation != null) { operation.ended(successful); } } } /** * Return the most appropriate lock information for a node. This is either * the lock info for the node itself, if it is locked, or a lock info for one * of its parents, if that is deep locked. * @return lock info or <code>null</code> if node is not locked * @throws RepositoryException if an error occurs */ public AbstractLockInfo getLockInfo(NodeId id) throws RepositoryException { acquire(); try { Path path = getPath(id); PathMap.Element element = lockMap.map(path, false); AbstractLockInfo info = (AbstractLockInfo) element.get(); if (info != null) { if (element.hasPath(path) || info.deep) { return info; } } return null; } catch (ItemNotFoundException e) { return null; } finally { release(); } } //----------------------------------------------------------< LockManager > /** * {@inheritDoc} */ public Lock lock(NodeImpl node, boolean isDeep, boolean isSessionScoped) throws LockException, RepositoryException { AbstractLockInfo info = internalLock(node, isDeep, isSessionScoped); return new LockImpl(info, node); } /** * {@inheritDoc} */ public Lock getLock(NodeImpl node) throws LockException, RepositoryException { acquire(); try { SessionImpl session = (SessionImpl) node.getSession(); Path path = getPath(node.getId()); PathMap.Element element = lockMap.map(path, false); AbstractLockInfo info = (AbstractLockInfo) element.get(); if (info == null) { throw new LockException("Node not locked: " + node.safeGetJCRPath()); } if (element.hasPath(path) || info.deep) { Node lockHolder = (Node) session.getItemManager().getItem(info.getId()); return new LockImpl(info, lockHolder); } else { throw new LockException("Node not locked: " + node.safeGetJCRPath()); } } catch (ItemNotFoundException e) { throw new LockException("Node not locked: " + node.safeGetJCRPath()); } finally { release(); } } /** * {@inheritDoc} * <p/> * In order to prevent deadlocks from within the synchronous dispatching of * events, content modifications should not be made from within code * sections that hold monitors. (see #JCR-194) */ public void unlock(NodeImpl node) throws LockException, RepositoryException { internalUnlock(node); } /** * {@inheritDoc} */ public boolean holdsLock(NodeImpl node) throws RepositoryException { acquire(); try { PathMap.Element element = lockMap.map(getPath(node.getId()), true); if (element == null) { return false; } return element.get() != null; } catch (ItemNotFoundException e) { return false; } finally { release(); } } /** * {@inheritDoc} */ public boolean isLockHolder(Session session, NodeImpl node) throws RepositoryException { acquire(); try { PathMap.Element element = lockMap.map(getPath(node.getId()), true); if (element == null) { return false; } AbstractLockInfo info = (AbstractLockInfo) element.get(); return info != null && info.getLockHolder() == session; } catch (ItemNotFoundException e) { return false; } finally { release(); } } /** * {@inheritDoc} */ public boolean isLocked(NodeImpl node) throws RepositoryException { acquire(); try { Path path = getPath(node.getId()); PathMap.Element element = lockMap.map(path, false); AbstractLockInfo info = (AbstractLockInfo) element.get(); if (info == null) { return false; } if (element.hasPath(path)) { return true; } else { return info.deep; } } catch (ItemNotFoundException e) { return false; } finally { release(); } } /** * {@inheritDoc} */ public void checkLock(NodeImpl node) throws LockException, RepositoryException { SessionImpl session = (SessionImpl) node.getSession(); checkLock(getPath(node.getId()), session); } /** * {@inheritDoc} */ public void checkLock(Path path, Session session) throws LockException, RepositoryException { PathMap.Element element = lockMap.map(path, false); AbstractLockInfo info = (AbstractLockInfo) element.get(); if (info != null) { if (element.hasPath(path) || info.deep) { if (session != info.getLockHolder()) { throw new LockException("Node locked."); } } } } /** * {@inheritDoc} */ public void lockTokenAdded(SessionImpl session, String lt) { try { LockToken lockToken = LockToken.parse(lt); NodeImpl node = (NodeImpl) this.session.getItemManager(). getItem(lockToken.id); PathMap.Element element = lockMap.map(node.getPrimaryPath(), true); if (element != null) { AbstractLockInfo info = (AbstractLockInfo) element.get(); if (info != null) { if (info.getLockHolder() == null) { info.setLockHolder(session); if (info instanceof LockInfo) { session.addListener((LockInfo) info); } } else { log.warn("Adding lock token has no effect: " + "lock already held by other session."); } } } } catch (IllegalArgumentException e) { log.warn("Bad lock token: " + e.getMessage()); } catch (RepositoryException e) { log.warn("Unable to set lock holder: " + e.getMessage()); log.debug("Root cause: ", e); } } /** * {@inheritDoc} */ public void lockTokenRemoved(SessionImpl session, String lt) { try { LockToken lockToken = LockToken.parse(lt); NodeImpl node = (NodeImpl) this.session.getItemManager(). getItem(lockToken.id); PathMap.Element element = lockMap.map(node.getPrimaryPath(), true); if (element != null) { AbstractLockInfo info = (AbstractLockInfo) element.get(); if (info != null) { if (session == info.getLockHolder()) { info.setLockHolder(null); } else { log.warn("Removing lock token has no effect: " + "lock held by other session."); } } } } catch (IllegalArgumentException e) { log.warn("Bad lock token: " + e.getMessage()); } catch (RepositoryException e) { log.warn("Unable to reset lock holder: " + e.getMessage()); log.debug("Root cause: ", e); } } /** * Return the path of an item given its id. This method will lookup the * item inside the systme session. */ private Path getPath(ItemId id) throws RepositoryException { return session.getHierarchyManager().getPath(id); } /** * Acquire lock on the lock map. */ private void acquire() { for (;;) { try { lockMapLock.acquire(); break; } catch (InterruptedException e) { // ignore } } } /** * Release lock on the lock map. */ private void release() { lockMapLock.release(); } /** * Start an update operation. This will acquire the lock on the lock map * and disable saving the lock map file. */ public void beginUpdate() { acquire(); savingDisabled = true; } /** * End an update operation. This will save the lock map file and release * the lock on the lock map. */ public void endUpdate() { savingDisabled = false; save(); release(); } /** * Cancel an update operation. This will release the lock on the lock map. */ public void cancelUpdate() { savingDisabled = false; release(); } //----------------------------------------------< SynchronousEventListener > /** * Internal event class that holds old and new paths for moved nodes */ private class HierarchyEvent { /** * ID recorded in event */ private final NodeId id; /** * Path recorded in event */ private final Path path; /** * Old path in move operation */ private Path oldPath; /** * New path in move operation */ private Path newPath; /** * Event type, may be {@link Event#NODE_ADDED}, * {@link Event#NODE_REMOVED} or a combination of both */ private int type; /** * Create a new instance of this class. * * @param id id * @param path path * @param type event type */ public HierarchyEvent(NodeId id, Path path, int type) { this.id = id; this.path = path; this.type = type; } /**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -