Package fr.adrienbrault.idea.symfony2plugin.action

Source Code of fr.adrienbrault.idea.symfony2plugin.action.SymfonySymbolSearchAction

package fr.adrienbrault.idea.symfony2plugin.action;

import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.featureStatistics.FeatureUsageTracker;
import com.intellij.ide.actions.GotoActionBase;
import com.intellij.ide.util.gotoByName.ChooseByNamePopup;
import com.intellij.navigation.ChooseByNameContributor;
import com.intellij.navigation.ChooseByNameContributorEx;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.Processor;
import com.intellij.util.indexing.FindSymbolParameters;
import com.intellij.util.indexing.IdFilter;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import fr.adrienbrault.idea.symfony2plugin.Symfony2Icons;
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
import fr.adrienbrault.idea.symfony2plugin.TwigHelper;
import fr.adrienbrault.idea.symfony2plugin.action.model.SymfonySymbolSearchModel;
import fr.adrienbrault.idea.symfony2plugin.dic.ContainerService;
import fr.adrienbrault.idea.symfony2plugin.doctrine.EntityHelper;
import fr.adrienbrault.idea.symfony2plugin.doctrine.EntityReference;
import fr.adrienbrault.idea.symfony2plugin.doctrine.dict.DoctrineTypes;
import fr.adrienbrault.idea.symfony2plugin.navigation.NavigationItemEx;
import fr.adrienbrault.idea.symfony2plugin.routing.Route;
import fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper;
import fr.adrienbrault.idea.symfony2plugin.stubs.ContainerCollectionResolver;
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
import icons.TwigIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;


public class SymfonySymbolSearchAction extends GotoActionBase {

    @Override
    protected void gotoActionPerformed(AnActionEvent paramAnActionEvent) {
        FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.popup.file");
        Project localProject = paramAnActionEvent.getData(CommonDataKeys.PROJECT);
        if (localProject != null) {
            SymfonySymbolSearchModel searchModel = new SymfonySymbolSearchModel(localProject, new ChooseByNameContributor[] { new Symfony2NavigationContributor(localProject) });
            showNavigationPopup(paramAnActionEvent, searchModel, new MyGotoCallback(), null, true);
        }
    }

    @Override
    public void update(AnActionEvent event) {
        super.update(event);

        Project project = event.getData(CommonDataKeys.PROJECT);

        boolean enabled = Symfony2ProjectComponent.isEnabled(project);

        event.getPresentation().setVisible(enabled);
        event.getPresentation().setEnabled(enabled);

    }

    private static class Symfony2NavigationContributor implements ChooseByNameContributorEx, DumbAware {

        final private Project project;
        private ContainerCollectionResolver.ServiceCollector serviceCollector;
        private Map<String, VirtualFile> templateMap;
        private Map<String, Route> routes;
        private Set<String> twigMacroSet;
        private Map<String, LookupElement> lookupElements;

        public Symfony2NavigationContributor(Project project) {
            this.project = project;
        }

        private ContainerCollectionResolver.ServiceCollector getServiceCollector() {
            if(this.serviceCollector == null) {
                this.serviceCollector = new ContainerCollectionResolver.ServiceCollector(this.project);

                this.serviceCollector.addCollectorSource(ContainerCollectionResolver.Source.COMPILER);
                this.serviceCollector.addCollectorSource(ContainerCollectionResolver.Source.INDEX);
            }

            return this.serviceCollector;
        }

        private Map<String, VirtualFile> getTemplateMap() {

            if(this.templateMap == null) {
                this.templateMap = TwigHelper.getTemplateFilesByName(this.project, true, true);
            }

            return this.templateMap;
        }

        private Map<String, Route> getRoutes() {

            if(this.routes == null) {
                this.routes = project.getComponent(Symfony2ProjectComponent.class).getRoutes();
            }

            return this.routes;
        }

        private Set<String> getTwigMacroSet() {

            if(this.twigMacroSet == null) {
                this.twigMacroSet = TwigHelper.getTwigMacroSet(this.project);
            }

            return this.twigMacroSet;
        }

