ExcludedFileIndex -> FileIndexFacade; use it in PsiClassImplUtil
[idea/community.git] / platform / vcs-impl / src / com / intellij / openapi / vcs / changes / UpdatingChangeListBuilder.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 package com.intellij.openapi.vcs.changes;
17
18 import com.intellij.lifecycle.PeriodicalTasksCloser;
19 import com.intellij.openapi.application.ApplicationManager;
20 import com.intellij.openapi.diagnostic.Logger;
21 import com.intellij.openapi.fileTypes.FileTypeManager;
22 import com.intellij.openapi.roots.FileIndexFacade;
23 import com.intellij.openapi.util.Getter;
24 import com.intellij.openapi.vcs.FilePath;
25 import com.intellij.openapi.vcs.FilePathImpl;
26 import com.intellij.openapi.vcs.VcsKey;
27 import com.intellij.openapi.vfs.VirtualFile;
28 import org.jetbrains.annotations.Nullable;
29
30 class UpdatingChangeListBuilder implements ChangelistBuilder {
31   private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.UpdatingChangeListBuilder");
32   private final ChangeListWorker myChangeListWorker;
33   private final FileHolderComposite myComposite;
34   // todo +-
35   private final Getter<Boolean> myDisposedGetter;
36   private VcsDirtyScope myScope;
37   private FoldersCutDownWorker myFoldersCutDownWorker;
38   private final IgnoredFilesComponent myIgnoredFilesComponent;
39   private final FileIndexFacade myIndex;
40   private final ChangeListManagerGate myGate;
41
42   UpdatingChangeListBuilder(final ChangeListWorker changeListWorker,
43                             final FileHolderComposite composite,
44                             final Getter<Boolean> disposedGetter,
45                             final IgnoredFilesComponent ignoredFilesComponent, final ChangeListManagerGate gate) {
46     myChangeListWorker = changeListWorker;
47     myComposite = composite;
48     myDisposedGetter = disposedGetter;
49     myIgnoredFilesComponent = ignoredFilesComponent;
50     myGate = gate;
51     myIndex = PeriodicalTasksCloser.getInstance().safeGetService(changeListWorker.getProject(), FileIndexFacade.class);
52   }
53
54   private void checkIfDisposed() {
55     if (myDisposedGetter.get()) throw new ChangeListManagerImpl.DisposedException();
56   }
57
58   public void setCurrent(final VcsDirtyScope scope, final FoldersCutDownWorker foldersWorker) {
59     myScope = scope;
60     myFoldersCutDownWorker = foldersWorker;
61   }
62
63   public void processChange(final Change change, VcsKey vcsKey) {
64     processChangeInList( change, (ChangeList) null, vcsKey);
65   }
66
67   public void processChangeInList(final Change change, @Nullable final ChangeList changeList, final VcsKey vcsKey) {
68     checkIfDisposed();
69
70     LOG.debug("[processChangeInList-1] entering, cl name: " + ((changeList == null) ? null: changeList.getName()) +
71       " change: " + ChangesUtil.getFilePath(change).getPath());
72     final String fileName = ChangesUtil.getFilePath(change).getName();
73     if (FileTypeManager.getInstance().isFileIgnored(fileName)) {
74       LOG.debug("[processChangeInList-1] file type ignored");
75       return;
76     }
77
78     ApplicationManager.getApplication().runReadAction(new Runnable() {
79       public void run() {
80         if (ChangeListManagerImpl.isUnder(change, myScope)) {
81           if (changeList != null) {
82             LOG.debug("[processChangeInList-1] to add change to cl");
83             myChangeListWorker.addChangeToList(changeList.getName(), change, vcsKey);
84           } else {
85             LOG.debug("[processChangeInList-1] to add to corresponding list");
86             myChangeListWorker.addChangeToCorrespondingList(change, vcsKey);
87           }
88         } else {
89           LOG.debug("[processChangeInList-1] not under scope");
90         }
91       }
92     });
93   }
94
95   public void processChangeInList(final Change change, final String changeListName, VcsKey vcsKey) {
96     checkIfDisposed();
97
98     LocalChangeList list = null;
99     if (changeListName != null) {
100       list = myChangeListWorker.getCopyByName(changeListName);
101       if (list == null) {
102         list = myGate.addChangeList(changeListName, null);
103       }
104     }
105     processChangeInList(change, list, vcsKey);
106   }
107
108   private boolean isExcluded(final VirtualFile file) {
109     return myIndex.isExcludedFile(file);
110   }
111
112   public void processUnversionedFile(final VirtualFile file) {
113     if (file == null) return;
114     checkIfDisposed();
115     if (isExcluded(file)) return;
116     if (myScope.belongsTo(new FilePathImpl(file))) {
117       if (myIgnoredFilesComponent.isIgnoredFile(file)) {
118         myComposite.getIgnoredFileHolder().addFile(file);
119       } else if (myComposite.getIgnoredFileHolder().containsFile(file)) {
120         // does not need to add: parent dir is already added
121       }
122       else {
123         myComposite.getVFHolder(FileHolder.HolderType.UNVERSIONED).addFile(file);
124       }
125       // if a file was previously marked as switched through recursion, remove it from switched list
126       myChangeListWorker.removeSwitched(file);
127     }
128   }
129
130   public void processLocallyDeletedFile(final FilePath file) {
131     processLocallyDeletedFile(new LocallyDeletedChange(file));
132   }
133
134   public void processLocallyDeletedFile(LocallyDeletedChange locallyDeletedChange) {
135     checkIfDisposed();
136     final FilePath file = locallyDeletedChange.getPath();
137     if (FileTypeManager.getInstance().isFileIgnored(file.getName())) return;
138     if (myScope.belongsTo(file)) {
139       myChangeListWorker.addLocallyDeleted(locallyDeletedChange);
140     }
141   }
142
143   public void processModifiedWithoutCheckout(final VirtualFile file) {
144     if (file == null) return;
145     checkIfDisposed();
146     if (isExcluded(file)) return;
147     if (myScope.belongsTo(new FilePathImpl(file))) {
148       myComposite.getVFHolder(FileHolder.HolderType.MODIFIED_WITHOUT_EDITING).addFile(file);
149     }
150   }
151
152   public void processIgnoredFile(final VirtualFile file) {
153     if (file == null) return;
154     checkIfDisposed();
155     if (isExcluded(file)) return;
156     if (myScope.belongsTo(new FilePathImpl(file))) {
157       myComposite.getIgnoredFileHolder().addFile(file);
158     }
159   }
160
161   public void processLockedFolder(final VirtualFile file) {
162     if (file == null) return;
163     checkIfDisposed();
164     if (myScope.belongsTo(new FilePathImpl(file))) {
165       if (myFoldersCutDownWorker.addCurrent(file)) {
166         myComposite.getVFHolder(FileHolder.HolderType.LOCKED).addFile(file);
167       }
168     }
169   }
170
171   public void processLogicallyLockedFolder(VirtualFile file, LogicalLock logicalLock) {
172     if (file == null) return;
173     checkIfDisposed();
174     if (myScope.belongsTo(new FilePathImpl(file))) {
175       ((LogicallyLockedHolder) myComposite.get(FileHolder.HolderType.LOGICALLY_LOCKED)).add(file, logicalLock);
176     }
177   }
178
179   public void processSwitchedFile(final VirtualFile file, final String branch, final boolean recursive) {
180     if (file == null) return;
181     checkIfDisposed();
182     if (isExcluded(file)) return;
183     if (myScope.belongsTo(new FilePathImpl(file))) {
184       myChangeListWorker.addSwitched(file, branch, recursive);
185     }
186   }
187
188   public void processRootSwitch(VirtualFile file, String branch) {
189     if (file == null) return;
190     checkIfDisposed();
191     if (myScope.belongsTo(new FilePathImpl(file))) {
192       ((SwitchedFileHolder) myComposite.get(FileHolder.HolderType.ROOT_SWITCH)).addFile(file, branch, false);
193     }
194   }
195
196   public boolean reportChangesOutsideProject() {
197     return false;
198   }
199 }