package jetbrains.mps.watching; /*Generated by MPS */ import com.intellij.openapi.components.ApplicationComponent; import jetbrains.mps.library.AdditionalLibrariesManager; import jetbrains.mps.classloading.ClassLoaderManager; import jetbrains.mps.classloading.MPSClassesListener; import java.util.Map; import jetbrains.mps.library.Library; import com.intellij.openapi.vfs.LocalFileSystem; import java.util.HashMap; import jetbrains.mps.ide.platform.watching.WatchedRoots; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ProjectManagerAdapter; import jetbrains.mps.ide.MPSCoreComponents; import org.jetbrains.annotations.NotNull; import com.intellij.openapi.project.Project; import jetbrains.mps.project.ProjectLibraryManager; import java.util.Set; import java.util.HashSet; import java.util.List; import java.util.Collection; import java.util.ArrayList; /** * This should probably be gone. * It listens for library changes, class reloads and refreshes library watched paths. */ public class WatchedRootsUpdater implements ApplicationComponent { private final AdditionalLibrariesManager myLibraryManager; private final ClassLoaderManager myClassLoaderManager; private MPSClassesListener myClassesListener; private final Map<Library, LocalFileSystem.WatchRequest> myLibrariesRequests = new HashMap<Library, LocalFileSystem.WatchRequest>(); private final Map<Library, LocalFileSystem.WatchRequest> myProjectLibrariesRequests = new HashMap<Library, LocalFileSystem.WatchRequest>(); private final LocalFileSystem myLocalFileSystem; private final WatchedRoots myWatchedRootsBase; private final ProjectManager myProjectManager; private ProjectManagerAdapter myProjectManagerListener; public WatchedRootsUpdater(LocalFileSystem lfs, WatchedRoots watchedRoots, MPSCoreComponents coreComponents, AdditionalLibrariesManager libraryManager, ProjectManager projectManager) { myLibraryManager = libraryManager; myProjectManager = projectManager; myClassLoaderManager = coreComponents.getClassLoaderManager(); myLocalFileSystem = lfs; myWatchedRootsBase = watchedRoots; } @NotNull @Override public String getComponentName() { return "Watched Roots Updater"; } @Override public void initComponent() { processLibrariesChange(); myProjectManagerListener = new ProjectManagerAdapter() { @Override public void projectOpened(Project project) { processLibrariesChange(project.getComponent(ProjectLibraryManager.class).getUILibraries(), myProjectLibrariesRequests); } @Override public void projectClosing(Project project) { processLibrariesChange(project.getComponent(ProjectLibraryManager.class).getUILibraries(), myProjectLibrariesRequests); } }; myProjectManager.addProjectManagerListener(myProjectManagerListener); } private void processLibrariesChange() { processLibrariesChange(myLibraryManager.getUILibraries(), myLibrariesRequests); processProjectLibrariesChange(); } private void processProjectLibrariesChange() { Set<Library> libs = new HashSet<Library>(); for (Project p : myProjectManager.getOpenProjects()) { libs.addAll(p.getComponent(ProjectLibraryManager.class).getUILibraries()); } processLibrariesChange(libs, myProjectLibrariesRequests); } private void processLibrariesChange(Set<Library> currentLibraries, Map<Library, LocalFileSystem.WatchRequest> libraryToRequest) { List<Library> toRemove = librarySubtract(libraryToRequest.keySet(), currentLibraries); List<Library> toAdd = librarySubtract(currentLibraries, libraryToRequest.keySet()); removeLibraryWatch(toRemove, libraryToRequest); addLibraryWatch(toAdd, libraryToRequest); } private void addLibraryWatch(List<Library> toAdd, Map<Library, LocalFileSystem.WatchRequest> librariesRequests) { for (Library l : toAdd) { LocalFileSystem.WatchRequest watchRequest = myLocalFileSystem.addRootToWatch(l.getPath(), true); librariesRequests.put(l, watchRequest); } } private void removeLibraryWatch(List<Library> toRemove, Map<Library, LocalFileSystem.WatchRequest> librariesRequests) { for (Library l : toRemove) { final LocalFileSystem.WatchRequest watchRequest = librariesRequests.get(l); if (watchRequest != null) { myLocalFileSystem.removeWatchedRoot(watchRequest); } librariesRequests.remove(l); } } private List<Library> librarySubtract(Collection<Library> from, Collection<Library> what) { List<Library> result = new ArrayList<Library>(); for (Library pattern : from) { boolean found = false; for (Library possibleMatching : what) { if (pattern.getPath().equals(possibleMatching.getPath())) { found = true; break; } } if (!(found)) { result.add(pattern); } } return result; } @Override public void disposeComponent() { myClassLoaderManager.removeClassesHandler(myClassesListener); myProjectManager.removeProjectManagerListener(myProjectManagerListener); } }