[project model api] annotate classes and interfaces from project model API as NonExte...
[idea/community.git] / platform / projectModel-api / src / com / intellij / openapi / project / ProjectLocator.java
1 // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2
3 /*
4  * @author max
5  */
6 package com.intellij.openapi.project;
7
8 import com.intellij.openapi.application.AccessToken;
9 import com.intellij.openapi.application.ApplicationManager;
10 import com.intellij.openapi.application.CachedSingletonsRegistry;
11 import com.intellij.openapi.vfs.VirtualFile;
12 import org.jetbrains.annotations.ApiStatus;
13 import org.jetbrains.annotations.NotNull;
14 import org.jetbrains.annotations.Nullable;
15
16 import java.util.Collection;
17 import java.util.HashMap;
18 import java.util.Map;
19
20 @ApiStatus.NonExtendable
21 public abstract class ProjectLocator {
22   // called very often by StubUpdatingIndex
23   private static ProjectLocator ourInstance = CachedSingletonsRegistry.markCachedField(ProjectLocator.class);
24
25   private static final ThreadLocal<Map<VirtualFile, Project>> ourPreferredProjects = ThreadLocal.withInitial(() -> new HashMap<>());
26
27   public static ProjectLocator getInstance() {
28     ProjectLocator result = ourInstance;
29     if (result == null) {
30       result = ApplicationManager.getApplication().getService(ProjectLocator.class);
31       ourInstance = result;
32     }
33     return result;
34   }
35
36   /**
37    * Returns an open project which contains the given file.
38    * This is a guess-method, so if several projects contain the file, only one will be returned.
39    * Also a project may be returned though it doesn't contain the file for sure (see implementations).
40    * @param file file to be located in projects.
41    * @return project which probably contains the file, or null if couldn't guess (for example, there are no open projects).
42    */
43   @Nullable
44   public abstract Project guessProjectForFile(@Nullable VirtualFile file);
45
46   /**
47   * Gets all open projects containing the given file.
48   * If none does, an empty list is returned.
49   * @param file file to be located in projects.
50   * @return list of open projects containing this file.
51   */
52   @NotNull
53   public abstract Collection<Project> getProjectsForFile(@NotNull VirtualFile file);
54
55   @NotNull
56   public static AccessToken runWithPreferredProject(@NotNull VirtualFile file, @NotNull Project preferredProject) {
57     Map<VirtualFile, Project> local = ourPreferredProjects.get();
58     local.put(file, preferredProject);
59     return new AccessToken() {
60       @Override
61       public void finish() {
62         local.remove(file);
63       }
64     };
65   }
66
67   @Nullable
68   static Project getPreferredProject(@NotNull VirtualFile file) {
69     return ourPreferredProjects.get().get(file);
70   }
71 }