IDEA-73437 (Freeze during CVS "Update project")

This commit is contained in:
Bas Leijdekkers
2011-09-06 11:28:53 +02:00
parent afe2ce1ba5
commit 4373ad6cfb
4 changed files with 15 additions and 266 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2011 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,31 +19,20 @@ import com.intellij.CvsBundle;
import com.intellij.cvsSupport2.CvsVcs2;
import com.intellij.cvsSupport2.actions.update.UpdateSettings;
import com.intellij.cvsSupport2.config.CvsConfiguration;
import com.intellij.cvsSupport2.connections.CvsRootProvider;
import com.intellij.cvsSupport2.cvsExecution.ModalityContext;
import com.intellij.cvsSupport2.cvsoperations.common.FindAllRoots;
import com.intellij.cvsSupport2.cvsoperations.common.FindAllRootsHelper;
import com.intellij.cvsSupport2.cvsoperations.common.PostCvsActivity;
import com.intellij.cvsSupport2.cvsoperations.cvsUpdate.MergedWithConflictProjectOrModuleFile;
import com.intellij.cvsSupport2.cvsoperations.cvsUpdate.UpdateOperation;
import com.intellij.cvsSupport2.cvsoperations.cvsUpdate.ui.CorruptedProjectFilesDialog;
import com.intellij.cvsSupport2.errorHandling.CannotFindCvsRootException;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsKey;
import com.intellij.openapi.vcs.update.FileGroup;
import com.intellij.openapi.vcs.update.UpdatedFiles;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Options;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.netbeans.lib.cvsclient.file.ICvsFileSystem;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
@@ -52,18 +41,14 @@ import java.util.Collection;
*/
public class UpdateHandler extends CommandCvsHandler implements PostCvsActivity {
private final FilePath[] myFiles;
private final Collection<VirtualFile> myRoots = new ArrayList<VirtualFile>();
private final Collection<File> myNotProcessedRepositories = new HashSet<File>();
private double myDirectoriesToBeProcessedCount;
private static final CvsMessagePattern UPDATE_PATTERN = new CvsMessagePattern(new String[]{"cvs server: Updating ", "*"}, 2);
private final Project myProject;
private final Collection<MergedWithConflictProjectOrModuleFile> myCorruptedFiles = new ArrayList<MergedWithConflictProjectOrModuleFile>();
private final UpdatedFiles myUpdatedFiles;
private final UpdateSettings myUpdateSettings;
public UpdateHandler(FilePath[] files, UpdateSettings updateSettings, @NotNull Project project, @NotNull UpdatedFiles updatedFiles) {
super(CvsBundle.message("operation.name.update"), new UpdateOperation(new FilePath[0], updateSettings, project),
super(CvsBundle.message("operation.name.update"), new UpdateOperation(files, updateSettings, project),
FileSetToBeUpdated.selectedFiles(files));
myFiles = files;
myProject = project;
@@ -71,65 +56,21 @@ public class UpdateHandler extends CommandCvsHandler implements PostCvsActivity
myUpdateSettings = updateSettings;
}
public void beforeLogin() {
try {
super.beforeLogin();
FindAllRoots findAllRoots = new FindAllRoots(myProject);
final FilePath[] filteredFiles = FindAllRootsHelper.findVersionedUnder(myFiles);
myRoots.addAll(findAllRoots.executeOn(filteredFiles));
myNotProcessedRepositories.addAll(findAllRoots.getDirectoriesToBeUpdated());
myDirectoriesToBeProcessedCount = myNotProcessedRepositories.size();
for(VirtualFile file: myRoots) {
if (getValidCvsRoot(file) != null) {
((UpdateOperation)myCvsOperation).addFile(file);
}
}
}
catch (ProcessCanceledException ex) {
myIsCanceled = true;
}
}
@Nullable
private static CvsRootProvider getValidCvsRoot(final VirtualFile file) {
try {
return CvsRootProvider.createOn(new File(file.getPath()));
}
catch (CannotFindCvsRootException e) {
return null;
}
}
public void addFileMessage(String message, ICvsFileSystem cvsFileSystem) {
super.addFileMessage(message, cvsFileSystem);
ProgressIndicator progress = getProgress();
if (progress == null) return;
if (UPDATE_PATTERN.matches(message)) {
String relativeFileName = UPDATE_PATTERN.getRelativeFileName(message);
myNotProcessedRepositories.remove(cvsFileSystem.getLocalFileSystem().getFile(relativeFileName));
int notProcessedSize = myNotProcessedRepositories.size();
progress.setFraction(0.5 + (myDirectoriesToBeProcessedCount - notProcessedSize) / (2 * myDirectoriesToBeProcessedCount));
}
}
public void registerCorruptedProjectOrModuleFile(MergedWithConflictProjectOrModuleFile mergedWithConflictProjectOrModuleFile) {
myCorruptedFiles.add(mergedWithConflictProjectOrModuleFile);
}
protected void onOperationFinished(ModalityContext modalityContext) {
if (myUpdateSettings.getPruneEmptyDirectories()) {
final IOFilesBasedDirectoryPruner pruner = new IOFilesBasedDirectoryPruner(ProgressManager.getInstance().getProgressIndicator());
for (final VirtualFile myRoot : myRoots) {
pruner.addFile(new File(myRoot.getPath()));
for (FilePath file : myFiles) {
pruner.addFile(file.getIOFile());
}
pruner.execute();
}
if (!myCorruptedFiles.isEmpty()) {
int showOptions = CvsConfiguration.getInstance(myProject).SHOW_CORRUPTED_PROJECT_FILES;
final int showOptions = CvsConfiguration.getInstance(myProject).SHOW_CORRUPTED_PROJECT_FILES;
if (showOptions == Options.PERFORM_ACTION_AUTOMATICALLY) {
for (final MergedWithConflictProjectOrModuleFile myCorruptedFile : myCorruptedFiles) {
@@ -142,7 +83,6 @@ public class UpdateHandler extends CommandCvsHandler implements PostCvsActivity
new CorruptedProjectFilesDialog(myProject, myCorruptedFiles).show();
}
}, myProject);
}
final VcsKey vcsKey = CvsVcs2.getKey();
@@ -154,9 +94,7 @@ public class UpdateHandler extends CommandCvsHandler implements PostCvsActivity
myUpdatedFiles.getGroupById(FileGroup.MODIFIED_ID).add(myCorruptedFile.getOriginal().getPath(), vcsKey, null);
}
}
}
}
protected PostCvsActivity getPostActivityHandler() {
@@ -255,6 +255,8 @@ public abstract class CvsCommandOperation extends CvsOperation implements IFileI
try {
command.execute(requestProcessor, eventManager, eventManager, clientEnvironment, new IProgressViewer() {
public void setProgress(double value) {
ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
if (progressIndicator != null) progressIndicator.setFraction(value);
}
});
}
@@ -1,184 +0,0 @@
/*
* Copyright 2000-2009 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.cvsSupport2.cvsoperations.common;
import com.intellij.CvsBundle;
import com.intellij.cvsSupport2.CvsUtil;
import com.intellij.cvsSupport2.application.CvsEntriesManager;
import com.intellij.cvsSupport2.connections.CvsEnvironment;
import com.intellij.cvsSupport2.util.CvsVfsUtil;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import java.io.File;
import java.util.*;
/**
* author: lesya
*/
public class FindAllRoots {
private final CvsEntriesManager myManager = CvsEntriesManager.getInstance();
private int myProcessedFiles;
private int mySuitableFiles;
private final Collection<File> myRepositories = new HashSet<File>();
private final Collection<VirtualFile> myResult = new ArrayList<VirtualFile>();
private final ProgressIndicator myProgress;
private final ProjectRootManager myProjectRootManager;
public FindAllRoots(Project project) {
myProgress = ProgressManager.getInstance().getProgressIndicator();
myProjectRootManager = ProjectRootManager.getInstance(project);
}
public Collection<VirtualFile> executeOn(final FilePath[] roots) {
final Collection<FilePath> rootsWithoutIntersections = getRootsWithoutIntersections(roots);
setText(CvsBundle.message("progress.text.searching.for.cvs.root"));
myManager.lockSynchronizationActions();
mySuitableFiles = calcVirtualFilesUnderCvsIn(rootsWithoutIntersections) * 2;
myProcessedFiles = 0;
try {
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
for (final FilePath file : rootsWithoutIntersections) {
VirtualFile virtualFile = file.getVirtualFile();
if (virtualFile != null) {
myResult.add(virtualFile);
process(virtualFile);
}
else {
VirtualFile virtualFileParent = file.getVirtualFileParent();
if (virtualFileParent != null) {
myResult.add(virtualFileParent);
}
}
}
}
});
}
finally {
myManager.unlockSynchronizationActions();
}
return myResult;
}
private int calcVirtualFilesUnderCvsIn(Collection<FilePath> rootsWithoutIntersections) {
int result = 0;
for (final FilePath cvsFileWrapper : rootsWithoutIntersections) {
if (!cvsFileWrapper.isDirectory()) {
result += 1;
}
else {
result += calcVirtualFilesUnderCvsIn(cvsFileWrapper.getVirtualFile());
}
}
return result;
}
private int calcVirtualFilesUnderCvsIn(VirtualFile file) {
if (file == null || !file.isDirectory()) return 0;
if (!myProjectRootManager.getFileIndex().isInContent(file)) return 0;
int result = 0;
if (file.findChild(CvsUtil.CVS) == null) return result;
result += 1;
VirtualFile[] children = file.getChildren();
if (children == null) return result;
for (VirtualFile child : children) {
if (child.getName() == CvsUtil.CVS) continue;
result += calcVirtualFilesUnderCvsIn(child);
}
return result;
}
private static Collection<FilePath> getRootsWithoutIntersections(FilePath[] roots) {
ArrayList<FilePath> result = new ArrayList<FilePath>();
List<FilePath> list = Arrays.asList(roots);
Collections.sort(list, new Comparator<FilePath>() {
public int compare(FilePath file, FilePath file1) {
return file.getPath().compareTo(file1.getPath());
}
});
FilePath[] sortedRoots = list.toArray(new FilePath[list.size()]);
for (int i = 0; i < sortedRoots.length; i++) {
FilePath root = sortedRoots[i];
if (i == 0) {
result.add(root);
}
else {
FilePath prevRoot = result.isEmpty() ? null : result.get(result.size() - 1);
if ((prevRoot == null) || ! VfsUtil.isAncestor(prevRoot.getIOFile(), root.getIOFile(), false)){
result.add(root);
}
}
}
return result;
}
private void setText(final String text) {
if (myProgress == null) return;
myProgress.setText(text);
ProgressManager.checkCanceled();
}
private void setText2(final String text) {
if (myProgress == null) return;
myProgress.setText2(text);
ProgressManager.checkCanceled();
}
private void process(VirtualFile root) {
if (!myProjectRootManager.getFileIndex().isInContent(root)) return;
setText2(CvsVfsUtil.getPresentablePathFor(root));
myProcessedFiles++;
setFraction();
VirtualFile[] children = root.getChildren();
if (children == null) return;
CvsEnvironment parentEnv = myManager.getCvsConnectionSettingsFor(root);
if (!parentEnv.isValid()) return;
myManager.cacheCvsAdminInfoIn(root);
myRepositories.add(CvsVfsUtil.getFileFor(root));
for (VirtualFile child : children) {
if (!child.isDirectory()) continue;
if (!myProjectRootManager.getFileIndex().isInContent(child)) continue;
CvsEnvironment childEnv = myManager.getCvsConnectionSettingsFor(child);
if (childEnv == null || !childEnv.isValid()) continue;
if (!childEnv.equals(parentEnv)) {
myResult.add(child);
}
process(child);
}
}
private void setFraction() {
if (myProgress == null) return;
myProgress.setFraction((double)myProcessedFiles / (double)mySuitableFiles);
ProgressManager.checkCanceled();
}
public Collection<File> getDirectoriesToBeUpdated() {
return myRepositories;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2011 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.
@@ -46,18 +46,21 @@ import java.io.File;
public class UpdateOperation extends CvsOperationOnFiles {
private final UpdateSettings myUpdateSettings;
private final Project myProject;
private final ProjectLevelVcsManager myVcsManager;
private final CvsVcs2 myVcs;
public UpdateOperation(FilePath[] files, UpdateSettings updateSettings, Project project) {
myUpdateSettings = updateSettings;
myProject = project;
myVcsManager = ProjectLevelVcsManager.getInstance(project);
myVcs = CvsVcs2.getInstance(project);
addAllFiles(files);
}
public UpdateOperation(FilePath[] files, String branchName,
boolean makeNewFilesReadOnly, Project project) {
this(files, new UpdateByBranchUpdateSettings(branchName, makeNewFilesReadOnly), project);
}
public void addAllFiles(FilePath[] files) {
for (FilePath file : files) {
addFile(file.getIOFile());
@@ -74,17 +77,8 @@ public class UpdateOperation extends CvsOperationOnFiles {
return "update";
}
public UpdateOperation(UpdateSettings updateSettings, Project project) {
this(new FilePath[0], updateSettings, project);
}
public UpdateOperation(FilePath[] files, String branchName,
boolean makeNewFilesReadOnly, Project project) {
this(files, new UpdateByBranchUpdateSettings(branchName, makeNewFilesReadOnly), project);
}
protected Command createCommand(CvsRootProvider root, CvsExecutionEnvironment cvsExecutionEnvironment) {
UpdateCommand updateCommand = new UpdateCommand();
final UpdateCommand updateCommand = new UpdateCommand();
addFilesToCommand(root, updateCommand);
//updateCommand.setPruneDirectories(myUpdateSettings.getPruneEmptyDirectories());
updateCommand.setCleanCopy(myUpdateSettings.getCleanCopy());
@@ -103,7 +97,6 @@ public class UpdateOperation extends CvsOperationOnFiles {
return updateCommand;
}
public void modifyOptions(GlobalOptions options) {
super.modifyOptions(options);
options.setDoNoChanges(myUpdateSettings.getDontMakeAnyChanges());
@@ -141,7 +134,7 @@ public class UpdateOperation extends CvsOperationOnFiles {
if (ignoreFileFilterFromSuper.shouldBeIgnored(abstractFileObject, cvsFileSystem)) {
return true;
}
VirtualFile fileByIoFile = CvsVfsUtil.findFileByIoFile(cvsFileSystem.getLocalFileSystem().getFile(abstractFileObject));
final VirtualFile fileByIoFile = CvsVfsUtil.findFileByIoFile(cvsFileSystem.getLocalFileSystem().getFile(abstractFileObject));
return fileByIoFile != null && myVcsManager.getVcsFor(fileByIoFile) != myVcs;
}
};