@NotNull private static VirtualFilePointer[] toPointers(@NotNull List<FilePointerPartNode> pointers) { if (pointers.isEmpty()) return VirtualFilePointer.EMPTY_ARRAY; List<VirtualFilePointer> list = ContainerUtil.mapNotNull( pointers, new Function<FilePointerPartNode, VirtualFilePointer>() { @Override public VirtualFilePointer fun(FilePointerPartNode pair) { return pair.leaf; } }); return list.toArray(new VirtualFilePointer[list.size()]); }
@NotNull private static List<VFileEvent> validateEvents(@NotNull List<VFileEvent> events) { final List<EventWrapper> deletionEvents = ContainerUtil.newArrayList(); for (int i = 0, size = events.size(); i < size; i++) { final VFileEvent event = events.get(i); if (event instanceof VFileDeleteEvent && event.isValid()) { deletionEvents.add(new EventWrapper((VFileDeleteEvent) event, i)); } } final TIntHashSet invalidIDs; if (deletionEvents.isEmpty()) { invalidIDs = EmptyIntHashSet.INSTANCE; } else { ContainerUtil.quickSort(deletionEvents, DEPTH_COMPARATOR); invalidIDs = new TIntHashSet(deletionEvents.size()); final Set<VirtualFile> dirsToBeDeleted = new THashSet<VirtualFile>(deletionEvents.size()); nextEvent: for (EventWrapper wrapper : deletionEvents) { final VirtualFile candidate = wrapper.event.getFile(); VirtualFile parent = candidate; while (parent != null) { if (dirsToBeDeleted.contains(parent)) { invalidIDs.add(wrapper.id); continue nextEvent; } parent = parent.getParent(); } if (candidate.isDirectory()) { dirsToBeDeleted.add(candidate); } } } final List<VFileEvent> filtered = new ArrayList<VFileEvent>(events.size() - invalidIDs.size()); for (int i = 0, size = events.size(); i < size; i++) { final VFileEvent event = events.get(i); if (event.isValid() && !(event instanceof VFileDeleteEvent && invalidIDs.contains(i))) { filtered.add(event); } } return filtered; }
@Override public void after(@NotNull final List<? extends VFileEvent> events) { cleanContainerCaches(); if (myUrlsToUpdate == null) { return; } for (String url : myUrlsToUpdate) { synchronized (VirtualFilePointerManagerImpl.this) { for (TreeMap<String, VirtualFilePointerImpl> urlToPointer : myUrlToPointerMaps.values()) { VirtualFilePointerImpl pointer = urlToPointer.remove(url); if (pointer != null) { String path = VfsUtil.urlToPath(pointer.getUrl()); urlToPointer.put(path, pointer); } } } } for (VirtualFilePointer pointer : myPointersToUpdate) { ((VirtualFilePointerImpl) pointer).update(); } for (EventDescriptor event : myEvents) { event.fireAfter(); } if (!myPointersToUpdate.isEmpty()) { VirtualFilePointer[] arr = myPointersToUpdate.toArray(new VirtualFilePointer[myPointersToUpdate.size()]); myBus.syncPublisher(VirtualFilePointerListener.TOPIC).validityChanged(arr); } myUrlsToUpdate = null; myEvents = null; myPointersToUpdate = null; }
@Override public void before(@NotNull final List<? extends VFileEvent> events) { cleanContainerCaches(); List<VirtualFilePointer> toFireEvents = new ArrayList<VirtualFilePointer>(); List<String> toUpdateUrl = new ArrayList<String>(); synchronized (VirtualFilePointerManagerImpl.this) { for (VFileEvent event : events) { if (event instanceof VFileDeleteEvent) { final VFileDeleteEvent deleteEvent = (VFileDeleteEvent) event; String url = deleteEvent.getFile().getPath(); addPointersUnder(url, true, toFireEvents); } else if (event instanceof VFileCreateEvent) { final VFileCreateEvent createEvent = (VFileCreateEvent) event; String url = createEvent.getPath(); addPointersUnder(url, false, toFireEvents); } else if (event instanceof VFileCopyEvent) { final VFileCopyEvent copyEvent = (VFileCopyEvent) event; String url = copyEvent.getNewParent().getPath() + "/" + copyEvent.getFile().getName(); addPointersUnder(url, false, toFireEvents); } else if (event instanceof VFileMoveEvent) { final VFileMoveEvent moveEvent = (VFileMoveEvent) event; List<VirtualFilePointer> pointers = new ArrayList<VirtualFilePointer>(); addPointersUnder(moveEvent.getFile().getPath(), false, pointers); for (VirtualFilePointer pointer : pointers) { VirtualFile file = pointer.getFile(); if (file != null) { toUpdateUrl.add(file.getPath()); } } } else if (event instanceof VFilePropertyChangeEvent) { final VFilePropertyChangeEvent change = (VFilePropertyChangeEvent) event; if (VirtualFile.PROP_NAME.equals(change.getPropertyName())) { List<VirtualFilePointer> pointers = new ArrayList<VirtualFilePointer>(); addPointersUnder(change.getFile().getPath(), false, pointers); for (VirtualFilePointer pointer : pointers) { VirtualFile file = pointer.getFile(); if (file != null) { toUpdateUrl.add(file.getPath()); } } } } } myEvents = new ArrayList<EventDescriptor>(); for (VirtualFilePointerListener listener : myUrlToPointerMaps.keySet()) { if (listener == null) continue; EventDescriptor event = new EventDescriptor(listener, toFireEvents); myEvents.add(event); } } for (EventDescriptor event : myEvents) { event.fireBefore(); } if (!toFireEvents.isEmpty()) { VirtualFilePointer[] arr = toFireEvents.toArray(new VirtualFilePointer[toFireEvents.size()]); myBus.syncPublisher(VirtualFilePointerListener.TOPIC).beforeValidityChanged(arr); } myPointersToUpdate = toFireEvents; myUrlsToUpdate = toUpdateUrl; }
@Override public void before(@NotNull final List<? extends VFileEvent> events) { List<FilePointerPartNode> toFireEvents = new ArrayList<FilePointerPartNode>(); List<FilePointerPartNode> toUpdateUrl = new ArrayList<FilePointerPartNode>(); VirtualFilePointer[] toFirePointers; synchronized (this) { incModificationCount(); for (VFileEvent event : events) { if (event instanceof VFileDeleteEvent) { final VFileDeleteEvent deleteEvent = (VFileDeleteEvent) event; addPointersUnder(deleteEvent.getFile(), false, "", toFireEvents); } else if (event instanceof VFileCreateEvent) { final VFileCreateEvent createEvent = (VFileCreateEvent) event; addPointersUnder(createEvent.getParent(), true, createEvent.getChildName(), toFireEvents); } else if (event instanceof VFileCopyEvent) { final VFileCopyEvent copyEvent = (VFileCopyEvent) event; addPointersUnder( copyEvent.getNewParent(), true, copyEvent.getFile().getName(), toFireEvents); } else if (event instanceof VFileMoveEvent) { final VFileMoveEvent moveEvent = (VFileMoveEvent) event; VirtualFile eventFile = moveEvent.getFile(); addPointersUnder(moveEvent.getNewParent(), true, eventFile.getName(), toFireEvents); List<FilePointerPartNode> nodes = new ArrayList<FilePointerPartNode>(); addPointersUnder(eventFile, false, "", nodes); for (FilePointerPartNode pair : nodes) { VirtualFile file = pair.leaf.getFile(); if (file != null) { toUpdateUrl.add(pair); } } } else if (event instanceof VFilePropertyChangeEvent) { final VFilePropertyChangeEvent change = (VFilePropertyChangeEvent) event; if (VirtualFile.PROP_NAME.equals(change.getPropertyName())) { VirtualFile eventFile = change.getFile(); VirtualFile parent = eventFile.getParent(); // e.g. for LightVirtualFiles addPointersUnder(parent, true, change.getNewValue().toString(), toFireEvents); List<FilePointerPartNode> nodes = new ArrayList<FilePointerPartNode>(); addPointersUnder(eventFile, false, "", nodes); for (FilePointerPartNode pair : nodes) { VirtualFile file = pair.leaf.getFile(); if (file != null) { toUpdateUrl.add(pair); } } } } } myEvents = new ArrayList<EventDescriptor>(); toFirePointers = toPointers(toFireEvents); for (final VirtualFilePointerListener listener : myPointers.keySet()) { if (listener == null) continue; List<VirtualFilePointer> filtered = ContainerUtil.filter( toFirePointers, new Condition<VirtualFilePointer>() { @Override public boolean value(VirtualFilePointer pointer) { return ((VirtualFilePointerImpl) pointer).getListener() == listener; } }); if (!filtered.isEmpty()) { EventDescriptor event = new EventDescriptor( listener, filtered.toArray(new VirtualFilePointer[filtered.size()])); myEvents.add(event); } } } for (EventDescriptor descriptor : myEvents) { descriptor.fireBefore(); } if (!toFireEvents.isEmpty()) { myBus.syncPublisher(VirtualFilePointerListener.TOPIC).beforeValidityChanged(toFirePointers); } myPointersToFire = toFireEvents; myPointersToUpdateUrl = toUpdateUrl; }