ExcludedFileIndex -> FileIndexFacade; use it in PsiClassImplUtil
[idea/community.git] / platform / lang-impl / src / com / intellij / openapi / vcs / impl / ModuleDefaultVcsRootPolicy.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.intellij.openapi.vcs.impl;
18
19 import com.intellij.lifecycle.PeriodicalTasksCloser;
20 import com.intellij.openapi.application.ApplicationManager;
21 import com.intellij.openapi.components.StorageScheme;
22 import com.intellij.openapi.module.Module;
23 import com.intellij.openapi.module.ModuleManager;
24 import com.intellij.openapi.module.ModuleUtil;
25 import com.intellij.openapi.project.Project;
26 import com.intellij.openapi.project.ex.ProjectEx;
27 import com.intellij.openapi.roots.FileIndexFacade;
28 import com.intellij.openapi.roots.ModuleRootManager;
29 import com.intellij.openapi.roots.ProjectRootManager;
30 import com.intellij.openapi.util.Computable;
31 import com.intellij.openapi.vcs.*;
32 import com.intellij.openapi.vcs.changes.DirtBuilder;
33 import com.intellij.openapi.vcs.changes.FilePathUnderVcs;
34 import com.intellij.openapi.vcs.changes.VcsGuess;
35 import com.intellij.openapi.vcs.ex.ProjectLevelVcsManagerEx;
36 import com.intellij.openapi.vcs.impl.projectlevelman.NewMappings;
37 import com.intellij.openapi.vfs.VfsUtil;
38 import com.intellij.openapi.vfs.VirtualFile;
39 import org.jetbrains.annotations.NotNull;
40 import org.jetbrains.annotations.Nullable;
41
42 import java.util.List;
43
44 /**
45  * @author yole
46  */
47 public class ModuleDefaultVcsRootPolicy extends DefaultVcsRootPolicy {
48   private final Project myProject;
49   private final VirtualFile myBaseDir;
50   private final ModuleManager myModuleManager;
51
52   public ModuleDefaultVcsRootPolicy(final Project project) {
53     myProject = project;
54     myBaseDir = project.getBaseDir();
55     myModuleManager = ModuleManager.getInstance(myProject);
56   }
57
58   public void addDefaultVcsRoots(final NewMappings mappingList, @NotNull final String vcsName, final List<VirtualFile> result) {
59     final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject);
60     if (myBaseDir != null && vcsName.equals(mappingList.getVcsFor(myBaseDir))) {
61       final AbstractVcs vcsFor = vcsManager.getVcsFor(myBaseDir);
62       if (vcsFor != null && vcsName.equals(vcsFor.getName())) {
63         result.add(myBaseDir);
64       }
65     }
66     final StorageScheme storageScheme = ((ProjectEx) myProject).getStateStore().getStorageScheme();
67     if (StorageScheme.DIRECTORY_BASED.equals(storageScheme) && (myBaseDir != null)) {
68       final VirtualFile ideaDir = myBaseDir.findChild(Project.DIRECTORY_STORE_FOLDER);
69       if (ideaDir != null && ideaDir.isValid() && ideaDir.isDirectory()) {
70         final AbstractVcs vcsFor = vcsManager.getVcsFor(ideaDir);
71         if (vcsFor != null && vcsName.equals(vcsFor.getName())) {
72           result.add(ideaDir);
73         }
74       }
75     }
76     // assertion for read access inside
77     final Module[] modules = ApplicationManager.getApplication().runReadAction(new Computable<Module[]>() {
78       public Module[] compute() {
79         return myModuleManager.getModules();
80       }
81     });
82     for(Module module: modules) {
83       final VirtualFile[] files = ModuleRootManager.getInstance(module).getContentRoots();
84       for(VirtualFile file: files) {
85         // if we're currently processing moduleAdded notification, getModuleForFile() will return null, so we pass the module
86         // explicitly (we know it anyway)
87         VcsDirectoryMapping mapping = mappingList.getMappingFor(file, module);
88         final String mappingVcs = mapping != null ? mapping.getVcs() : null;
89         if (vcsName.equals(mappingVcs)) {
90           result.add(file);
91         }
92       }
93     }
94   }
95
96   public boolean matchesDefaultMapping(final VirtualFile file, final Object matchContext) {
97     if (matchContext != null) {
98       return true;
99     }
100     if (myBaseDir != null && VfsUtil.isAncestor(myBaseDir, file, false)) {
101       return !ProjectRootManager.getInstance(myProject).getFileIndex().isIgnored(file);
102     }
103     return false;
104   }
105
106   @Nullable
107   public Object getMatchContext(final VirtualFile file) {
108     return ModuleUtil.findModuleForFile(file, myProject);
109   }
110
111   @Nullable
112   public VirtualFile getVcsRootFor(final VirtualFile file) {
113     if (myBaseDir != null && PeriodicalTasksCloser.getInstance().safeGetService(myProject, FileIndexFacade.class)
114       .isValidAncestor(myBaseDir, file)) {
115       return myBaseDir;
116     }
117     final VirtualFile contentRoot = ProjectRootManager.getInstance(myProject).getFileIndex().getContentRootForFile(file);
118     if (contentRoot != null) {
119       return contentRoot;
120     }
121     final StorageScheme storageScheme = ((ProjectEx) myProject).getStateStore().getStorageScheme();
122     if (StorageScheme.DIRECTORY_BASED.equals(storageScheme) && (myBaseDir != null)) {
123       final VirtualFile ideaDir = myBaseDir.findChild(Project.DIRECTORY_STORE_FOLDER);
124       if (ideaDir != null && ideaDir.isValid() && ideaDir.isDirectory()) {
125         if (VfsUtil.isAncestor(ideaDir, file, false)) {
126           return ideaDir;
127         }
128       }
129     }
130     return null;
131   }
132
133   public void markDefaultRootsDirty(final DirtBuilder builder, final VcsGuess vcsGuess) {
134     final Module[] modules = myModuleManager.getModules();
135     final StorageScheme storageScheme = ((ProjectEx) myProject).getStateStore().getStorageScheme();
136     if (StorageScheme.DIRECTORY_BASED.equals(storageScheme)) {
137       final FilePathImpl fp = new FilePathImpl(myBaseDir, Project.DIRECTORY_STORE_FOLDER, true);
138       final AbstractVcs vcs = vcsGuess.getVcsForDirty(fp);
139       if (vcs != null) {
140         builder.addDirtyDirRecursively(new FilePathUnderVcs(fp, vcs));
141       }
142     }
143
144     for(Module module: modules) {
145       final VirtualFile[] files = ModuleRootManager.getInstance(module).getContentRoots();
146       for(VirtualFile file: files) {
147         final AbstractVcs vcs = vcsGuess.getVcsForDirty(file);
148         if (vcs != null) {
149           builder.addDirtyDirRecursively(new VcsRoot(vcs, file));
150         }
151       }
152     }
153
154     final ProjectLevelVcsManager plVcsManager = ProjectLevelVcsManager.getInstance(myProject);
155     final String defaultMapping = ((ProjectLevelVcsManagerEx)plVcsManager).haveDefaultMapping();
156     final boolean haveDefaultMapping = (defaultMapping != null) && (defaultMapping.length() > 0);
157     if (haveDefaultMapping && (myBaseDir != null)) {
158       final AbstractVcs vcs = vcsGuess.getVcsForDirty(myBaseDir);
159       if (vcs != null) {
160         builder.addDirtyFile(new VcsRoot(vcs, myBaseDir));
161       }
162     }
163
164     final VcsRoot[] vcsRoots = plVcsManager.getAllVcsRoots();
165     for (VcsRoot root : vcsRoots) {
166       //if (! root.path.equals(baseDir)) {
167         builder.addDirtyDirRecursively(root);
168       //}
169     }
170   }
171 }