package com.lightd.ideap.maven.navigation; import com.intellij.navigation.ChooseByNameContributorEx; import com.intellij.navigation.NavigationItem; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiFileSystemItem; import com.intellij.psi.PsiManager; import com.intellij.psi.codeStyle.MinusculeMatcher; import com.intellij.psi.codeStyle.NameUtil; import com.intellij.psi.search.FilenameIndex; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.GlobalSearchScopes; import com.intellij.util.ArrayUtil; import com.intellij.util.CommonProcessors; import com.intellij.util.Processor; import com.intellij.util.indexing.FindSymbolParameters; import com.intellij.util.indexing.IdFilter; import com.lightd.ideap.maven.settings.MvnRunConfigurationSettings; import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.maven.dom.MavenDomUtil; import org.jetbrains.idea.maven.model.MavenId; import org.jetbrains.idea.maven.project.MavenProject; import org.jetbrains.idea.maven.project.MavenProjectsManager; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; public class PomNavigationContributor implements ChooseByNameContributorEx, DumbAware { private final Project project; private final boolean showPomLocation; private MavenProjectsManager projectsManager; public PomNavigationContributor(Project project) { this.project = project; showPomLocation = MvnRunConfigurationSettings.getInstance().isShowPomLocation(); } @Override public void processNames(@NotNull final Processor<String> processor, @NotNull GlobalSearchScope scope, IdFilter filter) { projectsManager = MavenProjectsManager.getInstance(project); List<MavenProject> mavenProjects = projectsManager.getRootProjects(); if (mavenProjects.size() > 0) { addProjectNames(processor, mavenProjects.get(0)); if (scope.isSearchInLibraries()) { for (MavenId mavenId : getNotImportPoms(mavenProjects.get(0)).keySet()) { processor.process(mavenId.getKey()); } } } } private void addProjectNames(final Processor<String> processor, MavenProject mavenProject) { processor.process(mavenProject.getMavenId().getKey()); for (MavenProject subModule : projectsManager.getModules(mavenProject)) { addProjectNames(processor, subModule); } } @Override public void processElementsWithName(@NotNull String name, @NotNull final Processor<NavigationItem> processor, @NotNull FindSymbolParameters parameters) { final MinusculeMatcher matcher = NameUtil.buildMatcher(parameters.getCompletePattern(), NameUtil.MatchingCaseSensitivity.FIRST_LETTER); if (!matcher.isStartMatch(name.substring(0, name.lastIndexOf(':')))) return; String[] names = name.split(":"); MavenId mavenId = new MavenId(names[0], names[1], names[2]); projectsManager = MavenProjectsManager.getInstance(project); MavenProject p = projectsManager.findProject(mavenId); PsiFileSystemItem pomFile = null; if (p != null) { pomFile = PsiManager.getInstance(project).findFile(p.getFile()); } else if (parameters.isSearchInLibraries()) { Map<MavenId, PsiFile> notImportPoms = getNotImportPoms(projectsManager.getRootProjects().get(0)); pomFile = notImportPoms.get(mavenId); } if (pomFile != null) { PomWrapper pomWrapper = new PomWrapper(pomFile, mavenId, project.getBasePath(), showPomLocation); processor.process(pomWrapper); } } @NotNull @Override public String[] getNames(Project project, boolean includeNonProjectItems) { CommonProcessors.CollectProcessor<String> processor = new CommonProcessors.CollectProcessor<String>(); GlobalSearchScope scope = includeNonProjectItems ? GlobalSearchScope.allScope(project) : GlobalSearchScope.projectScope(project); processNames(processor, scope, IdFilter.getProjectIdFilter(project, includeNonProjectItems)); return ArrayUtil.toStringArray(processor.getResults()); } @NotNull @Override public NavigationItem[] getItemsByName(String name, final String pattern, Project project, boolean includeNonProjectItems) { CommonProcessors.CollectProcessor<NavigationItem> processor = new CommonProcessors.CollectProcessor<NavigationItem>(); processElementsWithName(name, processor, FindSymbolParameters.wrap(pattern, project, includeNonProjectItems)); return processor.toArray(new NavigationItem[processor.getResults().size()]); } private Map<MavenId, PsiFile> getNotImportPoms(MavenProject mavenProject) { GlobalSearchScope pomScope = GlobalSearchScopes.directoryScope(project, mavenProject.getDirectoryFile(), true); PsiFile[] psiFiles = FilenameIndex.getFilesByName(project, "pom.xml", pomScope); Map<MavenId, PsiFile> poms = new LinkedHashMap<MavenId, PsiFile>(psiFiles.length); for (PsiFile psiFile : psiFiles) { if (projectsManager.findProject(psiFile.getVirtualFile()) == null) { MavenId mavenId = MavenDomUtil.describe(psiFile); poms.put(mavenId, psiFile); } } return poms; } }