| /* |
| * Copyright 2000-2014 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.intellij.plugins.intelliLang.inject.java; |
| |
| import com.intellij.openapi.components.ServiceManager; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.openapi.util.text.StringUtil; |
| import com.intellij.patterns.ElementPattern; |
| import com.intellij.psi.*; |
| import com.intellij.psi.impl.java.stubs.index.JavaAnnotationIndex; |
| import com.intellij.psi.search.GlobalSearchScope; |
| import com.intellij.psi.util.CachedValue; |
| import com.intellij.psi.util.CachedValueProvider; |
| import com.intellij.psi.util.CachedValuesManager; |
| import com.intellij.psi.util.PsiModificationTracker; |
| import com.intellij.util.PatternValuesIndex; |
| import com.intellij.util.containers.ContainerUtil; |
| import gnu.trove.THashMap; |
| import gnu.trove.THashSet; |
| import org.intellij.plugins.intelliLang.Configuration; |
| import org.intellij.plugins.intelliLang.inject.config.BaseInjection; |
| import org.intellij.plugins.intelliLang.inject.config.InjectionPlace; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Map; |
| import java.util.Set; |
| |
| /** |
| * Created by Max Medvedev on 22/03/14 |
| */ |
| public class InjectionCache { |
| private final CachedValue<Collection<String>> myAnnoIndex; |
| private final CachedValue<Collection<String>> myXmlIndex; |
| |
| public InjectionCache(final Project project, final Configuration configuration) { |
| |
| myXmlIndex = CachedValuesManager.getManager(project).createCachedValue(new CachedValueProvider<Collection<String>>() { |
| public Result<Collection<String>> compute() { |
| final Map<ElementPattern<?>, BaseInjection> map = new THashMap<ElementPattern<?>, BaseInjection>(); |
| for (BaseInjection injection : configuration.getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID)) { |
| for (InjectionPlace place : injection.getInjectionPlaces()) { |
| if (!place.isEnabled() || place.getElementPattern() == null) continue; |
| map.put(place.getElementPattern(), injection); |
| } |
| } |
| final Set<String> stringSet = PatternValuesIndex.buildStringIndex(map.keySet()); |
| return new Result<Collection<String>>(stringSet, configuration); |
| } |
| }, false); |
| |
| myAnnoIndex = CachedValuesManager.getManager(project).createCachedValue(new CachedValueProvider<Collection<String>>() { |
| public Result<Collection<String>> compute() { |
| final String annotationClass = configuration.getAdvancedConfiguration().getLanguageAnnotationClass(); |
| final Collection<String> result = new THashSet<String>(); |
| final ArrayList<String> annoClasses = new ArrayList<String>(3); |
| annoClasses.add(StringUtil.getShortName(annotationClass)); |
| for (int cursor = 0; cursor < annoClasses.size(); cursor++) { |
| final String annoClass = annoClasses.get(cursor); |
| for (PsiAnnotation annotation : JavaAnnotationIndex.getInstance().get(annoClass, project, GlobalSearchScope.allScope(project))) { |
| final PsiElement modList = annotation.getParent(); |
| if (!(modList instanceof PsiModifierList)) continue; |
| final PsiElement element = modList.getParent(); |
| if (element instanceof PsiParameter) { |
| final PsiElement scope = ((PsiParameter)element).getDeclarationScope(); |
| if (scope instanceof PsiNamedElement) { |
| ContainerUtil.addIfNotNull(((PsiNamedElement)scope).getName(), result); |
| } |
| else { |
| ContainerUtil.addIfNotNull(((PsiNamedElement)element).getName(), result); |
| } |
| } |
| else if (element instanceof PsiNamedElement) { |
| if (element instanceof PsiClass && ((PsiClass)element).isAnnotationType()) { |
| final String s = ((PsiClass)element).getName(); |
| if (!annoClasses.contains(s)) annoClasses.add(s); |
| } |
| else { |
| ContainerUtil.addIfNotNull(((PsiNamedElement)element).getName(), result); |
| } |
| } |
| } |
| } |
| return new Result<Collection<String>>(result, PsiModificationTracker.MODIFICATION_COUNT, configuration); |
| } |
| }, false); |
| } |
| |
| public static InjectionCache getInstance(Project project) { |
| return ServiceManager.getService(project, InjectionCache.class); |
| } |
| |
| public Collection<String> getAnnoIndex() { |
| return myAnnoIndex.getValue(); |
| } |
| |
| public Collection<String> getXmlIndex() { |
| return myXmlIndex.getValue(); |
| } |
| } |