        private Map<String, LookupElement> getModelLookupElements() {

            if(this.lookupElements == null) {
                List<LookupElement> modelLookupElements = EntityReference.getModelLookupElements(this.project, DoctrineTypes.Manager.ORM, DoctrineTypes.Manager.MONGO_DB);

                this.lookupElements = new HashMap<String, LookupElement>();
                for(LookupElement lookupElement: modelLookupElements) {
                    this.lookupElements.put(lookupElement.getLookupString(), lookupElement);
                }

            }

            return this.lookupElements;
        }


        @Override
        public void processNames(@NotNull Processor<String> processor, @NotNull GlobalSearchScope scope, @Nullable IdFilter filter) {


            for(String name: getServiceCollector().getServices().keySet()) {
                processor.process(name);
            }

            for(Map.Entry<String, VirtualFile> entry: getTemplateMap().entrySet()) {
                processor.process(entry.getKey());
            }

            for(String name: getRoutes().keySet()) {
                processor.process(name);
            }

            for(String name: getTwigMacroSet()) {
                processor.process(name);
            }

            for(String name: getModelLookupElements().keySet()) {
                processor.process(name);
            }

        }

        @Override
        public void processElementsWithName(@NotNull String name, @NotNull Processor<NavigationItem> processor, @NotNull FindSymbolParameters parameters) {

            for(ContainerService containerService: getServiceCollector().collect()) {
                if(containerService.getName().equals(name)) {

                    String serviceClass = getServiceCollector().resolve(name);
                    if (serviceClass != null) {
                        PhpClass phpClass = PhpElementsUtil.getClassInterface(this.project, serviceClass);
                        if(phpClass != null) {
                            processor.process(new NavigationItemEx(phpClass, containerService.getName(), containerService.isWeak() ? Symfony2Icons.SERVICE_PRIVATE_OPACITY : Symfony2Icons.SERVICE, "Service"));
                        }
                    }

                }
            }

            if(getTemplateMap().containsKey(name)) {
                VirtualFile virtualFile = getTemplateMap().get(name);
                PsiFile psiFile = PsiManager.getInstance(this.project).findFile(virtualFile);
                if(psiFile != null) {
                    processor.process(new NavigationItemEx(psiFile, name, psiFile.getFileType().getIcon(), "Template"));
                }
            }

            if(getRoutes().containsKey(name)) {
                String controllerName = getRoutes().get(name).getController();
                if(controllerName != null) {
                    for(PsiElement psiElement: RouteHelper.getMethodsOnControllerShortcut(this.project, controllerName)) {
                        processor.process(new NavigationItemEx(psiElement, name, Symfony2Icons.ROUTE, "Route"));
                    }
                }
            }

            if(getTwigMacroSet().contains(name)) {
                for(PsiElement macroTarget: TwigHelper.getTwigMacroTargets(project, name)) {
                    processor.process(new NavigationItemEx(macroTarget, name, TwigIcons.TwigFileIcon, "Macro"));
                }
            }

            if(getModelLookupElements().containsKey(name)) {
                PsiElement[] psiElements = EntityHelper.getModelPsiTargets(this.project, name);

                getModelLookupElements().get(name).getLookupString();
                for(PsiElement target: psiElements) {
                    processor.process(new NavigationItemEx(target, name, target.getIcon(0), "Entity"));
                }
            }

        }

        @NotNull
        @Override
        public String[] getNames(Project project, boolean includeNonProjectItems) {
            return new String[0];
        }

        @NotNull
        @Override
        public NavigationItem[] getItemsByName(String name, String pattern, Project project, boolean includeNonProjectItems) {
            return new NavigationItem[0];
        }
    }

    class MyGotoCallback extends GotoActionBase.GotoActionCallback<FileType> {

        @Override
        public void elementChosen(ChooseByNamePopup popup, Object element) {
            if(element instanceof NavigationItem) {
                ((NavigationItem) element).navigate(true);
            }
        }

    }

}
TOP

Related Classes of fr.adrienbrault.idea.symfony2plugin.action.SymfonySymbolSearchAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.