1 package com
.intellij
.util
.indexing
;
3 import com
.intellij
.ide
.startup
.BackgroundableCacheUpdater
;
4 import com
.intellij
.ide
.startup
.FileContent
;
5 import com
.intellij
.openapi
.application
.ApplicationManager
;
6 import com
.intellij
.openapi
.diagnostic
.Logger
;
7 import com
.intellij
.openapi
.extensions
.Extensions
;
8 import com
.intellij
.openapi
.module
.Module
;
9 import com
.intellij
.openapi
.module
.ModuleManager
;
10 import com
.intellij
.openapi
.progress
.ProgressIndicator
;
11 import com
.intellij
.openapi
.progress
.ProgressManager
;
12 import com
.intellij
.openapi
.project
.DumbServiceImpl
;
13 import com
.intellij
.openapi
.project
.Project
;
14 import com
.intellij
.openapi
.roots
.*;
15 import com
.intellij
.openapi
.ui
.Messages
;
16 import com
.intellij
.openapi
.util
.Key
;
17 import com
.intellij
.openapi
.util
.registry
.Registry
;
18 import com
.intellij
.openapi
.util
.registry
.RegistryValue
;
19 import com
.intellij
.openapi
.vfs
.VirtualFile
;
20 import com
.intellij
.openapi
.vfs
.VirtualFileManager
;
21 import com
.intellij
.util
.containers
.HashSet
;
22 import com
.intellij
.util
.ui
.UIUtil
;
23 import org
.jetbrains
.annotations
.Nullable
;
25 import java
.util
.Collection
;
26 import java
.util
.Iterator
;
27 import java
.util
.List
;
31 * @author Eugene Zhuravlev
34 public class UnindexedFilesUpdater
implements BackgroundableCacheUpdater
{
35 private static final Logger LOG
= Logger
.getInstance("#com.intellij.util.indexing.UnindexedFilesUpdater");
36 private static final Key
<Boolean
> DONT_INDEX_AGAIN_KEY
= Key
.create("DONT_INDEX_AGAIN_KEY");
37 private final FileBasedIndex myIndex
;
38 private final Project myProject
;
39 private final ProjectRootManager myRootManager
;
41 public UnindexedFilesUpdater(final Project project
, final ProjectRootManager rootManager
, FileBasedIndex index
) {
44 myRootManager
= rootManager
;
47 public VirtualFile
[] queryNeededFiles() {
48 CollectingContentIterator finder
= myIndex
.createContentIterator();
49 iterateIndexableFiles(finder
);
50 final List
<VirtualFile
> files
= finder
.getFiles();
51 for (Iterator
<VirtualFile
> virtualFileIterator
= files
.iterator(); virtualFileIterator
.hasNext();) {
52 VirtualFile file
= virtualFileIterator
.next();
53 if (file
.getUserData(DONT_INDEX_AGAIN_KEY
) != null) {
54 virtualFileIterator
.remove();
57 return files
.toArray(new VirtualFile
[files
.size()]);
60 public boolean initiallyBackgrounded() {
61 if (ApplicationManager
.getApplication().isCommandLine() || ApplicationManager
.getApplication().isUnitTestMode()) return false;
62 return Registry
.get(DumbServiceImpl
.FILE_INDEX_BACKGROUND
).asBoolean();
65 public boolean canBeSentToBackground(Collection
<VirtualFile
> remaining
) {
66 if (remaining
.size() < 42) {
70 final RegistryValue value
= Registry
.get(DumbServiceImpl
.FILE_INDEX_BACKGROUND
);
71 if (!value
.asBoolean()) {
72 if (Messages
.showDialog(myProject
, "<html>" +
73 "Sending indices update to background allows you to immediately use the most<br>" +
74 "basic editing capabilities of IntelliJ IDEA, plus version control operations.<p>" +
75 "However, many advanced functions such as 'Go to Class', advanced error highlighting,<br>" +
76 "refactorings and some others <b>will not be available</b> until indexing is complete.<p>" +
77 "Do you still want to send indexing to background?</html>", "Background Indexing",
78 new String
[]{"Yes", "No"}, 1, UIUtil
.getInformationIcon()) != 0) {
83 value
.setValue("true");
88 public void backgrounded(final Collection
<VirtualFile
> remaining
) {
89 new BackgroundCacheUpdaterRunner(myProject
, remaining
).processFiles(this);
92 public void processFile(final FileContent fileContent
) {
93 fileContent
.putUserData(FileBasedIndex
.PROJECT
, myProject
);
94 myIndex
.indexFileContent(fileContent
);
95 IndexingStamp
.flushCache();
98 private void iterateIndexableFiles(final ContentIterator processor
) {
99 final ProjectFileIndex projectFileIndex
= myRootManager
.getFileIndex();
100 // iterate associated libraries
101 final Module
[] modules
= ModuleManager
.getInstance(myProject
).getModules();
102 // iterate project content
103 projectFileIndex
.iterateContent(processor
);
105 ProgressIndicator indicator
= ProgressManager
.getInstance().getProgressIndicator();
107 Set
<VirtualFile
> visitedRoots
= new HashSet
<VirtualFile
>();
108 for (IndexedRootsProvider provider
: Extensions
.getExtensions(IndexedRootsProvider
.EP_NAME
)) {
109 //important not to depend on project here, to support per-project background reindex
110 // each client gives a project to FileBasedIndex
111 final Set
<String
> rootsToIndex
= provider
.getRootsToIndex();
112 for (String url
: rootsToIndex
) {
113 final VirtualFile root
= VirtualFileManager
.getInstance().findFileByUrl(url
);
114 if (visitedRoots
.add(root
)) {
115 iterateRecursively(root
, processor
, indicator
);
119 for (Module module
: modules
) {
120 OrderEntry
[] orderEntries
= ModuleRootManager
.getInstance(module
).getOrderEntries();
121 for (OrderEntry orderEntry
: orderEntries
) {
122 if (orderEntry
instanceof LibraryOrderEntry
|| orderEntry
instanceof JdkOrderEntry
) {
123 final VirtualFile
[] libSources
= orderEntry
.getFiles(OrderRootType
.SOURCES
);
124 final VirtualFile
[] libClasses
= orderEntry
.getFiles(OrderRootType
.CLASSES
);
125 for (VirtualFile
[] roots
: new VirtualFile
[][]{libSources
, libClasses
}) {
126 for (VirtualFile root
: roots
) {
127 if (visitedRoots
.add(root
)) {
128 iterateRecursively(root
, processor
, indicator
);
137 private static void iterateRecursively(@Nullable final VirtualFile root
, final ContentIterator processor
, ProgressIndicator indicator
) {
139 if (indicator
!= null) {
140 indicator
.setText("Scanning files to index");
141 indicator
.setText2(root
.getPresentableUrl());
144 if (root
.isDirectory()) {
145 for (VirtualFile file
: root
.getChildren()) {
146 if (file
.isDirectory()) {
147 iterateRecursively(file
, processor
, indicator
);
150 processor
.processFile(file
);
154 processor
.processFile(root
);
159 public void updatingDone() {
160 myIndex
.flushCaches();
163 public void canceled() {
164 myIndex
.flushCaches();