|
14 | 14 | package com.redhat.devtools.intellij.lsp4mp4ij.psi.core;
|
15 | 15 |
|
16 | 16 | import com.intellij.codeInsight.daemon.ImplicitUsageProvider;
|
17 |
| -import com.intellij.psi.PsiElement; |
| 17 | +import com.intellij.psi.*; |
18 | 18 | import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.jaxrs.JaxRsConstants;
|
19 | 19 | import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.utils.AnnotationUtils;
|
20 | 20 | import com.redhat.devtools.intellij.lsp4mp4ij.psi.internal.restclient.MicroProfileRestClientConstants;
|
21 | 21 | import org.jetbrains.annotations.NotNull;
|
22 | 22 |
|
23 | 23 | /**
|
24 |
| - * Automatically declares as used, methods annotated with jakarta.ws.rs.* or javax.ws.rs.* HTTP annotations, |
25 |
| - * or {@link org.eclipse.microprofile.rest.client.inject.RestClient} |
| 24 | + * Automatically declares the following as used: |
| 25 | + * <ul> |
| 26 | + * <li>methods annotated with jakarta.ws.rs.* or javax.ws.rs.* HTTP annotations, or {@link org.eclipse.microprofile.rest.client.inject.RestClient}</li> |
| 27 | + * <li>non-abstract public observer methods, i.e. with a parameter annotated with <code>@jakarta.enterprise.event.Observes</code></li> |
| 28 | + * </ul> |
| 29 | + * |
| 30 | + * |
| 31 | + * |
26 | 32 | */
|
27 | 33 | public class JavaEEImplicitUsageProvider implements ImplicitUsageProvider {
|
28 | 34 |
|
| 35 | + private static final String JAKARTA_OBSERVES = "jakarta.enterprise.event.Observes"; |
| 36 | + private static final String JAVAX_OBSERVES = "javax.enterprise.event.Observes"; |
| 37 | + |
| 38 | + |
29 | 39 | @Override
|
30 | 40 | public boolean isImplicitUsage(@NotNull PsiElement element) {
|
31 | 41 | return isImplicitRead(element) || isImplicitWrite(element);
|
32 | 42 | }
|
33 | 43 |
|
34 | 44 | @Override
|
35 | 45 | public boolean isImplicitRead(@NotNull PsiElement element) {
|
| 46 | + return isHttpOrRestClient(element) || isObserverMethod(element); |
| 47 | + } |
| 48 | + |
| 49 | + private boolean isObserverMethod(@NotNull PsiElement element) { |
| 50 | + if (element instanceof PsiMethod) { |
| 51 | + PsiMethod method = (PsiMethod) element; |
| 52 | + return isPublicNonAbstract(method) && observesOneParameter(method); |
| 53 | + } |
| 54 | + return false; |
| 55 | + } |
| 56 | + |
| 57 | + private boolean observesOneParameter(PsiMethod method) { |
| 58 | + //XXX ideally we might want to check if the parent class is a managed bean class or session bean class (or of an extension) |
| 59 | + //But that might prove a bit complex, so let's skip this part for now. |
| 60 | + |
| 61 | + PsiParameter[] parameters = method.getParameterList().getParameters(); |
| 62 | + |
| 63 | + int observesAnnotationCount = 0; |
| 64 | + |
| 65 | + for (PsiParameter parameter : parameters) { |
| 66 | + if (AnnotationUtils.hasAnyAnnotation(parameter, JAKARTA_OBSERVES, JAVAX_OBSERVES)) { |
| 67 | + observesAnnotationCount++; |
| 68 | + if (observesAnnotationCount > 1) { |
| 69 | + return false; |
| 70 | + } |
| 71 | + } |
| 72 | + } |
| 73 | + |
| 74 | + return observesAnnotationCount == 1; |
| 75 | + } |
| 76 | + |
| 77 | + private boolean isPublicNonAbstract(@NotNull PsiMethod method) { |
| 78 | + return !method.isConstructor() && |
| 79 | + method.hasModifierProperty(PsiModifier.PUBLIC) && |
| 80 | + !method.hasModifierProperty(PsiModifier.ABSTRACT); |
| 81 | + } |
| 82 | + |
| 83 | + private boolean isHttpOrRestClient(@NotNull PsiElement element) { |
36 | 84 | return AnnotationUtils.hasAnyAnnotation(element, JaxRsConstants.HTTP_METHOD_ANNOTATIONS) ||
|
37 | 85 | AnnotationUtils.hasAnnotation(element, MicroProfileRestClientConstants.REST_CLIENT_ANNOTATION);
|
38 | 86 | }
|
|
0 commit comments