diff --git a/src/com/magento/idea/magento2plugin/stubs/indexes/WebApiTypeIndex.java b/src/com/magento/idea/magento2plugin/stubs/indexes/WebApiTypeIndex.java index cc2bd34a2..f792e6c30 100644 --- a/src/com/magento/idea/magento2plugin/stubs/indexes/WebApiTypeIndex.java +++ b/src/com/magento/idea/magento2plugin/stubs/indexes/WebApiTypeIndex.java @@ -1,7 +1,8 @@ -/** +/* * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + package com.magento.idea.magento2plugin.stubs.indexes; import com.intellij.ide.highlighter.XmlFileType; @@ -13,41 +14,48 @@ import com.intellij.psi.xml.XmlDocument; import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; -import com.intellij.util.indexing.*; +import com.intellij.util.indexing.DataIndexer; +import com.intellij.util.indexing.FileBasedIndex; +import com.intellij.util.indexing.FileContent; +import com.intellij.util.indexing.ID; +import com.intellij.util.indexing.ScalarIndexExtension; import com.intellij.util.io.EnumeratorStringDescriptor; import com.intellij.util.io.KeyDescriptor; import com.jetbrains.php.lang.PhpLangUtil; import com.jetbrains.php.lang.psi.elements.Method; import com.jetbrains.php.lang.psi.elements.PhpClass; -import com.magento.idea.magento2plugin.project.Settings; import com.magento.idea.magento2plugin.linemarker.xml.LineMarkerXmlTagDecorator; +import com.magento.idea.magento2plugin.project.Settings; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import java.util.*; - /** * Indexer for classes/interfaces which have methods exposed via Web API. */ public class WebApiTypeIndex extends ScalarIndexExtension { - public static final ID KEY = ID.create("com.magento.idea.magento2plugin.stubs.indexes.webapi_type"); - + public static final ID KEY = ID.create( + "com.magento.idea.magento2plugin.stubs.indexes.webapi_type" + ); private final KeyDescriptor keyDescriptor = new EnumeratorStringDescriptor(); - @NotNull @Override - public ID getName() { + public @NotNull ID getName() { return KEY; } - @NotNull + @SuppressWarnings("PMD.CognitiveComplexity") @Override - public DataIndexer getIndexer() { + public @NotNull DataIndexer getIndexer() { return inputData -> { - Map map = new HashMap<>(); + final Map map = new HashMap<>(); + final PsiFile psiFile = inputData.getPsiFile(); - PsiFile psiFile = inputData.getPsiFile(); if (!Settings.isEnabled(psiFile.getProject())) { return map; } @@ -55,22 +63,26 @@ public DataIndexer getIndexer() { if (!(psiFile instanceof XmlFile)) { return map; } + final XmlDocument document = ((XmlFile) psiFile).getDocument(); - XmlDocument document = ((XmlFile) psiFile).getDocument(); if (document == null) { return map; } + final XmlTag[] xmlTags = PsiTreeUtil.getChildrenOfType( + psiFile.getFirstChild(), + XmlTag.class + ); - XmlTag xmlTags[] = PsiTreeUtil.getChildrenOfType(psiFile.getFirstChild(), XmlTag.class); if (xmlTags == null) { return map; } - for (XmlTag xmlTag : xmlTags) { - if (xmlTag.getName().equals("routes")) { - for (XmlTag routeNode : xmlTag.findSubTags("route")) { - for (XmlTag serviceNode : routeNode.findSubTags("service")) { - String typeName = serviceNode.getAttributeValue("class"); + for (final XmlTag xmlTag : xmlTags) { + if ("routes".equals(xmlTag.getName())) { + for (final XmlTag routeNode : xmlTag.findSubTags("route")) { + for (final XmlTag serviceNode : routeNode.findSubTags("service")) { + final String typeName = serviceNode.getAttributeValue("class"); + if (typeName != null) { map.put(PhpLangUtil.toPresentableFQN(typeName), null); } @@ -78,23 +90,21 @@ public DataIndexer getIndexer() { } } } + return map; }; } - @NotNull @Override - public KeyDescriptor getKeyDescriptor() { + public @NotNull KeyDescriptor getKeyDescriptor() { return keyDescriptor; } - @NotNull @Override - public FileBasedIndex.InputFilter getInputFilter() { - return file -> ( - file.getFileType() == XmlFileType.INSTANCE && file.getNameWithoutExtension().equals("webapi") - && !file.getPath().contains("testsuite") && !file.getPath().contains("_files") - ); + public @NotNull FileBasedIndex.InputFilter getInputFilter() { + return file -> file.getFileType() == XmlFileType.INSTANCE + && "webapi".equals(file.getNameWithoutExtension()) + && !file.getPath().contains("testsuite") && !file.getPath().contains("_files"); } @Override @@ -109,45 +119,77 @@ public int getVersion() { /** * Get list of Web API routes associated with the provided method. - * * Parent classes are not taken into account. + * + * @param method Method + * + * @return List[XmlTag] */ - public static List getWebApiRoutes(Method method) { - List tags = new ArrayList<>(); + public static List getWebApiRoutes(final Method method) { + final List tags = new ArrayList<>(); + if (!method.getAccess().isPublic()) { return tags; } - PhpClass phpClass = method.getContainingClass(); - String methodFqn = method.getName(); + final PhpClass phpClass = method.getContainingClass(); + if (phpClass == null) { return tags; } - String classFqn = phpClass.getPresentableFQN(); - Collection containingFiles = FileBasedIndex - .getInstance().getContainingFiles(KEY, classFqn, GlobalSearchScope.allScope(phpClass.getProject())); + final String classFqn = phpClass.getPresentableFQN(); + final Collection containingFiles = FileBasedIndex + .getInstance() + .getContainingFiles( + KEY, + classFqn, + GlobalSearchScope.allScope(phpClass.getProject()) + ); + + final PsiManager psiManager = PsiManager.getInstance(phpClass.getProject()); + final String methodFqn = method.getName(); + + for (final VirtualFile virtualFile : containingFiles) { + if (virtualFile.getFileType() != XmlFileType.INSTANCE) { + continue; + } + final XmlFile file = (XmlFile) psiManager.findFile(virtualFile); - PsiManager psiManager = PsiManager.getInstance(phpClass.getProject()); - for (VirtualFile virtualFile : containingFiles) { - XmlFile file = (XmlFile) psiManager.findFile(virtualFile); if (file == null) { continue; } - XmlTag rootTag = file.getRootTag(); + final XmlTag rootTag = file.getRootTag(); + + if (rootTag == null) { + continue; + } fillRelatedTags(classFqn, methodFqn, rootTag, tags); } + return tags; } /** - * Find routes related to the specified method within single webapi.xml + * Find routes related to the specified method within single webapi.xml. + * + * @param classFqn String + * @param methodFqn String + * @param parentTag XmlTag + * @param tagsReferences List[XmlTag] */ - private static void fillRelatedTags(String classFqn, String methodFqn, XmlTag parentTag, List tagsReferences) { - for (XmlTag routeNode : parentTag.findSubTags("route")) { - for (XmlTag serviceNode : routeNode.findSubTags("service")) { - String typeName = serviceNode.getAttributeValue("class"); - String methodName = serviceNode.getAttributeValue("method"); + @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") + private static void fillRelatedTags( + final String classFqn, + final String methodFqn, + final XmlTag parentTag, + final List tagsReferences + ) { + for (final XmlTag routeNode : parentTag.findSubTags("route")) { + for (final XmlTag serviceNode : routeNode.findSubTags("service")) { + final String typeName = serviceNode.getAttributeValue("class"); + final String methodName = serviceNode.getAttributeValue("method"); + if (typeName != null && typeName.equals(classFqn) - && methodName != null && methodName.equals(methodFqn) + && methodName != null && methodName.equals(methodFqn) ) { tagsReferences.add(new WebApiLineMarkerXmlTagDecorator(routeNode)); } @@ -160,25 +202,24 @@ private static void fillRelatedTags(String classFqn, String methodFqn, XmlTag pa */ private static class WebApiLineMarkerXmlTagDecorator extends LineMarkerXmlTagDecorator { - WebApiLineMarkerXmlTagDecorator(XmlTag xmlTag) { + public WebApiLineMarkerXmlTagDecorator(final XmlTag xmlTag) { super(xmlTag); } - @NotNull @Override - public String getDescription() { + public @NotNull String getDescription() { return ""; } @Override - @NotNull - @NonNls - public String getName() { - String httpMethod = this.xmlTag.getAttributeValue("method"); - String route = this.xmlTag.getAttributeValue("url"); + public @NonNls @NotNull String getName() { + final String httpMethod = this.xmlTag.getAttributeValue("method"); + final String route = this.xmlTag.getAttributeValue("url"); + if (httpMethod != null && route != null) { return String.format(" %-7s %s", httpMethod, route); } + return xmlTag.getName(); } }