IndexableSetContributor: log.error if a provider returns a set containing null; add...
[idea/community.git] / platform / indexing-api / src / com / intellij / util / indexing / IndexableSetContributor.java
1 /*
2  * Copyright 2000-2015 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.util.indexing;
17
18 import com.intellij.openapi.diagnostic.Logger;
19 import com.intellij.openapi.project.Project;
20 import com.intellij.openapi.vfs.VirtualFile;
21 import com.intellij.openapi.vfs.VirtualFileManager;
22 import com.intellij.util.NotNullFunction;
23 import com.intellij.util.containers.ContainerUtil;
24 import org.jetbrains.annotations.NotNull;
25
26 import java.util.Collections;
27 import java.util.HashSet;
28 import java.util.Set;
29
30 /**
31  * @author peter
32  */
33 public abstract class IndexableSetContributor implements IndexedRootsProvider {
34   
35   protected static final Set<VirtualFile> EMPTY_FILE_SET = Collections.emptySet();
36   private static final Logger LOG = Logger.getInstance(IndexableSetContributor.class);
37
38   @Override
39   public final Set<String> getRootsToIndex() {
40     return ContainerUtil.map2Set(getAdditionalRootsToIndex(), new NotNullFunction<VirtualFile, String>() {
41       @NotNull
42       @Override
43       public String fun(VirtualFile virtualFile) {
44         return virtualFile.getUrl();
45       }
46     });
47   }
48
49   @NotNull
50   public static Set<VirtualFile> getProjectRootsToIndex(IndexedRootsProvider provider, Project project) {
51     if (provider instanceof IndexableSetContributor) {
52       IndexableSetContributor contributor = (IndexableSetContributor)provider;
53       Set<VirtualFile> roots = contributor.getAdditionalProjectRootsToIndex(project);
54       return filterOutNulls(contributor, "getAdditionalProjectRootsToIndex(Project)", roots);
55     }
56     return EMPTY_FILE_SET;
57   }
58
59   @NotNull
60   public static Set<VirtualFile> getRootsToIndex(IndexedRootsProvider provider) {
61     if (provider instanceof IndexableSetContributor) {
62       IndexableSetContributor contributor = (IndexableSetContributor)provider;
63       Set<VirtualFile> roots = contributor.getAdditionalRootsToIndex();
64       return filterOutNulls(contributor, "getAdditionalRootsToIndex()", roots);
65     }
66
67     final HashSet<VirtualFile> result = new HashSet<VirtualFile>();
68     for (String url : provider.getRootsToIndex()) {
69       ContainerUtil.addIfNotNull(VirtualFileManager.getInstance().findFileByUrl(url), result);
70     }
71
72     return result;
73   }
74
75   /**
76    * @return an additional project-dependent set of {@link VirtualFile} instances to index,
77    *         the returned set should not contain nulls
78    */
79   @NotNull
80   public Set<VirtualFile> getAdditionalProjectRootsToIndex(@NotNull Project project) {
81     return EMPTY_FILE_SET;
82   }
83
84   /**
85    * @return an additional project-independent set of {@link VirtualFile} instances to index,
86    *         the returned set should not contain nulls
87    */
88   @NotNull
89   public abstract Set<VirtualFile> getAdditionalRootsToIndex();
90
91   @NotNull
92   private static Set<VirtualFile> filterOutNulls(@NotNull IndexableSetContributor contributor,
93                                                  @NotNull String methodInfo,
94                                                  @NotNull Set<VirtualFile> roots) {
95     for (VirtualFile root : roots) {
96       if (root == null) {
97         LOG.error("Please fix " + contributor.getClass().getName() + "#" + methodInfo + ".\n" +
98                   "The returned set is not expected to contain nulls, but it is " + roots);
99         Set<VirtualFile> result = ContainerUtil.newHashSet(roots.size());
100         ContainerUtil.addAllNotNull(result, roots);
101         return result;
102       }
103     }
104     return roots;
105   }
106 }