blob: 887f0047811aefc21ca2d0b5b929abb8cee39e07 [file] [log] [blame]
/*
* Copyright 2000-2013 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 org.zmlx.hg4idea.repo;
import com.intellij.dvcs.DvcsUtil;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.util.Consumer;
import com.intellij.util.concurrency.QueueProcessor;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* Listens to .hg service files changes and updates {@link HgRepository} when needed.
*/
final class HgRepositoryUpdater implements Disposable, BulkFileListener {
@NotNull private final HgRepositoryFiles myRepositoryFiles;
@Nullable private final MessageBusConnection myMessageBusConnection;
@NotNull private final QueueProcessor<Object> myUpdateQueue;
@Nullable private final VirtualFile myBranchHeadsDir;
@Nullable private final LocalFileSystem.WatchRequest myWatchRequest;
@NotNull private final QueueProcessor<Object> myUpdateConfigQueue;
HgRepositoryUpdater(@NotNull final HgRepository repository) {
VirtualFile hgDir = repository.getHgDir();
myWatchRequest = LocalFileSystem.getInstance().addRootToWatch(hgDir.getPath(), true);
myRepositoryFiles = HgRepositoryFiles.getInstance(hgDir);
DvcsUtil.visitVcsDirVfs(hgDir, HgRepositoryFiles.getSubDirRelativePaths());
myBranchHeadsDir = VcsUtil.getVirtualFile(myRepositoryFiles.getBranchHeadsDirPath());
Project project = repository.getProject();
myUpdateQueue = new QueueProcessor<Object>(new DvcsUtil.Updater(repository), project.getDisposed());
myUpdateConfigQueue = new QueueProcessor<Object>(new Consumer<Object>() {
@Override
public void consume(Object dummy) {
repository.updateConfig();
}
}, project.getDisposed());
if (!project.isDisposed()) {
myMessageBusConnection = project.getMessageBus().connect();
myMessageBusConnection.subscribe(VirtualFileManager.VFS_CHANGES, this);
}
else {
myMessageBusConnection = null;
}
}
@Override
public void dispose() {
if (myWatchRequest != null) {
LocalFileSystem.getInstance().removeWatchedRoot(myWatchRequest);
}
if (myMessageBusConnection != null) {
myMessageBusConnection.disconnect();
}
}
@Override
public void before(@NotNull List<? extends VFileEvent> events) {
// everything is handled in #after()
}
@Override
public void after(@NotNull List<? extends VFileEvent> events) {
// which files in .hg were changed
boolean branchHeadsChanged = false;
boolean branchFileChanged = false;
boolean dirstateFileChanged = false;
boolean mergeFileChanged = false;
boolean rebaseFileChanged = false;
boolean bookmarksFileChanged = false;
boolean tagsFileChanged = false;
boolean localTagsFileChanged = false;
boolean currentBookmarkFileChanged = false;
boolean configHgrcChanged = false;
for (VFileEvent event : events) {
String filePath = event.getPath();
if (filePath == null) {
continue;
}
if (myRepositoryFiles.isbranchHeadsFile(filePath)) {
branchHeadsChanged = true;
}
else if (myRepositoryFiles.isBranchFile(filePath)) {
branchFileChanged = true;
DvcsUtil.ensureAllChildrenInVfs(myBranchHeadsDir);
}
else if (myRepositoryFiles.isDirstateFile(filePath)) {
dirstateFileChanged = true;
}
else if (myRepositoryFiles.isMergeFile(filePath)) {
mergeFileChanged = true;
}
else if (myRepositoryFiles.isRebaseFile(filePath)) {
rebaseFileChanged = true;
}
else if (myRepositoryFiles.isBookmarksFile(filePath)) {
bookmarksFileChanged = true;
}
else if (myRepositoryFiles.isTagsFile(filePath)) {
tagsFileChanged = true;
}
else if (myRepositoryFiles.isLocalTagsFile(filePath)) {
localTagsFileChanged = true;
}
else if (myRepositoryFiles.isCurrentBookmarksFile(filePath)) {
currentBookmarkFileChanged = true;
}
else if (myRepositoryFiles.isConfigHgrcFile(filePath)) {
configHgrcChanged = true;
}
}
if (branchHeadsChanged ||
branchFileChanged ||
dirstateFileChanged ||
mergeFileChanged ||
rebaseFileChanged ||
bookmarksFileChanged ||
currentBookmarkFileChanged ||
tagsFileChanged ||
localTagsFileChanged) {
myUpdateQueue.add(Void.TYPE);
}
if (configHgrcChanged) {
myUpdateConfigQueue.add(Void.TYPE);
}
}
}