blob: 8a465bb272a3e838e9918d54d9db7267e2234bb6 [file] [log] [blame]
/*
* Copyright 2000-2014 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.application;
import com.intellij.cvsSupport2.CvsUtil;
import com.intellij.cvsSupport2.CvsVcs2;
import com.intellij.lifecycle.PeriodicalTasksCloser;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.command.CommandEvent;
import com.intellij.openapi.command.CommandListener;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vfs.*;
import org.jetbrains.annotations.NotNull;
import java.io.File;
public class CvsStorageSupportingDeletionComponent extends CvsStorageComponent implements CommandListener {
private static final Logger LOG = Logger.getInstance("#" + CvsStorageSupportingDeletionComponent.class.getName());
private Project myProject;
private DeletedCVSDirectoryStorage myDeletedStorage;
private DeleteHandler myDeleteHandler = null;
private AddHandler myAddHandler = null;
private CvsFileOperationsHandler myFileOperationsHandler;
private int myCommandLevel = 0;
private boolean myAnotherProjectCommand = false;
static final Key<AbstractVcs> FILE_VCS = new Key<AbstractVcs>("File VCS");
public void commandStarted(CommandEvent event) {
myCommandLevel++;
if (myCommandLevel == 1) {
myAnotherProjectCommand = (event.getProject() != null) != (event.getProject() == myProject);
}
if (LOG.isDebugEnabled()) {
LOG.debug("Started" + event.getCommandName() + ", commandLevel: " + myCommandLevel);
}
}
public void beforeCommandFinished(CommandEvent event) {}
public void undoTransparentActionStarted() {}
public void undoTransparentActionFinished() {}
public void commandFinished(CommandEvent event) {
myCommandLevel--;
if (LOG.isDebugEnabled()) {
LOG.debug("Finished" + event.getCommandName() + ", commandLevel: " + myCommandLevel);
}
execute();
}
public void init(Project project, boolean sync) {
myProject = project;
initializeDeletedStorage();
VirtualFileManager.getInstance().addVirtualFileListener(this);
CvsEntriesManager.getInstance().registerAsVirtualFileListener();
CommandProcessor.getInstance().addCommandListener(this);
myFileOperationsHandler = new CvsFileOperationsHandler(project, this);
LocalFileSystem.getInstance().registerAuxiliaryFileOperationsHandler(myFileOperationsHandler);
myIsActive = true;
}
public void dispose() {
VirtualFileManager.getInstance().removeVirtualFileListener(this);
CvsEntriesManager.getInstance().unregisterAsVirtualFileListener();
CommandProcessor.getInstance().removeCommandListener(this);
LocalFileSystem.getInstance().unregisterAuxiliaryFileOperationsHandler(myFileOperationsHandler);
myFileOperationsHandler = null;
myIsActive = false;
myProject = null;
}
public void beforeFileDeletion(@NotNull VirtualFileEvent event) {}
public DeleteHandler getDeleteHandler() {
if (myDeleteHandler == null) {
myDeleteHandler = myDeletedStorage.createDeleteHandler(myProject, this);
}
return myDeleteHandler;
}
public void fileDeleted(@NotNull VirtualFileEvent event) {}
private boolean shouldProcessEvent(VirtualFileEvent event, boolean parentShouldBeUnderCvs) {
if (myAnotherProjectCommand) {
return false;
}
final VirtualFile file = event.getFile();
if (disabled(file) || event.isFromRefresh() || isStorageEvent(event) || !isUnderCvsManagedModuleRoot(file)) {
return false;
}
return !parentShouldBeUnderCvs || parentIsUnderCvs(file);
}
private static boolean isStorageEvent(VirtualFileEvent event) {
return event.getRequestor() instanceof DeletedCVSDirectoryStorage;
}
private static boolean parentIsUnderCvs(VirtualFile file) {
return CvsUtil.fileIsUnderCvs(file.getParent());
}
public void beforeFileMovement(@NotNull VirtualFileMoveEvent event) {}
public void fileMoved(@NotNull VirtualFileMoveEvent event) {
fileCreated(event);
}
private boolean processMoveOrRename() {
return myDeleteHandler != null;
}
private AbstractVcs getFileVcs(VirtualFile file) {
final AbstractVcs storedData = file.getUserData(FILE_VCS);
if (storedData != null) {
return storedData;
}
return ProjectLevelVcsManager.getInstance(myProject).getVcsFor(file);
}
private boolean isUnderCvsManagedModuleRoot(VirtualFile file) {
return getFileVcs(file) == CvsVcs2.getInstance(myProject);
}
private boolean disabled(VirtualFile file) {
return ProjectLevelVcsManager.getInstance(myProject).getVcsFor(file) != CvsVcs2.getInstance(myProject);
}
public void beforePropertyChange(@NotNull VirtualFilePropertyEvent event) {
if (!event.getPropertyName().equals(VirtualFile.PROP_NAME)) return;
if (!CvsUtil.fileIsUnderCvs(event.getFile())) return;
beforeFileDeletion(event);
}
public void propertyChanged(@NotNull VirtualFilePropertyEvent event) {
if (processMoveOrRename()) {
fileDeleted(event);
fileCreated(event);
}
}
public void fileCreated(@NotNull final VirtualFileEvent event) {
if (!shouldProcessEvent(event, false)) return;
final Project project = myProject;
if (project == null) return; // already disposed
final VirtualFile file = event.getFile();
if (myDeleteHandler != null) {
myDeleteHandler.removeDeletedRoot(file);
}
myDeletedStorage.checkNeedForPurge(VfsUtil.virtualToIoFile(file));
deleteIfAdminDirCreated(file);
getAddHandler().addFile(file);
execute();
}
public AddHandler getAddHandler() {
if (myAddHandler == null) {
myAddHandler = new AddHandler(myProject, this);
}
return myAddHandler;
}
private void execute() {
if (myCommandLevel > 0) {
return;
}
//myDeletedStorage.sync();
if (!myAnotherProjectCommand) {
if (myDeleteHandler != null) {
myDeleteHandler.execute();
}
if (myAddHandler != null) {
myAddHandler.execute();
}
}
myAnotherProjectCommand = false;
myDeleteHandler = null;
myAddHandler = null;
}
private void initializeDeletedStorage() {
final File storageRoot = getStorageRoot();
storageRoot.mkdirs();
myDeletedStorage = new DeletedCVSDirectoryStorage(storageRoot);
}
private static File getStorageRoot() {
//noinspection HardCodedStringLiteral
return new File(PathManager.getSystemPath(), "CVS-TO-DELETE");
}
public void sync() {
//myDeletedStorage.sync();
}
public static CvsStorageComponent getInstance(Project project) {
return PeriodicalTasksCloser.getInstance().safeGetService(project, CvsStorageComponent.class);
}
public void deleteIfAdminDirCreated(VirtualFile addedFile) {
myDeletedStorage.deleteIfAdminDirCreated(addedFile);
}
}