diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/inspection/AbstractCamelInspection.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/inspection/AbstractCamelInspection.java index 0a785693..4d4d1bd0 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/inspection/AbstractCamelInspection.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/inspection/AbstractCamelInspection.java @@ -49,10 +49,10 @@ public abstract class AbstractCamelInspection extends LocalInspectionTool { private boolean forceEnabled; - public AbstractCamelInspection() { + protected AbstractCamelInspection() { } - public AbstractCamelInspection(boolean forceEnabled) { + protected AbstractCamelInspection(boolean forceEnabled) { this.forceEnabled = forceEnabled; } @@ -119,7 +119,7 @@ private void validateSimple(@NotNull PsiElement element, final @NotNull Problems CamelService camelService = element.getProject().getService(CamelService.class); IElementType type = element.getNode().getElementType(); - LOG.trace("Element " + element + " of type: " + type + " to inspect simple: " + text); + LOG.trace("Element %s of type: %s to inspect simple: %s".formatted(element, type, text)); try { // need to use the classloader that can load classes from the camel-core @@ -146,8 +146,8 @@ private void validateSimple(@NotNull PsiElement element, final @NotNull Problems holder.registerProblem(element, msg); } } - } catch (Throwable e) { - LOG.warn("Error inspection Camel simple: " + text, e); + } catch (Exception e) { + LOG.warn("Error inspection Camel simple: %s".formatted(text), e); } } @@ -189,8 +189,8 @@ private void validateJSonPath(@NotNull PsiElement element, final @NotNull Proble holder.registerProblem(element, msg); } } - } catch (Throwable e) { - LOG.warn("Error inspection Camel jsonpath: " + text, e); + } catch (Exception e) { + LOG.warn("Error inspection Camel jsonpath: %s".formatted(text), e); } } @@ -209,7 +209,7 @@ private void validateEndpoint(@NotNull PsiElement element, final @NotNull Proble // camel catalog expects & as & when it parses so replace all & as & String camelQuery = text; - camelQuery = camelQuery.replaceAll("&", "&"); + camelQuery = camelQuery.replace("&", "&"); // strip up ending incomplete parameter if (camelQuery.endsWith("&") || camelQuery.endsWith("?")) { @@ -219,9 +219,7 @@ private void validateEndpoint(@NotNull PsiElement element, final @NotNull Proble boolean stringFormat = camelIdeaUtils.isFromStringFormatEndpoint(element); if (stringFormat) { // if the node is fromF or toF, then replace all %X with {{%X}} as we cannot parse that value - camelQuery = camelQuery.replaceAll("%s", "\\{\\{\\%s\\}\\}"); - camelQuery = camelQuery.replaceAll("%d", "\\{\\{\\%d\\}\\}"); - camelQuery = camelQuery.replaceAll("%b", "\\{\\{\\%b\\}\\}"); + camelQuery = camelQuery.replaceAll("(%[bds])", "{{$1}}"); } boolean consumerOnly = camelIdeaUtils.isConsumerEndpoint(element); @@ -238,8 +236,8 @@ private void validateEndpoint(@NotNull PsiElement element, final @NotNull Proble extractSetValue(result, result.getUnknown(), text, element, holder, isOnTheFly, new AbstractCamelInspection.UnknownErrorMsg()); extractSetValue(result, result.getNotConsumerOnly(), text, element, holder, isOnTheFly, new AbstractCamelInspection.NotConsumerOnlyErrorMsg()); extractSetValue(result, result.getNotProducerOnly(), text, element, holder, isOnTheFly, new AbstractCamelInspection.NotProducerOnlyErrorMsg()); - } catch (Throwable e) { - LOG.warn("Error inspecting Camel endpoint: " + text, e); + } catch (Exception e) { + LOG.warn("Error inspecting Camel endpoint: %s".formatted(text), e); } } @@ -271,7 +269,7 @@ private static class BooleanErrorMsg implements CamelAnnotatorEndpointMessage entry) { String name = entry.getKey(); - boolean empty = entry.getValue() == null || entry.getValue().length() == 0; + boolean empty = entry.getValue() == null || entry.getValue().isEmpty(); if (empty) { return name + " has empty boolean value"; } else { @@ -381,7 +379,6 @@ public boolean isWarnLevel() { * * @return the summary, or empty if no validation errors */ - @SuppressWarnings("unchecked") private String summaryErrorMessage(EndpointValidationResult result, T entry, CamelAnnotatorEndpointMessage msg) { if (result.getIncapable() != null) { return "Incapable of parsing uri: " + result.getIncapable(); diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/ui/CamelDebuggerEvaluationDialog.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/ui/CamelDebuggerEvaluationDialog.java index c0c73d30..4de81efe 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/ui/CamelDebuggerEvaluationDialog.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/ui/CamelDebuggerEvaluationDialog.java @@ -74,8 +74,6 @@ import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; import java.util.HashMap; import java.util.Map; import java.util.function.Supplier; @@ -83,7 +81,7 @@ public class CamelDebuggerEvaluationDialog extends DialogWrapper { public static final DataKey KEY = DataKey.create("CAMEL_DEBUGGER_EVALUATION_DIALOG"); - //can not use new SHIFT_DOWN_MASK etc because in this case ActionEvent modifiers do not match + //cannot use new SHIFT_DOWN_MASK etc. because in this case ActionEvent modifiers do not match private static final int ADD_WATCH_MODIFIERS = (SystemInfo.isMac ? InputEvent.META_MASK : InputEvent.CTRL_MASK) | InputEvent.SHIFT_MASK; static KeyStroke addWatchKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, ADD_WATCH_MODIFIERS); diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/extension/camel/JavaCamelIdeaUtils.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/extension/camel/JavaCamelIdeaUtils.java index 374425a5..1dd52732 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/extension/camel/JavaCamelIdeaUtils.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/service/extension/camel/JavaCamelIdeaUtils.java @@ -55,7 +55,6 @@ import com.intellij.psi.impl.source.PostprocessReformattingAspect; import com.intellij.psi.impl.source.PsiClassReferenceType; import com.intellij.psi.search.searches.ClassInheritorsSearch; -import com.intellij.psi.util.ClassUtil; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.testFramework.LightVirtualFile; @@ -94,7 +93,7 @@ public class JavaCamelIdeaUtils extends CamelIdeaUtils implements CamelIdeaUtils "kamelet", "step", "transacted", "saga", "route", "resequence", "policy", "onException", "onCompletion", "from", "rest", "restConfiguration"); /** - * Name of the methods corresponding to root element of sub DSL. + * Name of the methods corresponding to the root element of sub DSL. */ private static final Set SUB_DSL_ROOTS = Set.of("expression", "dataFormat"); /** @@ -122,6 +121,23 @@ public class JavaCamelIdeaUtils extends CamelIdeaUtils implements CamelIdeaUtils "org.apache.camel.spring.SpringRouteBuilder", "org.apache.camel.builder.endpoint.EndpointRouteBuilder" ); + private static final List BEAN_ANNOTATIONS = Arrays.asList( + "org.springframework.stereotype.Component", + "org.springframework.stereotype.Service", + "org.springframework.stereotype.Repository", + "javax.inject.Named", + "javax.inject.Singleton", + "javax.enterprise.context.ApplicationScoped", + "javax.enterprise.context.SessionScoped", + "javax.enterprise.context.ConversationScoped", + "javax.enterprise.context.RequestScoped", + "jakarta.inject.Named", + "jakarta.inject.Singleton", + "jakarta.enterprise.context.ApplicationScoped", + "jakarta.enterprise.context.SessionScoped", + "jakarta.enterprise.context.ConversationScoped", + "jakarta.enterprise.context.RequestScoped" + ); @Override public boolean isCamelFile(PsiFile file) { @@ -216,10 +232,10 @@ public boolean isCamelExpressionUsedAsPredicate(PsiElement element, String langu // okay dive into the psi and find out which EIP are using the simple PsiElement child = call.getFirstChild(); - if (child instanceof PsiReferenceExpression) { + if (child instanceof PsiReferenceExpression psiReferenceExpression) { // this code is needed as it may be used as a method call as a parameter and this requires // a bit of psi code to unwrap the right elements. - PsiExpression exp = ((PsiReferenceExpression) child).getQualifierExpression(); + PsiExpression exp = psiReferenceExpression.getQualifierExpression(); if (exp == null) { // okay it was not a direct method call, so see if it was passed in as a parameter instead (expression list) element = element.getParent(); @@ -230,8 +246,8 @@ public boolean isCamelExpressionUsedAsPredicate(PsiElement element, String langu exp = PsiTreeUtil.getParentOfType(element.getParent(), PsiMethodCallExpression.class); } } - if (exp instanceof PsiMethodCallExpression) { - PsiMethod method = ((PsiMethodCallExpression) exp).resolveMethod(); + if (exp instanceof PsiMethodCallExpression psiMethodCallExpression) { + PsiMethod method = psiMethodCallExpression.resolveMethod(); if (method != null) { String name = method.getName(); return Arrays.asList(PREDICATE_EIPS).contains(name); @@ -299,7 +315,7 @@ public boolean isFromStringFormatEndpoint(PsiElement element) { public boolean acceptForAnnotatorOrInspection(PsiElement element) { // skip XML limit on siblings if (!IdeaUtils.getService().isFromFileType(element, "xml")) { - // for programming languages you can have complex structures with concat which we don't support yet + // for programming languages you can have complex structures with concat which we don't support it yet. // we currently only support oneliner, so check how many siblings the element has (it has 1 with ending parenthesis which is okay) return countSiblings(element) <= 1; } @@ -310,8 +326,8 @@ public boolean acceptForAnnotatorOrInspection(PsiElement element) { public PsiClass getBeanClass(PsiElement element) { final PsiElement beanPsiElement = getPsiElementForCamelBeanMethod(element); if (beanPsiElement != null) { - if (beanPsiElement instanceof PsiClass) { - return (PsiClass) beanPsiElement; + if (beanPsiElement instanceof PsiClass psiClass) { + return psiClass; } PsiJavaCodeReferenceElement referenceElement = PsiTreeUtil.findChildOfType(beanPsiElement, PsiJavaCodeReferenceElement.class); @@ -372,19 +388,22 @@ public boolean isPlaceForEndpointUri(PsiElement location) { } /** - * @return the {@link PsiClass} for the matching bean name by looking for classes annotated with spring Component, Service or Repository + * @return the {@link PsiClass} for the matching bean name by looking for classes annotated with + * Spring Component, Service or Repository or Quarkus javax or jakarta annotations. */ private Optional searchForMatchingBeanClass(String beanName, Project project) { final JavaClassUtils javaClassUtils = JavaClassUtils.getService(); - return javaClassUtils.findBeanClassByName(beanName, "org.springframework.stereotype.Component", project) - .or(() -> javaClassUtils.findBeanClassByName(beanName, "org.springframework.stereotype.Service", project)) - .or(() -> javaClassUtils.findBeanClassByName(beanName, "org.springframework.stereotype.Repository", project)); + + return BEAN_ANNOTATIONS + .stream() + .map(annotation -> javaClassUtils.findBeanClassByName(beanName, annotation, project)) + .flatMap(Optional::stream) + .findFirst(); } private List findEndpoints(Module module, Predicate uriCondition, Predicate elementCondition) { PsiManager manager = PsiManager.getInstance(module.getProject()); - //TODO: use IdeaUtils.ROUTE_BUILDER_OR_EXPRESSION_CLASS_QUALIFIED_NAME somehow - PsiClass routeBuilderClass = ClassUtil.findPsiClass(manager, "org.apache.camel.builder.RouteBuilder"); + PsiClass routeBuilderClass = IdeaUtils.findRouteBuilderClass(manager); List results = new ArrayList<>(); if (routeBuilderClass != null) { @@ -394,8 +413,7 @@ private List findEndpoints(Module module, Predicate uriCondi Collection literals = PsiTreeUtil.findChildrenOfType(routeBuilder, PsiLiteralExpression.class); for (PsiLiteralExpression literal : literals) { Object val = literal.getValue(); - if (val instanceof String) { - String endpointUri = (String) val; + if (val instanceof String endpointUri) { if (uriCondition.test(endpointUri) && elementCondition.test(literal)) { results.add(literal); } @@ -436,7 +454,7 @@ private void format(PsiFile file, Document document, int startOffset, int endOff final VirtualFile vFile = FileDocumentManager.getInstance().getFile(document); if ((vFile == null || vFile instanceof LightVirtualFile) && !ApplicationManager.getApplication().isUnitTestMode()) { // we assume that control flow reaches this place when the document is backed by a "virtual" file so any changes made by - // a formatter affect only PSI and it is out of sync with a document text + // a formatter affect only PSI, and it is out of sync with a document text return; } diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/CamelIdeaUtils.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/CamelIdeaUtils.java index 74306070..eb9d6d2d 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/CamelIdeaUtils.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/CamelIdeaUtils.java @@ -20,6 +20,7 @@ import com.github.cameltooling.idea.reference.endpoint.CamelEndpoint; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.Service; import com.intellij.openapi.module.Module; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiClass; @@ -34,13 +35,13 @@ import java.util.List; import java.util.Objects; import java.util.function.Predicate; -import java.util.stream.Collectors; /** * Utility methods to work with Camel related {@link com.intellij.psi.PsiElement} elements. *

* This class is only for Camel related IDEA APIs. If you need only IDEA APIs then use {@link IdeaUtils} instead. */ +@Service public final class CamelIdeaUtils implements Disposable { public static final String[] CAMEL_FILE_EXTENSIONS = {"java", "xml", "yaml", "yml"}; @@ -192,7 +193,7 @@ public boolean isCamelExpressionOrLanguage(PsiClass clazz) { } /** - * Certain elements should be skipped for endpoint validation such as ActiveMQ brokerURL property and others. + * Certain elements should be skipped for endpoint validation, such as ActiveMQ brokerURL property and others. */ public boolean skipEndpointValidation(PsiElement element) { return enabledExtensions.stream() @@ -264,10 +265,9 @@ public List findEndpointDeclarations(Module module, Predicate - * This class is only for IDEA APIs. If you need Camel related APIs as well then use {@link CamelIdeaUtils} instead. + * This class is only for IDEA APIs. If you need Camel related APIs as well, use {@link CamelIdeaUtils} instead. */ +@Service public final class IdeaUtils implements Disposable { - private static final List ROUTE_BUILDER_OR_EXPRESSION_CLASS_QUALIFIED_NAME = Arrays.asList( - "org.apache.camel.builder.RouteBuilder", "org.apache.camel.builder.BuilderSupport", - "org.apache.camel.model.ProcessorDefinition", "org.apache.camel.model.language.ExpressionDefinition"); + private static final List ROUTE_BUILDER_OR_EXPRESSION_CLASS_QUALIFIED_NAME = List.of( + "org.apache.camel.builder.endpoint.EndpointRouteBuilder", + "org.apache.camel.builder.RouteBuilder", + "org.apache.camel.builder.BuilderSupport", + "org.apache.camel.model.ProcessorDefinition", + "org.apache.camel.model.language.ExpressionDefinition" + ); private final List enabledExtensions; private IdeaUtils() { enabledExtensions = Arrays.stream(IdeaUtilsExtension.EP_NAME.getExtensions()) .filter(IdeaUtilsExtension::isExtensionEnabled) - .collect(Collectors.toList()); + .toList(); } public static IdeaUtils getService() { @@ -124,9 +130,9 @@ public String extractTextFromElement(PsiElement element) { * Extract the text value from the {@link PsiElement} from any of the support languages this plugin works with. * * @param element the element - * @param fallBackToGeneric if could find any of the supported languages fallback to generic if true + * @param fallBackToGeneric if it could find any of the supported language-fallbacks to generic if true * @param concatString concatenated the string if it wrapped - * @param stripWhitespace + * @param stripWhitespace strip whitespaces * @return the text or null if the element is not a text/literal kind. */ @Nullable @@ -156,7 +162,7 @@ public String extractTextFromElement(PsiElement element, boolean fallBackToGener } /** - * Is the element from a java setter method (eg setBrokerURL) or from a XML configured bean style + * Is the element from a java setter method (e.g., setBrokerURL) or from an XML configured bean style * configuration using property element. */ public boolean isElementFromSetterProperty(@NotNull PsiElement element, @NotNull String setter) { @@ -181,21 +187,21 @@ public boolean isElementFromAnnotation(@NotNull PsiElement element, @NotNull Str * Is the element from Java language */ public boolean isJavaLanguage(PsiElement element) { - return element != null && PsiUtil.getNotAnyLanguage(element.getNode()).is(JavaLanguage.INSTANCE); + return element != null && PsiUtilCore.getNotAnyLanguage(element.getNode()).is(JavaLanguage.INSTANCE); } /** * Is the element from XML language */ public boolean isXmlLanguage(PsiElement element) { - return element != null && PsiUtil.getNotAnyLanguage(element.getNode()).is(XMLLanguage.INSTANCE); + return element != null && PsiUtilCore.getNotAnyLanguage(element.getNode()).is(XMLLanguage.INSTANCE); } /** * Is the element from YAML language */ public boolean isYamlLanguage(PsiElement element) { - return element != null && PsiUtil.getNotAnyLanguage(element.getNode()).is(YAMLLanguage.INSTANCE); + return element != null && PsiUtilCore.getNotAnyLanguage(element.getNode()).is(YAMLLanguage.INSTANCE); } /** @@ -207,8 +213,8 @@ public boolean isFromFileType(PsiElement element, @NotNull String... extensions) } PsiFile file; - if (element instanceof PsiFile) { - file = (PsiFile) element; + if (element instanceof PsiFile psiFile) { + file = psiFile; } else { file = PsiTreeUtil.getParentOfType(element, PsiFile.class); } @@ -255,7 +261,7 @@ public boolean isFromFileType(PsiElement element, @NotNull String... extensions) } /** - * Is the given class or any of its super classes a class with the qualified name. + * Is the given class or any of its superclasses a class with the qualified name. * * @param target the class * @param fqnClassName the class name to match @@ -273,11 +279,11 @@ private static boolean isClassOrParentOf(@Nullable PsiClass target, @NotNull Str } /** - * Is the element from a constructor call with the given constructor name (eg class name) + * Is the element from a constructor call with the given constructor name (e.g., class name) * * @param element the element - * @param constructorName the name of the constructor (eg class) - * @return true if its a constructor call from the given name, false otherwise + * @param constructorName the name of the constructor (e.g., class) + * @return true if it is a constructor call from the given name, false otherwise */ public boolean isElementFromConstructor(@NotNull PsiElement element, @NotNull String constructorName) { // java constructor @@ -292,7 +298,7 @@ public boolean isElementFromConstructor(@NotNull PsiElement element, @NotNull St } /** - * Is the given element from a Java method call with any of the given method names + * Is the given element from a Java method call with any of the given method names? * * @param element the psi element * @param methods method call names @@ -311,7 +317,7 @@ public boolean isFromJavaMethodCall(PsiElement element, boolean fromRouteBuilder * Returns the first parent of the given element which matches the given condition. * * @param element element from which the search starts - * @param strict if true, element itself cannot be returned if it matches the condition + * @param strict if true, the element itself cannot be returned if it matches the condition * @param matchCondition condition which the parent must match to be returned * @param stopCondition condition which stops the search, causing the method to return null */ @@ -358,7 +364,7 @@ public boolean isFromJavaMethod(PsiMethodCallExpression call, boolean fromRouteB } /** - * Is the given element from a XML tag with any of the given tag names + * Is the given element from an XML tag with any of the given tag names? * * @param xml the xml tag * @param methods xml tag names @@ -370,7 +376,7 @@ public boolean isFromXmlTag(@NotNull XmlTag xml, @NotNull String... methods) { } /** - * Is the given element from a XML tag with any of the given tag names + * Is the given element from an XML tag with any of the given tag names * * @param xml the xml tag * @param parentTag a special parent tag name to match first @@ -416,7 +422,7 @@ public boolean hasParentYAMLKeyValue(@NotNull YAMLKeyValue keyValue, @NotNull St } /** - * Is the given element from a XML tag with the parent and is of any of the given tag names + * Is the given element from an XML tag with the parent and is of any given tag names? * * @param xml the xml tag * @param parentTag a special parent tag name to match first @@ -440,8 +446,8 @@ public void iterateYamlFiles(Module module, Consumer yamlFileConsumer) fileIndex.iterateContent(f -> { if (yamlFiles.contains(f)) { PsiFile file = PsiManager.getInstance(module.getProject()).findFile(f); - if (file instanceof YAMLFile) { - yamlFileConsumer.accept((YAMLFile) file); + if (file instanceof YAMLFile yamlFile) { + yamlFileConsumer.accept(yamlFile); } } return true; @@ -456,8 +462,7 @@ public void iterateXmlDocumentRoots(Module module, Consumer rootTag) { fileIndex.iterateContent(f -> { if (xmlFiles.contains(f)) { PsiFile file = PsiManager.getInstance(module.getProject()).findFile(f); - if (file instanceof XmlFile) { - XmlFile xmlFile = (XmlFile) file; + if (file instanceof XmlFile xmlFile) { XmlTag root = xmlFile.getRootTag(); if (root != null) { rootTag.accept(xmlFile.getRootTag()); @@ -503,7 +508,6 @@ private int getCaretPositionInsidePsiElement(String stringLiteral) { return hackIndex; } - /** * Return the Query parameter at the cursor location for the query parameter. *

    @@ -513,7 +517,7 @@ private int getCaretPositionInsidePsiElement(String stringLiteral) { *
  • timer:trigger?repeatCount=0&delay=<cursor> will return {"delay",""}
  • *
  • jms:qu<cursor> will return {":qu", ""}
  • *
- * @return a list with the query parameter and the value if present. The query parameter is returned with separator char + * @return an array with the query parameter and the value if present. The query parameter is returned with separator char */ public String[] getQueryParameterAtCursorPosition(PsiElement element) { String positionText = extractTextFromElement(element); @@ -557,10 +561,7 @@ public boolean isCaretAtEndOfLine(PsiElement element) { public boolean isWhiteSpace(PsiElement element) { IElementType type = element.getNode().getElementType(); - if (type == TokenType.WHITE_SPACE) { - return true; - } - return false; + return type == TokenType.WHITE_SPACE; } public boolean isJavaDoc(PsiElement element) { @@ -645,19 +646,20 @@ public static YAMLKeyValue getYamlKeyValueAt(Project project, XSourcePosition po YAMLKeyValue keyValue = null; PsiElement psiElement = XDebuggerUtil.getInstance().findContextElement(file, position.getOffset(), project, false); - //This must be indent element because the position is at the beginning of the line - if (psiElement instanceof LeafPsiElement && "indent".equals(((LeafPsiElement) psiElement).getElementType().toString())) { - psiElement = psiElement.getNextSibling(); //This must be sequence item + // This must be the indent element because the position is at the beginning of the line + if (psiElement instanceof LeafPsiElement leafPsiElement && "indent".equals(leafPsiElement.getElementType().toString())) { + psiElement = psiElement.getNextSibling(); //This must be the sequence item Collection keyValues = null; - if (psiElement instanceof YAMLSequence) { //This is the beginning of sequence, get first item - psiElement = ((YAMLSequence) psiElement).getItems().get(0); + if (psiElement instanceof YAMLSequence yamlSequence) { + // This is the beginning of the sequence; get the first item + psiElement = yamlSequence.getItems().get(0); keyValues = ((YAMLSequenceItem) psiElement).getKeysValues(); - } else if (psiElement instanceof YAMLSequenceItem) { - keyValues = ((YAMLSequenceItem) psiElement).getKeysValues(); - } else if (psiElement instanceof YAMLKeyValue) { - keyValue = (YAMLKeyValue) psiElement; - } else if (psiElement instanceof YAMLMapping) { - keyValues = ((YAMLMapping) psiElement).getKeyValues(); + } else if (psiElement instanceof YAMLSequenceItem yamlSequenceItem) { + keyValues = yamlSequenceItem.getKeysValues(); + } else if (psiElement instanceof YAMLKeyValue yamlKeyValue) { + keyValue = yamlKeyValue; + } else if (psiElement instanceof YAMLMapping yamlMapping) { + keyValues = yamlMapping.getKeyValues(); } if (keyValues != null && !keyValues.isEmpty()) { keyValue = keyValues.iterator().next(); @@ -666,4 +668,13 @@ public static YAMLKeyValue getYamlKeyValueAt(Project project, XSourcePosition po return keyValue; } + + public static PsiClass findRouteBuilderClass(PsiManager manager) { + return ROUTE_BUILDER_OR_EXPRESSION_CLASS_QUALIFIED_NAME + .stream() + .map(fqn -> ClassUtil.findPsiClass(manager, fqn)) + .filter(Objects::nonNull) + .findFirst() + .orElse(null); + } } diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/JavaClassUtils.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/JavaClassUtils.java index cae02673..2816b5b6 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/JavaClassUtils.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/util/JavaClassUtils.java @@ -22,7 +22,6 @@ import java.util.Collections; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; @@ -56,6 +55,13 @@ public class JavaClassUtils implements Disposable { * The prefix of all the classes in the java lang package. */ private static final String JAVA_LANG_PACKAGE = "java.lang."; + private static final List BEAN_ANNOTATIONS = Arrays.asList( + "org.springframework.stereotype.Component", + "org.springframework.stereotype.Service", + "org.springframework.stereotype.Repository", + "javax.inject.Named", + "jakarta.inject.Named" + ); public static JavaClassUtils getService() { return ApplicationManager.getApplication().getService(JavaClassUtils.class); @@ -66,11 +72,12 @@ public static JavaClassUtils getService() { * to class name decapitalized */ public String getBeanName(PsiClass clazz) { - final String beanName = getBeanName(clazz, "org.springframework.stereotype.Component") - .orElseGet(() -> getBeanName(clazz, "org.springframework.stereotype.Service") - .orElseGet(() -> getBeanName(clazz, "org.springframework.stereotype.Repository") - .orElse(Introspector.decapitalize(clazz.getText())))); - return beanName; + return BEAN_ANNOTATIONS + .stream() + .map(annotation -> getBeanName(clazz, annotation)) + .flatMap(Optional::stream) + .findFirst() + .orElseGet(() -> Introspector.decapitalize(clazz.getText())); } /** @@ -97,10 +104,9 @@ public Optional findBeanClassByName(String beanName, String annotation if (beanName.equals(StringUtils.stripDoubleQuotes(value))) { return Optional.of(psiClass); } - } } else { - if (Introspector.decapitalize(psiClass.getName()).equalsIgnoreCase(StringUtils.stripDoubleQuotes(beanName))) { + if (StringUtils.stripDoubleQuotes(beanName).equalsIgnoreCase(Introspector.decapitalize(psiClass.getName()))) { return Optional.of(psiClass); } } @@ -127,9 +133,9 @@ private Collection getClassesAnnotatedWith(Project project, String ann public JavaClassReference findClassReference(@NotNull PsiElement element) { List references = Arrays.stream(element.getReferences()) - .filter(r -> r instanceof JavaClassReference) - .map(r -> (JavaClassReference) r) - .collect(Collectors.toList()); + .filter(JavaClassReference.class::isInstance) + .map(JavaClassReference.class::cast) + .toList(); if (!references.isEmpty()) { return references.get(references.size() - 1); } @@ -139,8 +145,8 @@ public JavaClassReference findClassReference(@NotNull PsiElement element) { public PsiClass resolveClassReference(@NotNull PsiReference reference) { final PsiElement resolveElement = reference.resolve(); - if (resolveElement instanceof PsiClass) { - return (PsiClass) resolveElement; + if (resolveElement instanceof PsiClass psiClass) { + return psiClass; } else if (resolveElement instanceof PsiField) { final PsiType psiType = PsiUtil.getTypeByPsiElement(resolveElement); if (psiType != null) { @@ -180,24 +186,12 @@ public String toSimpleType(@Nullable String type) { if (result.startsWith(JAVA_LANG_PACKAGE)) { result = result.substring(JAVA_LANG_PACKAGE.length()); } - switch (result) { - case "string": - case "long": - case "boolean": - case "double": - case "float": - case "short": - case "char": - case "byte": - case "int": - return result; - case "character": - return "char"; - case "integer": - return "int"; - default: - return type; - } + return switch (result) { + case "string", "long", "boolean", "double", "float", "short", "char", "byte", "int" -> result; + case "character" -> "char"; + case "integer" -> "int"; + default -> type; + }; } /** diff --git a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml index fcd3f795..33884d4f 100644 --- a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml +++ b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml @@ -79,8 +79,6 @@ - -