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));
}
}
}
}