package com.intellij.javascript.flex.mxml.schema; import com.intellij.ProjectTopics; import com.intellij.openapi.components.AbstractProjectComponent; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModuleRootEvent; import com.intellij.openapi.roots.ModuleRootListener; import gnu.trove.THashMap; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; /** * @author Maxim.Mossienko */ public class CodeContextHolder extends AbstractProjectComponent { private final Set<Module> myModulesWithSdkComponentsHandled = new HashSet<>(); private final Map<String, Map<Module, CodeContext>> myStandardContexts = new HashMap<>(); private final Map<String, Map<Module, CodeContext>> myNSToCodeContextMap = new THashMap<>(); static final CodeContext EMPTY = new CodeContext(null, null); public CodeContextHolder(Project project) { super(project); project.getMessageBus().connect().subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() { @Override public void rootsChanged(final ModuleRootEvent event) { synchronized (CodeContextHolder.this) { myNSToCodeContextMap.clear(); myStandardContexts.clear(); myModulesWithSdkComponentsHandled.clear(); } } }); } @Override @NonNls @NotNull public String getComponentName() { return "CodeContextHolder"; } @Nullable public synchronized CodeContext getCodeContext(@NotNull final String namespace, @NotNull final Module module) { final Map<Module, CodeContext> map = myNSToCodeContextMap.get(namespace); if (map != null) return map.get(module); return null; } public synchronized void putCodeContext(@NotNull final String namespace, @NotNull final Module module, @NotNull final CodeContext codeContext) { Map<Module, CodeContext> map = myNSToCodeContextMap.get(namespace); if (map == null) { map = new THashMap<>(); myNSToCodeContextMap.put(namespace, map); } map.put(module, codeContext); } public synchronized void clearCodeContext(@NotNull final String namespace, @NotNull final Module module) { Map<Module, CodeContext> map = myNSToCodeContextMap.get(namespace); if (map != null) { map.remove(module); } } public static CodeContextHolder getInstance(@NotNull Project project) { return project.getComponent(CodeContextHolder.class); } @Nullable public synchronized CodeContext getStandardContext(final String namespace, final Module module) { final Map<Module, CodeContext> map = myStandardContexts.get(namespace); return map == null ? null : map.get(module); } public synchronized Collection<String> getNamespaces(final Module module) { final List<String> result = new ArrayList<>(); for (final Map.Entry<String, Map<Module, CodeContext>> entry : myStandardContexts.entrySet()) { if (entry.getValue().containsKey(module)) { result.add(entry.getKey()); } } for (final Map.Entry<String, Map<Module, CodeContext>> entry : myNSToCodeContextMap.entrySet()) { if (entry.getValue().containsKey(module)) { result.add(entry.getKey()); } } return result; } synchronized void putStandardContext(final String namespace, final Module module, final CodeContext codeContext) { Map<Module, CodeContext> map = myStandardContexts.get(namespace); if (map == null) { map = new HashMap<>(); myStandardContexts.put(namespace, map); } map.put(module, codeContext); } synchronized boolean areSdkComponentsHandledForModule(final Module module) { return myModulesWithSdkComponentsHandled.contains(module); } synchronized boolean setSdkComponentsHandledForModule(final Module module) { return myModulesWithSdkComponentsHandled.add(module); } }