package jetbrains.mps.ide.platform.watching; /*Generated by MPS */ import com.intellij.openapi.components.ApplicationComponent; import org.apache.log4j.Logger; import org.apache.log4j.LogManager; import com.intellij.util.messages.MessageBus; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.VirtualFileManagerListener; import com.intellij.util.messages.MessageBusConnection; import com.intellij.openapi.vfs.newvfs.BulkFileListener; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import jetbrains.mps.RuntimeFlags; import com.intellij.openapi.application.ApplicationManager; import java.util.List; import com.intellij.openapi.vfs.newvfs.events.VFileEvent; import com.intellij.openapi.application.Application; import jetbrains.mps.internal.collections.runtime.ListSequence; import jetbrains.mps.internal.collections.runtime.IWhereFilter; import jetbrains.mps.ide.vfs.VirtualFileUtils; import jetbrains.mps.internal.collections.runtime.IVisitor; import org.apache.log4j.Level; import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent; import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent; import com.intellij.openapi.vfs.newvfs.events.VFileDeleteEvent; import com.intellij.openapi.vfs.newvfs.events.VFileCopyEvent; import com.intellij.openapi.vfs.newvfs.events.VFileMoveEvent; public class FSChangesWatcher implements ApplicationComponent { private static final Logger LOG = LogManager.getLogger(FSChangesWatcher.class); private final MessageBus myBus; private final VirtualFileManager myVirtualFileManager; private final VirtualFileManagerListener myVirtualFileManagerListener = new VirtualFileManagerListener() { @Override public void beforeRefreshStart(boolean async) { myReloadManager.suspendReloads(); } @Override public void afterRefreshFinish(boolean async) { myReloadManager.resumeReloads(); } }; private MessageBusConnection myConnection; private BulkFileListener myBusListener = new FSChangesWatcher.BulkFileChangesListener(); private ReloadManagerComponent myReloadManager; public FSChangesWatcher(MessageBus bus, VirtualFileManager virtualFileManager, ReloadManagerComponent reloadManager) { myBus = bus; myVirtualFileManager = virtualFileManager; myReloadManager = reloadManager; } @NonNls @NotNull @Override public String getComponentName() { return "Model Changes Watcher"; } @Override public void initComponent() { initComponent(false); } public void initComponent(boolean force) { if (myConnection == null && (force || !(RuntimeFlags.isTestMode()))) { myConnection = myBus.connect(); myConnection.subscribe(VirtualFileManager.VFS_CHANGES, myBusListener); myVirtualFileManager.addVirtualFileManagerListener(myVirtualFileManagerListener); } } @Override public void disposeComponent() { if (myConnection == null) { return; } myVirtualFileManager.removeVirtualFileManagerListener(myVirtualFileManagerListener); myConnection.disconnect(); myConnection = null; } public static FSChangesWatcher instance() { return ApplicationManager.getApplication().getComponent(FSChangesWatcher.class); } private class BulkFileChangesListener implements BulkFileListener { private BulkFileChangesListener() { } @Override public void before(@NotNull List<? extends VFileEvent> events) { } @Override public void after(@NotNull final List<? extends VFileEvent> events) { final Application application = ApplicationManager.getApplication(); if (application.isDisposeInProgress() || application.isDisposed()) { return; } if (ListSequence.fromList(events).all(new IWhereFilter<VFileEvent>() { public boolean accept(VFileEvent it) { return VirtualFileUtils.isFileEventFromMPS(it); } })) { return; } myReloadManager.runReload(FileProcessor.class, new ReloadAction<FileProcessor>() { public void runAction(final FileProcessor participant) { ListSequence.fromList(events).where(new IWhereFilter<VFileEvent>() { public boolean accept(VFileEvent it) { return !(VirtualFileUtils.isFileEventFromMPS(it)); } }).visitAll(new IVisitor<VFileEvent>() { public void visit(VFileEvent it) { if (LOG.isDebugEnabled()) { LOG.debug("Got event " + it); } processAfterEvent(it, participant); } }); } }); } private void processAfterEvent(VFileEvent event, FileProcessor processor) { if (LOG.isDebugEnabled()) { LOG.debug("Process after event for " + event.getPath()); } if (event.getFile() == null) { if (LOG.isEnabledFor(Level.WARN)) { LOG.warn("event.getFile() is null. Event: " + event.getClass().getName() + "; path=" + event.getPath()); } return; } if (!(processor.accepts(event.getFile()))) { return; } if (event instanceof VFileContentChangeEvent) { processor.processContentChanged(event.getFile()); } else if (event instanceof VFileCreateEvent) { processor.processCreate(event.getFile()); } else if (event instanceof VFileDeleteEvent) { processor.processDelete(event.getFile()); } else if (event instanceof VFileCopyEvent) { processor.processCreate(event.getFile()); } else if (event instanceof VFileMoveEvent) { VFileMoveEvent re = (VFileMoveEvent) event; String name = re.getFile().getName(); processor.processDelete(event.getFile()); processor.processCreate(re.getNewParent().findChild(name)); } } } }