Package fr.adrienbrault.idea.symfony2plugin.util.dict

Source Code of fr.adrienbrault.idea.symfony2plugin.util.dict.ServiceUtil

package fr.adrienbrault.idea.symfony2plugin.util.dict;

import com.intellij.ide.highlighter.XmlFileType;
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.indexing.FileBasedIndex;
import com.intellij.util.indexing.FileBasedIndexImpl;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import fr.adrienbrault.idea.symfony2plugin.dic.XmlTagParser;
import fr.adrienbrault.idea.symfony2plugin.stubs.ContainerCollectionResolver;
import fr.adrienbrault.idea.symfony2plugin.stubs.ServiceIndexUtil;
import fr.adrienbrault.idea.symfony2plugin.stubs.SymfonyProcessors;
import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.ContainerParameterStubIndex;
import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.ServicesTagStubIndex;
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
import fr.adrienbrault.idea.symfony2plugin.util.service.ServiceXmlParserFactory;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.yaml.YAMLFileType;

import java.util.*;

public class ServiceUtil {


    static final Map<String , String> TAG_INTERFACES = new HashMap<String , String>() {{
        //put("assetic.asse", null);
        put("assetic.factory_worker", "Assetic\\Factory\\Worker\\WorkerInterface");
        put("assetic.filter", "Assetic\\Filter\\FilterInterface");
        put("assetic.formula_loader", "Assetic\\Factory\\Loader\\FormulaLoaderInterface");
        put("assetic.formula_resource", null);
        put("assetic.templating.php", null);
        put("assetic.templating.twig", null);
        put("console.command", "\\Symfony\\Component\\Console\\Command\\Command");
        put("data_collector", "\\Symfony\\Component\\HttpKernel\\DataCollector\\DataCollectorInterface");
        put("doctrine.event_listener", null);
        put("doctrine.event_subscriber", null);
        put("form.type", "\\Symfony\\Component\\Form\\FormTypeInterface");
        put("form.type_extension", "\\Symfony\\Component\\Form\\FormExtensionInterface");
        put("form.type_guesser", "\\Symfony\\Component\\Form\\FormTypeGuesserInterface");
        put("kernel.cache_clearer", null);
        put("kernel.cache_warmer", "\\Symfony\\Component\\HttpKernel\\CacheWarmer\\CacheWarmerInterface");
        put("kernel.fragment_renderer", null);
        put("monolog.logger", null);
        put("monolog.processor", null);
        put("routing.loader", "Symfony\\Component\\Config\\Loader\\LoaderInterface");
        //put("security.remember_me_aware", null);
        put("security.voter", "Symfony\\Component\\Security\\Core\\Authorization\\Voter\\VoterInterface");
        put("serializer.encoder", "Symfony\\Component\\Serializer\\Encoder\\EncoderInterface");
        put("serializer.normalizer", "Symfony\\Component\\Serializer\\Normalizer\\NormalizerInterface");
        // Symfony\Component\Serializer\Normalizer\DenormalizerInterface
        put("swiftmailer.default.plugin", "Swift_Events_EventListener");
        put("templating.helper", "\\Symfony\\Component\\Templating\\Helper\\HelperInterface");
        put("translation.loader", "\\Symfony\\Component\\Translation\\Loader\\LoaderInterface");
        put("translation.extractor", "\\Symfony\\Component\\Translation\\Extractor\\ExtractorInterface");
        put("translation.dumper", "\\Symfony\\Component\\Translation\\Dumper\\DumperInterface");
        put("twig.extension", "\\Twig_Extension");
        put("twig.loader", "Twig_LoaderInterface");
        put("validator.constraint_validator", "Symfony\\Component\\Validator\\ConstraintValidator");
        put("validator.initializer", "Symfony\\Component\\Validator\\ObjectInitializerInterface");

    }};

    /**
     * %test%, service, \Class\Name to PhpClass
     */
    @Nullable
    public static PhpClass getResolvedClassDefinition(Project project, String serviceClassParameterName) {

        // match parameter
        if(serviceClassParameterName.startsWith("%") && serviceClassParameterName.endsWith("%")) {
            String serviceClass = ContainerCollectionResolver.resolveParameter(project, serviceClassParameterName);

            if(serviceClass != null) {
                return PhpElementsUtil.getClassInterface(project, serviceClass);
            }

            return null;
        }

        // service names dont have namespaces
        if(!serviceClassParameterName.contains("\\")) {
            String serviceClass = ContainerCollectionResolver.resolveService(project, serviceClassParameterName);
            if(serviceClass != null) {
                return PhpElementsUtil.getClassInterface(project, serviceClass);
            }
        }

        // fallback to class name with and without namespaces
        return PhpElementsUtil.getClassInterface(project, serviceClassParameterName);
    }

