| /* |
| * 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); |
| } |
| } |