/** * Forces a reparse of the specified collection of files. * * @param files the files to reparse. */ public static void reparseFiles(@NotNull final Collection<VirtualFile> files) { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { // files must be processed under one write action to prevent firing event for invalid files. final Set<VFilePropertyChangeEvent> events = new THashSet<VFilePropertyChangeEvent>(); for (VirtualFile file : files) { saveOrReload(file, events); } BulkFileListener publisher = ApplicationManager.getApplication().getMessageBus().syncPublisher(VirtualFileManager.VFS_CHANGES); List<VFileEvent> eventList = new ArrayList<VFileEvent>(events); publisher.before(eventList); publisher.after(eventList); } }); }
@Override public void notifyPropertyChanged(@NotNull final VirtualFile virtualFile, @NotNull final String property, final Object oldValue, final Object newValue) { final Application application = ApplicationManager.getApplication(); final Runnable runnable = new Runnable() { @Override public void run() { if (virtualFile.isValid() && !application.isDisposed()) { application.runWriteAction(new Runnable() { @Override public void run() { List<VFilePropertyChangeEvent> events = Collections .singletonList(new VFilePropertyChangeEvent(this, virtualFile, property, oldValue, newValue, false)); BulkFileListener listener = application.getMessageBus().syncPublisher(VirtualFileManager.VFS_CHANGES); listener.before(events); listener.after(events); } }); } } }; application.invokeLater(runnable, ModalityState.NON_MODAL); }
public static void reparseFiles(@NotNull final Collection<VirtualFile> files) { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { // files must be processed under one write action to prevent firing event for invalid files. final Set<VFilePropertyChangeEvent> events = new THashSet<VFilePropertyChangeEvent>(); for (VirtualFile file : files) { saveOrReload(file, events); } ApplicationManager.getApplication().getMessageBus().syncPublisher(VirtualFileManager.VFS_CHANGES) .before(new ArrayList<VFileEvent>(events)); ApplicationManager.getApplication().getMessageBus().syncPublisher(VirtualFileManager.VFS_CHANGES) .after(new ArrayList<VFileEvent>(events)); } }); }
@Override public void notifyPropertyChanged(final VirtualFile virtualFile, final String property, final Object oldValue, final Object newValue) { final Application application = ApplicationManager.getApplication(); final Runnable runnable = new Runnable() { @Override public void run() { if (virtualFile.isValid() && !application.isDisposed()) { application.runWriteAction(new Runnable() { @Override public void run() { List<VFilePropertyChangeEvent> events = Collections .singletonList(new VFilePropertyChangeEvent(this, virtualFile, property, oldValue, newValue, false)); BulkFileListener listener = application.getMessageBus().syncPublisher(VirtualFileManager.VFS_CHANGES); listener.before(events); listener.after(events); } }); } } }; application.invokeLater(runnable, ModalityState.NON_MODAL); }
/** * Internal handler for file delete, move and rename events * @param event IntelliJ's file change event * @throws CmsConnectionException if the connection to OpenCms fails */ private void handleFileEvent(VFileEvent event) throws CmsConnectionException { // File is deleted if (event instanceof VFileDeleteEvent) { handleFileDeleteEvent(event); } // File is moved if (event instanceof VFileMoveEvent) { handleFileMoveEvent(event); } // File is renamed if (event instanceof VFilePropertyChangeEvent) { String propertyName = ((VFilePropertyChangeEvent)event).getPropertyName(); if ("name".equals(propertyName)) { handleFileRenameEvent(event); } } }
/** * Internal handler for file rename events fills a list of files to be renamed that is handled later in * {@link OpenCmsModuleFileChangeHandler#handleChanges()} * @param event IntelliJ's file change event * @throws CmsConnectionException if the connection to OpenCms fails */ private void handleFileRenameEvent(VFileEvent event) throws CmsConnectionException { VirtualFile ideaVFile = event.getFile(); if (ideaVFile != null) { String renameFilePath = ideaVFile.getPath(); OpenCmsModule ocmsModule = openCmsModules.getModuleForPath(renameFilePath); if (ocmsModule != null) { LOG.debug("The following file was renamed: " + ideaVFile.getPath()); String oldName = (String)((VFilePropertyChangeEvent)event).getOldValue(); String newName = (String)((VFilePropertyChangeEvent)event).getNewValue(); String newVfsPath = ocmsModule.getVfsPathForRealPath(renameFilePath); String oldVfsPath = newVfsPath.replaceFirst(newName, oldName); if (!oldVfsPath.equals(newVfsPath) && ocmsModule.isPathModuleResource(ocmsModule.getLocalVfsRoot() + oldVfsPath) && getVfsAdapter().exists(oldVfsPath)) { changeHandler.addFileToBeRenamed(ocmsModule, ideaVFile, oldVfsPath, newVfsPath, newName); } } } }
@RequiredDispatchThread public static void reparseFiles(@Nonnull final Collection<VirtualFile> files) { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { // files must be processed under one write action to prevent firing event for invalid files. final Set<VFilePropertyChangeEvent> events = new THashSet<VFilePropertyChangeEvent>(); for (VirtualFile file : files) { saveOrReload(file, events); } BulkFileListener publisher = ApplicationManager.getApplication().getMessageBus().syncPublisher(VirtualFileManager.VFS_CHANGES); List<VFileEvent> eventList = new ArrayList<VFileEvent>(events); publisher.before(eventList); publisher.after(eventList); } }); }
@RequiredWriteAction private static void saveOrReload(VirtualFile file, @Nonnull Collection<VFilePropertyChangeEvent> events) { if (file == null || file.isDirectory() || !file.isValid()) { return; } FileDocumentManager documentManager = FileDocumentManager.getInstance(); if (documentManager.isFileModified(file)) { Document document = documentManager.getDocument(file); if (document != null) { documentManager.saveDocument(document); } } events.add(new VFilePropertyChangeEvent(FORCE_RELOAD_REQUESTOR, file, VirtualFile.PROP_NAME, file.getName(), file.getName(), false)); }
@Override public void notifyPropertyChanged(@Nonnull final VirtualFile virtualFile, @Nonnull final String property, final Object oldValue, final Object newValue) { final Application application = ApplicationManager.getApplication(); final Runnable runnable = new Runnable() { @Override public void run() { if (virtualFile.isValid() && !application.isDisposed()) { application.runWriteAction(new Runnable() { @Override public void run() { List<VFilePropertyChangeEvent> events = Collections .singletonList(new VFilePropertyChangeEvent(this, virtualFile, property, oldValue, newValue, false)); BulkFileListener listener = application.getMessageBus().syncPublisher(VirtualFileManager.VFS_CHANGES); listener.before(events); listener.after(events); } }); } } }; application.invokeLater(runnable, ModalityState.NON_MODAL); }
public GistManagerImpl() { ApplicationManager.getApplication().getMessageBus().connect().subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener.Adapter() { @Override public void after(@Nonnull List<? extends VFileEvent> events) { if (events.stream().anyMatch(this::shouldDropCache)) { invalidateData(); } } private boolean shouldDropCache(VFileEvent e) { if (!(e instanceof VFilePropertyChangeEvent)) return false; String propertyName = ((VFilePropertyChangeEvent)e).getPropertyName(); return propertyName.equals(VirtualFile.PROP_NAME) || propertyName.equals(VirtualFile.PROP_ENCODING); } }); }
public VirtualFilePropertyEvent(Object requestor, @NotNull VirtualFile file, @NotNull String propertyName, Object oldValue, Object newValue){ super(requestor, file, file.getName(), file.getParent()); myPropertyName = propertyName; myOldValue = oldValue; myNewValue = newValue; VFilePropertyChangeEvent.checkPropertyValuesCorrect(requestor, propertyName, oldValue, newValue); }
private static void saveOrReload(VirtualFile file, @NotNull Collection<VFilePropertyChangeEvent> events) { if (file == null || file.isDirectory() || !file.isValid()) { return; } FileDocumentManager documentManager = FileDocumentManager.getInstance(); if (documentManager.isFileModified(file)) { Document document = documentManager.getDocument(file); if (document != null) { documentManager.saveDocumentAsIs(document); // this can be called e.g. in context of undo, so we shouldn't modify document } } events.add(new VFilePropertyChangeEvent(FORCE_RELOAD_REQUESTOR, file, VirtualFile.PROP_NAME, file.getName(), file.getName(), false)); }
@Override public void after(List<? extends VFileEvent> events) { if (!enabled) { return; } for (VFileEvent event : events) { VirtualFile modifiedFile = null; // Skip delete events. if (event instanceof VFileContentChangeEvent || event instanceof VFileCreateEvent) { modifiedFile = event.getFile(); } else if (event instanceof VFileCopyEvent) { VFileCopyEvent copyEvent = (VFileCopyEvent) event; modifiedFile = copyEvent.getNewParent(); } else if (event instanceof VFileMoveEvent) { VFileMoveEvent moveEvent = (VFileMoveEvent) event; modifiedFile = moveEvent.getNewParent(); } else if (event instanceof VFilePropertyChangeEvent) { VFilePropertyChangeEvent propEvent = (VFilePropertyChangeEvent) event; // Check for file renames (sometimes we get property change events without the name // actually changing though) if (propEvent.getPropertyName().equals(VirtualFile.PROP_NAME) && !propEvent.getOldValue().equals(propEvent.getNewValue())) { modifiedFile = propEvent.getFile(); } } if (SymbolTableProvider.isSourceFile(modifiedFile)) { queueChange(modifiedFile); } } }
private static void saveOrReload(final VirtualFile virtualFile, Collection<VFilePropertyChangeEvent> events) { if (virtualFile == null || virtualFile.isDirectory() || !virtualFile.isValid()) { return; } final FileDocumentManager documentManager = FileDocumentManager.getInstance(); if (documentManager.isFileModified(virtualFile)) { Document document = documentManager.getDocument(virtualFile); if (document != null) { documentManager.saveDocument(document); } } events.add( new VFilePropertyChangeEvent(FORCE_RELOAD_REQUESTOR, virtualFile, VirtualFile.PROP_NAME, virtualFile.getName(), virtualFile.getName(), false)); }
private boolean isMoveOrRename( VFileEvent event ) { return event instanceof VFilePropertyChangeEvent && ((VFilePropertyChangeEvent)event).getPropertyName().equals( VirtualFile.PROP_NAME ) || event instanceof VFileMoveEvent; }
private static void checkSubscription() { if (ourSubscribed.getAndSet(true)) return; Application app = ApplicationManager.getApplication(); app.getMessageBus().connect(app).subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener.Adapter() { @Override public void after(@NotNull List<? extends VFileEvent> events) { InvalidationState state = null; synchronized (ourLock) { for (VFileEvent event : events) { if (!(event.getFileSystem() instanceof LocalFileSystem)) continue; if (event instanceof VFileCreateEvent) continue; // created file should not invalidate + getFile is costly if (event instanceof VFilePropertyChangeEvent && !VirtualFile.PROP_NAME.equals(((VFilePropertyChangeEvent)event).getPropertyName())) { continue; } String path = event.getPath(); if (event instanceof VFilePropertyChangeEvent) { path = ((VFilePropertyChangeEvent)event).getOldPath(); } else if (event instanceof VFileMoveEvent) { path = ((VFileMoveEvent)event).getOldPath(); } VirtualFile file = event.getFile(); if (file == null || !file.isDirectory()) { state = InvalidationState.invalidate(state, path); } else { Collection<String> affectedPaths = ourDominatorsMap.get(path); if (affectedPaths != null) { affectedPaths = ContainerUtil.newArrayList(affectedPaths); // defensive copying; original may be updated on invalidation for (String affectedPath : affectedPaths) { state = InvalidationState.invalidate(state, affectedPath); } } } } } if (state != null) state.scheduleRefresh(); } }); }
/** * This gets called on all file system changes, but we're interested in changes to module root directories. When we see them, we'll update * the settings.gradle file. Note that users can also refactor modules by renaming them, which just changes their display name and not * the filesystem directory -- when that happens, this class gets a * {@link ModuleAdapter#modulesRenamed(com.intellij.openapi.project.Project, java.util.List)} callback. However, it's not appropriate to * update settings.gradle in that case since Gradle doesn't case about IJ's display name of the module. */ @Override public void after(@NotNull List<? extends VFileEvent> events) { for (VFileEvent event : events) { if (!(event instanceof VFilePropertyChangeEvent)) { continue; } VFilePropertyChangeEvent propChangeEvent = (VFilePropertyChangeEvent)event; if (!(VirtualFile.PROP_NAME.equals(propChangeEvent.getPropertyName()))) { continue; } VirtualFile eventFile = propChangeEvent.getFile(); if (!eventFile.isDirectory()) { continue; } // Dig through our modules and find the one that matches the change event's path (the module will already have its path updated by // now). Module module = null; Module[] modules = ModuleManager.getInstance(myProject).getModules(); for (Module m : modules) { VirtualFile file = GradleUtil.getGradleBuildFile(m); if (file != null) { VirtualFile moduleDir = file.getParent(); if (moduleDir != null && FileUtil.pathsEqual(eventFile.getPath(), moduleDir.getPath())) { module = m; break; } } } // If we found the module, then remove the old reference from the settings.gradle file and put in a new one. if (module != null) { AndroidGradleFacet androidGradleFacet = AndroidGradleFacet.getInstance(module); if (androidGradleFacet == null) { continue; } String oldPath = androidGradleFacet.getConfiguration().GRADLE_PROJECT_PATH; String newPath = updateProjectNameInGradlePath(androidGradleFacet, eventFile); if (oldPath.equals(newPath)) { continue; } GradleSettingsFile settingsFile = GradleSettingsFile.get(myProject); if (settingsFile != null) { settingsFile.removeModule(oldPath); settingsFile.addModule(newPath, VfsUtilCore.virtualToIoFile(eventFile)); } } } }
public static void execute(final PsiElement element, final String newName, final UsageInfo[] usages, @Nullable final RefactoringElementListener listener) throws IncorrectOperationException { try { final VirtualFile virtualFile; if (element instanceof PsiFile) { logger.info("Renaming file..."); virtualFile = ((PsiFile) element).getVirtualFile(); } else if (element instanceof PsiDirectory) { logger.info("Renaming directory..."); virtualFile = ((PsiDirectory) element).getVirtualFile(); } else { // should never reach here since we check if file/directory before making a rename logger.warn("RenameFile: failed to find proper object to rename: " + element.getClass()); throw new IncorrectOperationException("Can't perform rename on objects other than files and directories"); } final String currentPath = virtualFile.getPath(); final String parentDirectory = virtualFile.getParent().getPath(); final String newPath = Path.combine(parentDirectory, newName); final Project project = element.getProject(); // a single file may have 0, 1, or 2 pending changes to it // 0 - file has not been touched in the local workspace // 1 - file has versioned OR unversioned changes // 2 - file has versioned AND unversioned changes (rare but can happen) final List<PendingChange> pendingChanges = new ArrayList<PendingChange>(2); pendingChanges.addAll(CommandUtils.getStatusForFiles(TFSVcs.getInstance(project).getServerContext(true), ImmutableList.of(currentPath))); // ** Rename logic ** // If 1 change and it's an add that means it's a new unversioned file so rename thru the file system // Anything else can be renamed // Deleted files should not be at this point since IDE disables rename option for them if (pendingChanges.size() == 1 && pendingChanges.get(0).getChangeTypes().contains(ServerStatusType.ADD)) { logger.info("Renaming unversioned file thru file system"); RenameUtil.doRenameGenericNamedElement(element, newName, usages, listener); } else { logger.info("Renaming file thru tf commandline"); CommandUtils.renameFile(TFSVcs.getInstance(project).getServerContext(true), currentPath, newPath); // this alerts that a rename has taken place so any additional processing can take place final VFileEvent event = new VFilePropertyChangeEvent(element.getManager(), virtualFile, "name", currentPath, newName, false); PersistentFS.getInstance().processEvents(Collections.singletonList(event)); } } catch (Throwable t) { logger.warn("renameElement experienced a failure while trying to rename a file", t); throw new IncorrectOperationException(t); } if (listener != null) { listener.elementRenamed(element); } }
private static void checkSubscription() { if (ourSubscribed.getAndSet(true)) return; Application app = ApplicationManager.getApplication(); app.getMessageBus().connect(app).subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener.Adapter() { @Override public void after(@Nonnull List<? extends VFileEvent> events) { InvalidationState state = null; synchronized (ourLock) { for (VFileEvent event : events) { if (!(event.getFileSystem() instanceof LocalFileSystem)) continue; if (event instanceof VFileCreateEvent) continue; // created file should not invalidate + getFile is costly if (event instanceof VFilePropertyChangeEvent && !VirtualFile.PROP_NAME.equals(((VFilePropertyChangeEvent)event).getPropertyName())) { continue; } String path = event.getPath(); if (event instanceof VFilePropertyChangeEvent) { path = ((VFilePropertyChangeEvent)event).getOldPath(); } else if (event instanceof VFileMoveEvent) { path = ((VFileMoveEvent)event).getOldPath(); } VirtualFile file = event.getFile(); if (file == null || !file.isDirectory()) { state = InvalidationState.invalidate(state, path); } else { Collection<String> affectedPaths = ourDominatorsMap.get(path); if (affectedPaths != null) { affectedPaths = ContainerUtil.newArrayList(affectedPaths); // defensive copying; original may be updated on invalidation for (String affectedPath : affectedPaths) { state = InvalidationState.invalidate(state, affectedPath); } } } } } if (state != null) state.scheduleRefresh(); } }); }