@NotNull private VirtualFilePointerImpl getOrCreate( @NotNull Disposable parentDisposable, @Nullable VirtualFilePointerListener listener, @NotNull String path, @NotNull Pair<VirtualFile, String> fileAndUrl) { FilePointerPartNode root = myPointers.get(listener); FilePointerPartNode node; if (root == null) { root = new FilePointerPartNode(path, null, fileAndUrl); myPointers.put(listener, root); node = root; } else { node = root.findPointerOrCreate(path, 0, fileAndUrl); } VirtualFilePointerImpl pointer; if (node.leaf == null) { pointer = new VirtualFilePointerImpl(listener, parentDisposable, fileAndUrl); node.associate(pointer, fileAndUrl); } else { pointer = node.leaf; } pointer.myNode.incrementUsageCount(1); root.checkConsistency(); return pointer; }
@Override public void after(@NotNull final List<? extends VFileEvent> events) { incModificationCount(); for (FilePointerPartNode node : myPointersToUpdateUrl) { synchronized (this) { VirtualFilePointerImpl pointer = node.leaf; String urlBefore = pointer.getUrlNoUpdate(); Pair<VirtualFile, String> after = node.update(); String urlAfter = after.second; if (URL_COMPARATOR.compare(urlBefore, urlAfter) != 0) { // url has changed, reinsert FilePointerPartNode root = myPointers.get(pointer.getListener()); int useCount = node.useCount; node.remove(); FilePointerPartNode newNode = root.findPointerOrCreate(VfsUtilCore.urlToPath(urlAfter), 0, after); VirtualFilePointerImpl existingPointer = newNode.leaf; if (existingPointer != null) { // can happen when e.g. file renamed to the existing file // merge two pointers pointer.myNode = newNode; } else { newNode.associate(pointer, after); } newNode.incrementUsageCount(useCount); } } } VirtualFilePointer[] pointersToFireArray = toPointers(myPointersToFire); for (VirtualFilePointer pointer : pointersToFireArray) { ((VirtualFilePointerImpl) pointer).myNode.update(); } for (EventDescriptor event : myEvents) { event.fireAfter(); } if (pointersToFireArray.length != 0) { myBus.syncPublisher(VirtualFilePointerListener.TOPIC).validityChanged(pointersToFireArray); } myPointersToUpdateUrl = Collections.emptyList(); myEvents = Collections.emptyList(); myPointersToFire = Collections.emptyList(); for (FilePointerPartNode root : myPointers.values()) { root.checkConsistency(); } }