    /**
     * Get parameter def inside xml or yaml file
     */
    public static Collection<PsiElement> getParameterDefinition(Project project, String parameterName) {

        if(parameterName.length() > 2 && parameterName.startsWith("%") && parameterName.endsWith("%")) {
            parameterName = parameterName.substring(1, parameterName.length() - 1);
        }

        Collection<PsiElement> psiElements = new ArrayList<PsiElement>();

        Collection<VirtualFile> fileCollection = FileBasedIndex.getInstance().getContainingFiles(ContainerParameterStubIndex.KEY, parameterName, GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(project), XmlFileType.INSTANCE, YAMLFileType.YML));
        for(VirtualFile virtualFile: fileCollection) {
            PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
            if(psiFile != null) {
                psiElements.addAll(ServiceIndexUtil.findParameterDefinitions(psiFile, parameterName));
            }
        }

        return psiElements;

    }

    public static Collection<PsiElement> getServiceClassTargets(Project project, String value) {

        List<PsiElement> resolveResults = new ArrayList<PsiElement>();

        if(StringUtils.isBlank(value)) {
            return resolveResults;
        }

        // resolve class or parameter class
        PhpClass phpClass = ServiceUtil.getResolvedClassDefinition(project, value);
        if(phpClass != null) {
            resolveResults.add(phpClass);
        }

        // get parameter def target
        if(value.startsWith("%") && value.endsWith("%")) {
            resolveResults.addAll(ServiceUtil.getParameterDefinition(project, value));
        }

        return resolveResults;
    }

    public static Set<String> getTaggedServices(Project project, String tagName) {

        SymfonyProcessors.CollectProjectUniqueKeys projectUniqueKeysStrong = new SymfonyProcessors.CollectProjectUniqueKeys(project, ServicesTagStubIndex.KEY);
        FileBasedIndexImpl.getInstance().processAllKeys(ServicesTagStubIndex.KEY, projectUniqueKeysStrong, project);

        Set<String> service = new HashSet<String>();

        for(String serviceName: projectUniqueKeysStrong.getResult()) {

            List<String[]> serviceDefinitions = FileBasedIndexImpl.getInstance().getValues(ServicesTagStubIndex.KEY, serviceName, GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(project), XmlFileType.INSTANCE, YAMLFileType.YML));
            for(String[] strings: serviceDefinitions) {
                if(Arrays.asList(strings).contains(tagName)) {
                    service.add(serviceName);
                }
            }

        }

        return service;
    }

    public static Collection<PhpClass> getTaggedClasses(Project project, String tagName) {

        List<PhpClass> phpClasses = new ArrayList<PhpClass>();

        Set<String> taggedServices = getTaggedServices(project, tagName);
        if(taggedServices.size() == 0) {
            return phpClasses;
        }

        ContainerCollectionResolver.ServiceCollector collector = new ContainerCollectionResolver.ServiceCollector(project, ContainerCollectionResolver.Source.COMPILER, ContainerCollectionResolver.Source.INDEX);
        for(String serviceName: taggedServices) {
            String resolvedService = collector.resolve(serviceName);
            if(resolvedService != null) {
                PhpClass phpClass = PhpElementsUtil.getClass(project, resolvedService);
                if(phpClass != null) {
                    phpClasses.add(phpClass);
                }
            }
        }

        return phpClasses;
    }

    public static Collection<PhpClass> getTaggedClassesWithCompiled(Project project, String tagName) {

        Set<String> uniqueClass = new HashSet<String>();

        Collection<PhpClass> taggedClasses = new ArrayList<PhpClass>();
        for(PhpClass phpClass: getTaggedClasses(project, tagName)) {
            String presentableFQN = phpClass.getPresentableFQN();
            if(presentableFQN != null && !uniqueClass.contains(presentableFQN)) {
                uniqueClass.add(presentableFQN);
                taggedClasses.add(phpClass);
            }
        }

        XmlTagParser xmlTagParser = ServiceXmlParserFactory.getInstance(project, XmlTagParser.class);

        List<String> taggedCompiledClasses= xmlTagParser.getTaggedClass(tagName);
        if(taggedCompiledClasses == null) {
            return taggedClasses;
        }

        for(String className: taggedCompiledClasses) {
            if(!uniqueClass.contains(className)) {
                PhpClass phpClass = PhpElementsUtil.getClass(project, className);
                if(phpClass != null) {
                    taggedClasses.add(phpClass);
                }
            }
        }

        return taggedClasses;
    }


}
TOP

Related Classes of fr.adrienbrault.idea.symfony2plugin.util.dict.ServiceUtil

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.