mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Reduce file watcher roundups on adding/removing watch roots
This commit is contained in:
+2
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -284,9 +284,7 @@ public class ArtifactManagerImpl extends ArtifactManager implements ProjectCompo
|
||||
ContainerUtil.addIfNotNull(request, requestsToRemove);
|
||||
}
|
||||
|
||||
final LocalFileSystem fileSystem = LocalFileSystem.getInstance();
|
||||
fileSystem.removeWatchedRoots(requestsToRemove);
|
||||
final Set<LocalFileSystem.WatchRequest> newRequests = fileSystem.addRootsToWatch(toAdd, true);
|
||||
Set<LocalFileSystem.WatchRequest> newRequests = LocalFileSystem.getInstance().replaceWatchedRoots(requestsToRemove, toAdd, true);
|
||||
for (LocalFileSystem.WatchRequest request : newRequests) {
|
||||
myWatchedOutputs.put(request.getRootPath(), request);
|
||||
}
|
||||
|
||||
+2
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -98,12 +98,7 @@ public class CompilerProjectExtensionImpl extends CompilerProjectExtension {
|
||||
public void setCompilerOutputUrl(String compilerOutputUrl) {
|
||||
VirtualFilePointer pointer = VirtualFilePointerManager.getInstance().create(compilerOutputUrl, myProject, null);
|
||||
setCompilerOutputPointer(pointer);
|
||||
final LocalFileSystem.WatchRequest watchRequest =
|
||||
LocalFileSystem.getInstance().addRootToWatch(ProjectRootManagerImpl.extractLocalPath(compilerOutputUrl), true);
|
||||
if (myCompilerOutputWatchRequest != null) {
|
||||
LocalFileSystem.getInstance().removeWatchedRoot(myCompilerOutputWatchRequest);
|
||||
}
|
||||
myCompilerOutputWatchRequest = watchRequest;
|
||||
myCompilerOutputWatchRequest = LocalFileSystem.getInstance().replaceWatchedRoot(myCompilerOutputWatchRequest, compilerOutputUrl, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -614,12 +614,7 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
|
||||
private void addRootsToWatch() {
|
||||
final Set<String> rootPaths = getAllRoots(false);
|
||||
if (rootPaths == null) return;
|
||||
|
||||
final Set<LocalFileSystem.WatchRequest> newRootsToWatch = LocalFileSystem.getInstance().addRootsToWatch(rootPaths, true);
|
||||
|
||||
//remove old requests after adding new ones, helps avoiding unnecessary synchronizations
|
||||
LocalFileSystem.getInstance().removeWatchedRoots(myRootsToWatch);
|
||||
myRootsToWatch = newRootsToWatch;
|
||||
myRootsToWatch = LocalFileSystem.getInstance().replaceWatchedRoots(myRootsToWatch, rootPaths, true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+55
-21
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.roots.impl.libraries;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
@@ -12,17 +27,15 @@ import com.intellij.openapi.vfs.newvfs.events.*;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author ksafonov
|
||||
*/
|
||||
public abstract class JarDirectoryWatcher implements Disposable {
|
||||
|
||||
private final JarDirectories myJarDirectories;
|
||||
private MessageBusConnection myBusConnection = null;
|
||||
private final List<LocalFileSystem.WatchRequest> myWatchRequests = new ArrayList<LocalFileSystem.WatchRequest>();
|
||||
private Collection<LocalFileSystem.WatchRequest> myWatchRequests = Collections.emptySet();
|
||||
|
||||
public JarDirectoryWatcher(JarDirectories jarDirectories) {
|
||||
myJarDirectories = jarDirectories;
|
||||
@@ -30,21 +43,39 @@ public abstract class JarDirectoryWatcher implements Disposable {
|
||||
|
||||
public void updateWatchedRoots() {
|
||||
final LocalFileSystem fs = LocalFileSystem.getInstance();
|
||||
if (!myWatchRequests.isEmpty()) {
|
||||
fs.removeWatchedRoots(myWatchRequests);
|
||||
myWatchRequests.clear();
|
||||
}
|
||||
if (!myJarDirectories.isEmpty()) {
|
||||
final Set<String> recursiveRoots = new HashSet<String>();
|
||||
final Set<String> flatRoots = new HashSet<String>();
|
||||
final VirtualFileManager fm = VirtualFileManager.getInstance();
|
||||
for (OrderRootType rootType : myJarDirectories.getRootTypes()) {
|
||||
for (String url : myJarDirectories.getDirectories(rootType)) {
|
||||
if (fm.getFileSystem(VirtualFileManager.extractProtocol(url)) instanceof LocalFileSystem) {
|
||||
final boolean watchRecursively = myJarDirectories.isRecursive(rootType, url);
|
||||
final LocalFileSystem.WatchRequest request = fs.addRootToWatch(VirtualFileManager.extractPath(url), watchRecursively);
|
||||
myWatchRequests.add(request);
|
||||
final String path = VirtualFileManager.extractPath(url);
|
||||
(watchRecursively ? recursiveRoots : flatRoots).add(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flatRoots.isEmpty()) {
|
||||
myWatchRequests = fs.replaceWatchedRoots(myWatchRequests, recursiveRoots, true);
|
||||
}
|
||||
else if (recursiveRoots.isEmpty()) {
|
||||
myWatchRequests = fs.replaceWatchedRoots(myWatchRequests, flatRoots, false);
|
||||
}
|
||||
else {
|
||||
fs.removeWatchedRoots(myWatchRequests);
|
||||
final int rootsTotal = flatRoots.size() + recursiveRoots.size();
|
||||
if (rootsTotal > 0) {
|
||||
myWatchRequests = new ArrayList<LocalFileSystem.WatchRequest>(rootsTotal);
|
||||
myWatchRequests.addAll(fs.addRootsToWatch(flatRoots, false));
|
||||
myWatchRequests.addAll(fs.addRootsToWatch(recursiveRoots, true));
|
||||
}
|
||||
else {
|
||||
myWatchRequests = Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
if (myBusConnection == null) {
|
||||
myBusConnection = ApplicationManager.getApplication().getMessageBus().connect();
|
||||
myBusConnection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() {
|
||||
@@ -58,17 +89,18 @@ public abstract class JarDirectoryWatcher implements Disposable {
|
||||
for (VFileEvent event : events) {
|
||||
if (event instanceof VFileCopyEvent) {
|
||||
final VFileCopyEvent copyEvent = (VFileCopyEvent)event;
|
||||
final VirtualFile file = copyEvent.getFile();
|
||||
if (isUnderJarDirectory(copyEvent.getNewParent() + "/" + copyEvent.getNewChildName()) ||
|
||||
isUnderJarDirectory(copyEvent.getFile().getUrl())) {
|
||||
file != null && isUnderJarDirectory(file.getUrl())) {
|
||||
changesDetected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (event instanceof VFileMoveEvent) {
|
||||
final VFileMoveEvent moveEvent = (VFileMoveEvent)event;
|
||||
|
||||
final VirtualFile file = moveEvent.getFile();
|
||||
if (isUnderJarDirectory(file.getUrl()) || isUnderJarDirectory(moveEvent.getOldParent().getUrl() + "/" + file.getName())) {
|
||||
if (file != null &&
|
||||
(isUnderJarDirectory(file.getUrl()) || isUnderJarDirectory(moveEvent.getOldParent().getUrl() + "/" + file.getName()))) {
|
||||
changesDetected = true;
|
||||
break;
|
||||
}
|
||||
@@ -106,11 +138,7 @@ public abstract class JarDirectoryWatcher implements Disposable {
|
||||
}
|
||||
}
|
||||
else {
|
||||
final MessageBusConnection connection = myBusConnection;
|
||||
if (connection != null) {
|
||||
myBusConnection = null;
|
||||
connection.disconnect();
|
||||
}
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,13 +146,19 @@ public abstract class JarDirectoryWatcher implements Disposable {
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
cleanup();
|
||||
}
|
||||
|
||||
private void cleanup() {
|
||||
if (!myWatchRequests.isEmpty()) {
|
||||
LocalFileSystem.getInstance().removeWatchedRoots(myWatchRequests);
|
||||
myWatchRequests.clear();
|
||||
myWatchRequests = Collections.emptySet();
|
||||
}
|
||||
if (myBusConnection != null) {
|
||||
myBusConnection.disconnect();
|
||||
|
||||
final MessageBusConnection connection = myBusConnection;
|
||||
if (connection != null) {
|
||||
myBusConnection = null;
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,8 +25,11 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Collections.singleton;
|
||||
|
||||
public abstract class LocalFileSystem extends NewVirtualFileSystem {
|
||||
@NonNls public static final String PROTOCOL = "file";
|
||||
@NonNls public static final String PROTOCOL_PREFIX = PROTOCOL + "://";
|
||||
@@ -125,14 +128,34 @@ public abstract class LocalFileSystem extends NewVirtualFileSystem {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public abstract WatchRequest addRootToWatch(@NotNull final String rootPath, final boolean toWatchRecursively);
|
||||
public WatchRequest addRootToWatch(@NotNull final String rootPath, final boolean watchRecursively) {
|
||||
final Set<WatchRequest> result = addRootsToWatch(singleton(rootPath), watchRecursively);
|
||||
return result.size() == 1 ? result.iterator().next() : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract Set<WatchRequest> addRootsToWatch(@NotNull final Collection<String> rootPaths, final boolean toWatchRecursively);
|
||||
public abstract Set<WatchRequest> addRootsToWatch(@NotNull final Collection<String> rootPaths, final boolean watchRecursively);
|
||||
|
||||
public abstract void removeWatchedRoots(@NotNull final Collection<WatchRequest> rootsToWatch);
|
||||
public void removeWatchedRoot(@Nullable final WatchRequest watchRequest) {
|
||||
if (watchRequest != null) {
|
||||
removeWatchedRoots(singleton(watchRequest));
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void removeWatchedRoot(@NotNull final WatchRequest watchRequest);
|
||||
public abstract void removeWatchedRoots(@NotNull final Collection<WatchRequest> watchRequests);
|
||||
|
||||
@Nullable
|
||||
public WatchRequest replaceWatchedRoot(@Nullable final WatchRequest watchRequest,
|
||||
@NotNull final String rootPath,
|
||||
final boolean watchRecursively) {
|
||||
final Set<WatchRequest> requests = watchRequest != null ? singleton(watchRequest) : Collections.<WatchRequest>emptySet();
|
||||
final Set<WatchRequest> result = replaceWatchedRoots(requests, singleton(rootPath), watchRecursively);
|
||||
return result.size() == 1 ? result.iterator().next() : null;
|
||||
}
|
||||
|
||||
public abstract Set<WatchRequest> replaceWatchedRoots(@NotNull final Collection<WatchRequest> watchRequests,
|
||||
@NotNull final Collection<String> rootPaths,
|
||||
final boolean watchRecursively);
|
||||
|
||||
public abstract void registerAuxiliaryFileOperationsHandler(@NotNull LocalFileOperationsHandler handler);
|
||||
|
||||
|
||||
+114
-113
@@ -15,12 +15,11 @@
|
||||
*/
|
||||
package com.intellij.openapi.vfs.impl.local;
|
||||
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.components.ApplicationComponent;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.io.FileAttributes;
|
||||
import com.intellij.openapi.util.io.FileSystemUtil;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
@@ -114,6 +113,12 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
|
||||
public void disposeComponent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getComponentName() {
|
||||
return "LocalFileSystem";
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public void cleanupForNextTest(Set<VirtualFile> survivors) throws IOException {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@@ -231,31 +236,29 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
|
||||
|
||||
private void setUpFileWatcher() {
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
if (application.isDisposeInProgress() || !myWatcher.isOperational()) return;
|
||||
|
||||
if (application.isDisposeInProgress()) return;
|
||||
final AccessToken token = application.acquireReadActionLock();
|
||||
try {
|
||||
synchronized (myLock) {
|
||||
final WatchRequestImpl[] watchRequests = normalizeRootsForRefresh();
|
||||
final List<String> myRecursiveRoots = new ArrayList<String>();
|
||||
final List<String> myFlatRoots = new ArrayList<String>();
|
||||
|
||||
if (myWatcher.isOperational()) {
|
||||
application.runReadAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (myLock) {
|
||||
final WatchRequestImpl[] watchRequests = normalizeRootsForRefresh();
|
||||
List<String> myRecursiveRoots = new ArrayList<String>();
|
||||
List<String> myFlatRoots = new ArrayList<String>();
|
||||
|
||||
for (WatchRequestImpl root : watchRequests) {
|
||||
if (root.isToWatchRecursively()) {
|
||||
myRecursiveRoots.add(root.myFSRootPath);
|
||||
}
|
||||
else {
|
||||
myFlatRoots.add(root.myFSRootPath);
|
||||
}
|
||||
}
|
||||
|
||||
myWatcher.setWatchRoots(myRecursiveRoots, myFlatRoots);
|
||||
for (WatchRequestImpl watchRequest : watchRequests) {
|
||||
if (watchRequest.isToWatchRecursively()) {
|
||||
myRecursiveRoots.add(watchRequest.myFSRootPath);
|
||||
}
|
||||
else {
|
||||
myFlatRoots.add(watchRequest.myFSRootPath);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
myWatcher.setWatchRoots(myRecursiveRoots, myFlatRoots);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,48 +283,6 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getComponentName() {
|
||||
return "LocalFileSystem";
|
||||
}
|
||||
|
||||
@Override
|
||||
public WatchRequest addRootToWatch(@NotNull final String rootPath, final boolean toWatchRecursively) {
|
||||
if (rootPath.length() == 0 || !myWatcher.isOperational()) return null;
|
||||
|
||||
Application app = ApplicationManager.getApplication();
|
||||
return app.runReadAction(new Computable<WatchRequest>() {
|
||||
@Override
|
||||
public WatchRequest compute() {
|
||||
synchronized (myLock) {
|
||||
final WatchRequestImpl result = new WatchRequestImpl(rootPath, toWatchRecursively);
|
||||
boolean alreadyWatched = isAlreadyWatched(result);
|
||||
if (!alreadyWatched) {
|
||||
final VirtualFile existingFile = findFileByPathIfCached(rootPath);
|
||||
if (existingFile != null) {
|
||||
final ModalityState modalityState = ModalityState.defaultModalityState();
|
||||
RefreshQueue.getInstance().refresh(true, toWatchRecursively, null, modalityState, existingFile);
|
||||
if (existingFile.isDirectory() && !toWatchRecursively && existingFile instanceof NewVirtualFile) {
|
||||
for (VirtualFile child : ((NewVirtualFile)existingFile).getCachedChildren()) {
|
||||
RefreshQueue.getInstance().refresh(true, false, null, modalityState, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
myRootsToWatch.add(result);
|
||||
if (alreadyWatched) {
|
||||
result.myDominated = true;
|
||||
return result;
|
||||
}
|
||||
myCachedNormalizedRequests = null;
|
||||
setUpFileWatcher();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean isAlreadyWatched(final WatchRequestImpl request) {
|
||||
for (final WatchRequestImpl current : normalizeRootsForRefresh()) {
|
||||
if (dominates(current, request)) return true;
|
||||
@@ -339,74 +300,114 @@ public final class LocalFileSystemImpl extends LocalFileSystemBase implements Ap
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Set<WatchRequest> addRootsToWatch(@NotNull final Collection<String> rootPaths, final boolean toWatchRecursively) {
|
||||
if (!myWatcher.isOperational()) return Collections.emptySet();
|
||||
public Set<WatchRequest> addRootsToWatch(@NotNull final Collection<String> rootPaths, final boolean watchRecursively) {
|
||||
if (rootPaths.isEmpty() || !myWatcher.isOperational()) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
else {
|
||||
return replaceWatchedRoots(Collections.<WatchRequest>emptySet(), rootPaths, watchRecursively);
|
||||
}
|
||||
}
|
||||
|
||||
final Set<WatchRequest> result = new HashSet<WatchRequest>();
|
||||
final Set<VirtualFile> filesToSynchronize = new HashSet<VirtualFile>();
|
||||
@Override
|
||||
public void removeWatchedRoots(@NotNull final Collection<WatchRequest> watchRequests) {
|
||||
if (watchRequests.isEmpty()) return;
|
||||
|
||||
Application application = ApplicationManager.getApplication();
|
||||
application.runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
synchronized (myLock) {
|
||||
for (String rootPath : rootPaths) {
|
||||
LOG.assertTrue(rootPath != null);
|
||||
if (rootPath.length() > 0) {
|
||||
final WatchRequestImpl request = new WatchRequestImpl(rootPath, toWatchRecursively);
|
||||
final VirtualFile existingFile = findFileByPathIfCached(rootPath);
|
||||
if (existingFile != null) {
|
||||
if (!isAlreadyWatched(request)) {
|
||||
filesToSynchronize.add(existingFile);
|
||||
}
|
||||
}
|
||||
result.add(request);
|
||||
myRootsToWatch.add(request); //add in any case, safe to add inplace without copying myRootsToWatch before the loop
|
||||
}
|
||||
}
|
||||
final AccessToken token = ApplicationManager.getApplication().acquireReadActionLock();
|
||||
try {
|
||||
synchronized (myLock) {
|
||||
final boolean update = doRemoveWatchedRoots(watchRequests);
|
||||
if (update) {
|
||||
myCachedNormalizedRequests = null;
|
||||
setUpFileWatcher();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
}
|
||||
|
||||
if (!application.isUnitTestMode() && !filesToSynchronize.isEmpty()) {
|
||||
for (VirtualFile file : filesToSynchronize) {
|
||||
if (file instanceof NewVirtualFile && file.getFileSystem() instanceof LocalFileSystem) {
|
||||
((NewVirtualFile)file).markDirtyRecursively();
|
||||
@Override
|
||||
public Set<WatchRequest> replaceWatchedRoots(@NotNull final Collection<WatchRequest> watchRequests,
|
||||
@NotNull final Collection<String> rootPaths,
|
||||
final boolean watchRecursively) {
|
||||
if (rootPaths.isEmpty() || !myWatcher.isOperational()) {
|
||||
removeWatchedRoots(watchRequests);
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
final Set<WatchRequest> result = new HashSet<WatchRequest>();
|
||||
final Set<VirtualFile> filesToSync = new HashSet<VirtualFile>();
|
||||
|
||||
final AccessToken token = ApplicationManager.getApplication().acquireReadActionLock();
|
||||
try {
|
||||
synchronized (myLock) {
|
||||
final boolean update = doAddRootsToWatch(rootPaths, watchRecursively, result, filesToSync) ||
|
||||
doRemoveWatchedRoots(watchRequests);
|
||||
if (update) {
|
||||
myCachedNormalizedRequests = null;
|
||||
setUpFileWatcher();
|
||||
}
|
||||
}
|
||||
refreshFiles(filesToSynchronize, true, toWatchRecursively, null);
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
|
||||
syncFiles(filesToSync, watchRecursively);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeWatchedRoot(@NotNull final WatchRequest watchRequest) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
synchronized (myLock) {
|
||||
if (myRootsToWatch.remove((WatchRequestImpl)watchRequest) && !((WatchRequestImpl)watchRequest).myDominated) {
|
||||
myCachedNormalizedRequests = null;
|
||||
setUpFileWatcher();
|
||||
private boolean doAddRootsToWatch(@NotNull final Collection<String> roots,
|
||||
final boolean recursively,
|
||||
@NotNull final Set<WatchRequest> results,
|
||||
@NotNull final Set<VirtualFile> filesToSync) {
|
||||
boolean update = false;
|
||||
|
||||
for (String root : roots) {
|
||||
final WatchRequestImpl result = new WatchRequestImpl(root, recursively);
|
||||
final boolean alreadyWatched = isAlreadyWatched(result);
|
||||
|
||||
if (!alreadyWatched) {
|
||||
final VirtualFile existingFile = findFileByPathIfCached(root);
|
||||
if (existingFile != null) {
|
||||
if (existingFile.isDirectory() && !recursively && existingFile instanceof NewVirtualFile) {
|
||||
filesToSync.addAll(((NewVirtualFile)existingFile).getCachedChildren());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
result.myDominated = alreadyWatched;
|
||||
myRootsToWatch.add(result);
|
||||
results.add(result);
|
||||
|
||||
update |= !alreadyWatched;
|
||||
}
|
||||
|
||||
return update;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeWatchedRoots(@NotNull final Collection<WatchRequest> rootsToWatch) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
synchronized (myLock) {
|
||||
if (myRootsToWatch.removeAll(rootsToWatch)) {
|
||||
myCachedNormalizedRequests = null;
|
||||
setUpFileWatcher();
|
||||
}
|
||||
}
|
||||
private void syncFiles(@NotNull final Set<VirtualFile> filesToSync, final boolean watchRecursively) {
|
||||
if (filesToSync.isEmpty() || ApplicationManager.getApplication().isUnitTestMode()) return;
|
||||
|
||||
for (VirtualFile file : filesToSync) {
|
||||
if (file instanceof NewVirtualFile && file.getFileSystem() instanceof LocalFileSystem) {
|
||||
((NewVirtualFile)file).markDirtyRecursively();
|
||||
}
|
||||
});
|
||||
}
|
||||
refreshFiles(filesToSync, true, watchRecursively, null);
|
||||
}
|
||||
|
||||
private boolean doRemoveWatchedRoots(@NotNull final Collection<WatchRequest> watchRequests) {
|
||||
boolean update = false;
|
||||
|
||||
for (WatchRequest watchRequest : watchRequests) {
|
||||
final boolean wasWatched = myRootsToWatch.remove((WatchRequestImpl)watchRequest) && !((WatchRequestImpl)watchRequest).myDominated;
|
||||
update |= wasWatched;
|
||||
}
|
||||
|
||||
return update;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-8
@@ -181,24 +181,19 @@ public class Win32LocalFileSystem extends LocalFileSystemBase {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public WatchRequest addRootToWatch(@NotNull String rootPath, boolean toWatchRecursively) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<WatchRequest> addRootsToWatch(@NotNull Collection<String> rootPaths, boolean toWatchRecursively) {
|
||||
public Set<WatchRequest> addRootsToWatch(@NotNull Collection<String> rootPaths, boolean watchRecursively) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeWatchedRoots(@NotNull Collection<WatchRequest> rootsToWatch) {
|
||||
public void removeWatchedRoots(@NotNull Collection<WatchRequest> watchRequests) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeWatchedRoot(@NotNull WatchRequest watchRequest) {
|
||||
public Set<WatchRequest> replaceWatchedRoots(@NotNull Collection<WatchRequest> watchRequests, @NotNull Collection<String> rootPaths, boolean watchRecursively) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
@@ -81,24 +81,20 @@ public class MockLocalFileSystem extends LocalFileSystem {
|
||||
public void refreshFiles(@NotNull Iterable<VirtualFile> files, boolean async, boolean recursive, @Nullable Runnable onFinish) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public WatchRequest addRootToWatch(@NotNull final String rootPath, final boolean toWatchRecursively) {
|
||||
throw new UnsupportedOperationException("'addRootToWatch' not implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Set<WatchRequest> addRootsToWatch(@NotNull final Collection<String> rootPaths, final boolean toWatchRecursively) {
|
||||
throw new UnsupportedOperationException("'addRootsToWatch' not implemented in " + getClass().getName());
|
||||
public Set<WatchRequest> addRootsToWatch(@NotNull final Collection<String> rootPaths, final boolean watchRecursively) {
|
||||
throw new UnsupportedOperationException("Not implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeWatchedRoots(@NotNull final Collection<WatchRequest> rootsToWatch) {
|
||||
throw new UnsupportedOperationException("Not implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeWatchedRoot(@NotNull final WatchRequest watchRequest) {
|
||||
public Set<WatchRequest> replaceWatchedRoots(@NotNull Collection<WatchRequest> watchRequests, @NotNull Collection<String> rootPaths, boolean watchRecursively) {
|
||||
throw new UnsupportedOperationException("Not implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+14
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,10 +19,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.VcsDirectoryMapping;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author irengrig
|
||||
@@ -51,17 +48,25 @@ public class FileWatchRequestModifier implements Runnable {
|
||||
final List<VcsDirectoryMapping> deleted = new LinkedList<VcsDirectoryMapping>(myDirectoryMappingWatches.keySet());
|
||||
deleted.removeAll(copy);
|
||||
|
||||
final Map<String, VcsDirectoryMapping> toAdd = new HashMap<String, VcsDirectoryMapping>();
|
||||
for (VcsDirectoryMapping mapping : added) {
|
||||
if (mapping.isDefaultMapping()) continue;
|
||||
final LocalFileSystem.WatchRequest watchRequest = myLfs.addRootToWatch(mapping.getDirectory(), true);
|
||||
myDirectoryMappingWatches.put(mapping, watchRequest);
|
||||
if (!mapping.isDefaultMapping()) {
|
||||
toAdd.put(mapping.getDirectory(), mapping);
|
||||
}
|
||||
}
|
||||
|
||||
final Collection<LocalFileSystem.WatchRequest> toRemove = new ArrayList<LocalFileSystem.WatchRequest>();
|
||||
for (VcsDirectoryMapping mapping : deleted) {
|
||||
if (mapping.isDefaultMapping()) continue;
|
||||
final LocalFileSystem.WatchRequest removed = myDirectoryMappingWatches.remove(mapping);
|
||||
if (removed != null) {
|
||||
myLfs.removeWatchedRoot(removed);
|
||||
toRemove.add(removed);
|
||||
}
|
||||
}
|
||||
|
||||
final Set<LocalFileSystem.WatchRequest> requests = myLfs.replaceWatchedRoots(toRemove, toAdd.keySet(), true);
|
||||
for (LocalFileSystem.WatchRequest request : requests) {
|
||||
myDirectoryMappingWatches.put(toAdd.get(request.getRootPath()), request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-15
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
|
||||
import com.intellij.javaee.ExternalResourceManager;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -31,6 +32,7 @@ import com.intellij.openapi.roots.WatchedRootsProvider;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -166,26 +168,23 @@ public class FetchExtResourceAction extends BaseExtResourceAction implements Wat
|
||||
});
|
||||
}
|
||||
|
||||
private void fetchDtd(final Project project, final String dtdUrl, final String url, final ProgressIndicator indicator)
|
||||
throws IOException {
|
||||
|
||||
private void fetchDtd(final Project project, final String dtdUrl, final String url, final ProgressIndicator indicator) throws IOException {
|
||||
final String extResourcesPath = getExternalResourcesPath();
|
||||
final File extResources = new File(extResourcesPath);
|
||||
final boolean alreadyExists = extResources.exists();
|
||||
extResources.mkdirs();
|
||||
LOG.assertTrue(extResources.exists());
|
||||
LOG.assertTrue(extResources.mkdirs() || extResources.exists(), extResources);
|
||||
|
||||
final PsiManager psiManager = PsiManager.getInstance(project);
|
||||
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(
|
||||
extResources.getAbsolutePath().replace(File.separatorChar, '/'));
|
||||
LOG.assertTrue(vFile != null);
|
||||
if (!alreadyExists) LocalFileSystem.getInstance().addRootToWatch(vFile.getPath(), true);
|
||||
}
|
||||
});
|
||||
final AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(FetchExtResourceAction.class);
|
||||
try {
|
||||
final String path = FileUtil.toSystemIndependentName(extResources.getAbsolutePath());
|
||||
final VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(path);
|
||||
LOG.assertTrue(vFile != null, path);
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
}
|
||||
}, indicator.getModalityState());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user