📄 lockmanagerimpl.java
字号:
* Merge this event with another event. The result will be stored in * this event * * @param event other event to merge with */ public void merge(HierarchyEvent event) { type |= event.type; if (event.type == Event.NODE_ADDED) { newPath = event.path; oldPath = path; } else { oldPath = event.path; newPath = path; } } /** * Return the event type. May be {@link Event#NODE_ADDED}, * {@link Event#NODE_REMOVED} or a combination of both.\ * * @return event type */ public int getType() { return type; } /** * Return the old path if this is a move operation * * @return old path */ public Path getOldPath() { return oldPath; } /** * Return the new path if this is a move operation * * @return new path */ public Path getNewPath() { return newPath; } } /** * {@inheritDoc} */ public void onEvent(EventIterator events) { Iterator iter = consolidateEvents(events); while (iter.hasNext()) { HierarchyEvent event = (HierarchyEvent) iter.next(); switch (event.type) { case Event.NODE_ADDED: nodeAdded(event.path); break; case Event.NODE_REMOVED: nodeRemoved(event.path); break; case Event.NODE_ADDED | Event.NODE_REMOVED: nodeMoved(event.getOldPath(), event.getNewPath()); break; } } } /** * Consolidate an event iterator obtained from observation, merging * add and remove operations on nodes with the same UUID into a move * operation. */ private Iterator consolidateEvents(EventIterator events) { LinkedMap eventMap = new LinkedMap(); while (events.hasNext()) { EventImpl event = (EventImpl) events.nextEvent(); HierarchyEvent he; try { he = new HierarchyEvent(event.getChildId(), PathFormat.parse(event.getPath(), nsResolver).getNormalizedPath(), event.getType()); } catch (MalformedPathException e) { log.info("Unable to get event's path: " + e.getMessage()); continue; } catch (RepositoryException e) { log.info("Unable to get event's path: " + e.getMessage()); continue; } HierarchyEvent heExisting = (HierarchyEvent) eventMap.get(he.id); if (heExisting != null) { heExisting.merge(he); } else { eventMap.put(he.id, he); } } return eventMap.values().iterator(); } /** * Refresh a non-empty path element whose children might have changed * its position. */ private void refresh(PathMap.Element element) { final ArrayList infos = new ArrayList(); boolean needsSave = false; // save away non-empty children element.traverse(new PathMap.ElementVisitor() { public void elementVisited(PathMap.Element element) { LockInfo info = (LockInfo) element.get(); infos.add(info); } }, false); // remove all children element.removeAll(); // now re-insert at appropriate location or throw away if node // does no longer exist for (int i = 0; i < infos.size(); i++) { LockInfo info = (LockInfo) infos.get(i); try { NodeImpl node = (NodeImpl) session.getItemManager(). getItem(info.getId()); lockMap.put(node.getPrimaryPath(), info); } catch (RepositoryException e) { info.setLive(false); if (!info.sessionScoped) { needsSave = true; } } } // save if required if (needsSave) { save(); } } /** * Invoked when some node has been added. If the parent of that node * exists, shift all name siblings of the new node having an index greater * or equal. * * @param path path of added node */ private void nodeAdded(Path path) { acquire(); try { PathMap.Element parent = lockMap.map(path.getAncestor(1), true); if (parent != null) { refresh(parent); } } catch (PathNotFoundException e) { log.warn("Unable to determine path of added node's parent.", e); } finally { release(); } } /** * Invoked when some node has been moved. Relink the child inside our * map to the new parent. * * @param oldPath old path * @param newPath new path */ private void nodeMoved(Path oldPath, Path newPath) { acquire(); try { PathMap.Element parent = lockMap.map(oldPath.getAncestor(1), true); if (parent != null) { refresh(parent); } } catch (PathNotFoundException e) { log.warn("Unable to determine path of moved node's parent.", e); } finally { release(); } } /** * Invoked when some node has been removed. Remove the child from our * path map. Disable all locks contained in that subtree. * * @param path path of removed node */ private void nodeRemoved(Path path) { acquire(); try { PathMap.Element parent = lockMap.map(path.getAncestor(1), true); if (parent != null) { refresh(parent); } } catch (PathNotFoundException e) { log.warn("Unable to determine path of removed node's parent.", e); } finally { release(); } } /** * Contains information about a lock and gets placed inside the child * information of a {@link org.apache.jackrabbit.util.PathMap}. */ class LockInfo extends AbstractLockInfo implements SessionListener { /** * Create a new instance of this class. * * @param lockToken lock token * @param sessionScoped whether lock token is session scoped * @param deep whether lock is deep * @param lockOwner owner of lock */ public LockInfo(LockToken lockToken, boolean sessionScoped, boolean deep, String lockOwner) { super(lockToken, sessionScoped, deep, lockOwner); } /** * {@inheritDoc} * <p/> * When the owning session is logging out, we have to perform some * operations depending on the lock type. * (1) If the lock was session-scoped, we unlock the node. * (2) If the lock was open-scoped, we remove the lock token * from the session and set the lockHolder field to <code>null</code>. */ public void loggingOut(SessionImpl session) { if (live) { if (sessionScoped) { // if no session currently holds lock, reassign SessionImpl lockHolder = getLockHolder(); if (lockHolder == null) { setLockHolder(session); } try { NodeImpl node = (NodeImpl) session.getItemManager().getItem(getId()); node.unlock(); } catch (RepositoryException e) { log.warn("Unable to remove session-scoped lock on node '" + lockToken + "': " + e.getMessage()); log.debug("Root cause: ", e); } } else { if (session == lockHolder) { session.removeLockToken(lockToken.toString()); lockHolder = null; } } } } /** * {@inheritDoc} */ public void loggedOut(SessionImpl session) { } } //----------------------------------------------------< LockEventListener > /** * Set a lock event channel * * @param eventChannel lock event channel */ public void setEventChannel(LockEventChannel eventChannel) { this.eventChannel = eventChannel; eventChannel.setListener(this); } /** * {@inheritDoc} */ public void externalLock(NodeId nodeId, boolean isDeep, String userId) throws RepositoryException { acquire(); try { Path path = getPath(nodeId); // create lock token LockInfo info = new LockInfo(new LockToken(nodeId), false, isDeep, userId); info.setLive(true); lockMap.put(path, info); save(); } finally { release(); } } /** * {@inheritDoc} */ public void externalUnlock(NodeId nodeId) throws RepositoryException { acquire(); try { Path path = getPath(nodeId); PathMap.Element element = lockMap.map(path, true); if (element == null) { throw new LockException("Node not locked: " + path.toString()); } AbstractLockInfo info = (AbstractLockInfo) element.get(); if (info == null) { throw new LockException("Node not locked: " + path.toString()); } element.set(null); info.setLive(false); save(); } finally { release(); } } /** * Dump contents of path map and elements included to <code>PrintStream</code> given. * * @param ps print stream to dump to */ public void dump(final PrintStream ps) { lockMap.traverse(new PathMap.ElementVisitor() { public void elementVisited(PathMap.Element element) { StringBuffer line = new StringBuffer(); for (int i = 0; i < element.getDepth(); i++) { line.append("--"); } line.append(element.getName()); int index = element.getIndex(); if (index != 0 && index != 1) { line.append('['); line.append(index); line.append(']'); } line.append(" "); line.append(element.get()); ps.println(line.toString()); } }, true); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -