@NotNull private VirtualFilePointer create( @Nullable("null means the pointer will be created from the (not null) url") VirtualFile file, @Nullable("null means url has to be computed from the (not-null) file path") String url, @NotNull Disposable parentDisposable, @Nullable VirtualFilePointerListener listener) { VirtualFileSystem fileSystem; String protocol; String path; if (file == null) { int protocolEnd = url.indexOf(URLUtil.SCHEME_SEPARATOR); if (protocolEnd == -1) { protocol = null; fileSystem = null; } else { protocol = url.substring(0, protocolEnd); fileSystem = myVirtualFileManager.getFileSystem(protocol); } path = url.substring(protocolEnd + URLUtil.SCHEME_SEPARATOR.length()); } else { fileSystem = file.getFileSystem(); protocol = fileSystem.getProtocol(); path = file.getPath(); url = VirtualFileManager.constructUrl(protocol, path); } if (fileSystem == TEMP_FILE_SYSTEM) { // for tests, recreate always VirtualFile found = file == null ? VirtualFileManager.getInstance().findFileByUrl(url) : file; return new IdentityVirtualFilePointer(found, url); } boolean isJar = fileSystem == JAR_FILE_SYSTEM; if (fileSystem != LOCAL_FILE_SYSTEM && !isJar) { // we are unable to track alien file systems for now VirtualFile found = fileSystem == null ? null : file != null ? file : VirtualFileManager.getInstance().findFileByUrl(url); // if file is null, this pointer will never be alive return getOrCreateIdentity(url, found); } if (file == null) { String cleanPath = cleanupPath(path, isJar); // if newly created path is the same as substringed from url one then the url did not change, // we can reuse it //noinspection StringEquality if (cleanPath != path) { url = VirtualFileManager.constructUrl(protocol, cleanPath); path = cleanPath; } } // else url has come from VirtualFile.getPath() and is good enough VirtualFilePointerImpl pointer = getOrCreate(parentDisposable, listener, path, Pair.create(file, url)); DelegatingDisposable.registerDisposable(parentDisposable, pointer); return pointer; }
private void copyToTemp(VirtualFile file) { try { final byte[] bytes = file.contentsToByteArray(); mySavedCopies.put(file, bytes); mySavedTimestamps.put(file, file.getTimeStamp()); } catch (IOException e) { LOG.error(e); } }
private void saveChangedProjectFile( final VirtualFile file, @Nullable final Project project, final StateStorage storage) { if (file.exists()) { copyToTemp(file); } registerProjectToReload(project, file, storage); }
@Override public void saveChangedProjectFile(final VirtualFile file, final Project project) { if (file.exists()) { copyToTemp(file); } registerProjectToReload(project, file, null); }
@NotNull private VirtualFilePointer create( @Nullable VirtualFile file, @NotNull String url, @NotNull final Disposable parentDisposable, @Nullable VirtualFilePointerListener listener) { String protocol; IVirtualFileSystem fileSystem; if (file == null) { protocol = VirtualFileManager.extractProtocol(url); fileSystem = myVirtualFileManager.getFileSystem(protocol); } else { protocol = null; fileSystem = file.getFileSystem(); } if (fileSystem == myTempFileSystem) { // for tests, recreate always VirtualFile found = file == null ? VirtualFileManager.getInstance().findFileByUrl(url) : file; return new IdentityVirtualFilePointer(found, url); } if (fileSystem != myLocalFileSystem && !(fileSystem instanceof ArchiveFileSystem)) { // we are unable to track alien file systems for now VirtualFile found = fileSystem == null ? null : file != null ? file : VirtualFileManager.getInstance().findFileByUrl(url); // if file is null, this pointer will never be alive return getOrCreateIdentity(url, found); } String path; if (file == null) { path = VirtualFileManager.extractPath(url); path = cleanupPath(path, protocol, fileSystem); url = VirtualFileManager.constructUrl(protocol, path); } else { path = file.getPath(); // url has come from VirtualFile.getUrl() and is good enough } VirtualFilePointerImpl pointer = getOrCreate(parentDisposable, listener, path, Pair.create(file, url)); DelegatingDisposable.registerDisposable(parentDisposable, pointer); return pointer; }
@Override @NotNull public synchronized VirtualFilePointer create( @NotNull VirtualFile file, @NotNull Disposable parent, @Nullable VirtualFilePointerListener listener) { return create(file, file.getUrl(), parent, listener); }
private void restoreCopy(VirtualFile file) { try { if (file == null) return; // Externally deleted actually. if (!file.isWritable()) return; // IDEA was unable to save it as well. So no need to restore. final byte[] bytes = mySavedCopies.get(file); if (bytes != null) { try { file.setBinaryContent(bytes, -1, mySavedTimestamps.get(file)); } catch (IOException e) { Messages.showWarningDialog( ProjectBundle.message("project.reload.write.failed", file.getPresentableUrl()), ProjectBundle.message("project.reload.write.failed.title")); } } } finally { mySavedCopies.remove(file); mySavedTimestamps.remove(file); } }
@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; }