-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes #1114 Signed-off-by: azerr <[email protected]>
- Loading branch information
1 parent
3fbeb41
commit 95184a8
Showing
5 changed files
with
316 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
src/main/java/com/redhat/microprofile/psi/internal/quarkus/vertx/java/VertxWebConstants.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2023 Red Hat Inc. and others. | ||
* All rights reserved. This program and the accompanying materials | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v20.html | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Red Hat Inc. - initial API and implementation | ||
*******************************************************************************/ | ||
package com.redhat.microprofile.psi.internal.quarkus.vertx.java; | ||
|
||
/** | ||
* Constants important to working with Renarde applications. | ||
*/ | ||
public class VertxWebConstants { | ||
|
||
public static final String ROUTE_FQN = "io.quarkus.vertx.web.Route"; | ||
|
||
public static final String ROUTE_PATH = "path"; | ||
|
||
} |
143 changes: 143 additions & 0 deletions
143
...va/com/redhat/microprofile/psi/internal/quarkus/vertx/java/VertxWebJaxRsInfoProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2023 Red Hat Inc. and others. | ||
* All rights reserved. This program and the accompanying materials | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v20.html | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Red Hat Inc. - initial API and implementation | ||
*******************************************************************************/ | ||
package com.redhat.microprofile.psi.internal.quarkus.vertx.java; | ||
|
||
|
||
import com.intellij.openapi.module.Module; | ||
import com.intellij.openapi.progress.ProcessCanceledException; | ||
import com.intellij.openapi.progress.ProgressIndicator; | ||
import com.intellij.psi.*; | ||
import com.intellij.util.KeyedLazyInstanceEP; | ||
import com.redhat.devtools.intellij.lsp4ij.LSPIJUtils; | ||
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.jaxrs.*; | ||
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.utils.IPsiUtils; | ||
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.utils.PsiTypeUtils; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.Set; | ||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
|
||
import static com.redhat.devtools.intellij.lsp4mp4ij.psi.core.utils.AnnotationUtils.hasAnnotation; | ||
import static com.redhat.devtools.intellij.lsp4mp4ij.psi.core.utils.PsiTypeUtils.overlaps; | ||
import static com.redhat.microprofile.psi.internal.quarkus.vertx.java.VertxWebConstants.ROUTE_FQN; | ||
import static com.redhat.microprofile.psi.internal.quarkus.vertx.java.VertxWebUtils.getRouteAnnotation; | ||
|
||
/** | ||
* Use custom logic for all JAX-RS features in classes that extends Renarde's | ||
* <code>Controller</code> class. | ||
*/ | ||
public class VertxWebJaxRsInfoProvider extends KeyedLazyInstanceEP<IJaxRsInfoProvider> implements IJaxRsInfoProvider { | ||
|
||
private static final Logger LOGGER = Logger.getLogger(VertxWebJaxRsInfoProvider.class.getName()); | ||
|
||
@Override | ||
public boolean canProvideJaxRsMethodInfoForClass(PsiFile typeRoot, Module javaProject, ProgressIndicator monitor) { | ||
return PsiTypeUtils.findType(javaProject, ROUTE_FQN) != null; | ||
} | ||
|
||
@Override | ||
public Set<PsiClass> getAllJaxRsClasses(Module javaProject, ProgressIndicator monitor) { | ||
// TODO: implement when LSP4IJ will support workspace symbols | ||
return Collections.emptySet(); | ||
} | ||
|
||
@Override | ||
public List<JaxRsMethodInfo> getJaxRsMethodInfo(PsiFile typeRoot, JaxRsContext jaxrsContext, IPsiUtils utils, | ||
ProgressIndicator monitor) { | ||
try { | ||
PsiClass type = findFirstClass(typeRoot); | ||
if (type == null) { | ||
return Collections.emptyList(); | ||
} | ||
String pathSegment = null;//JaxRsUtils.getJaxRsPathValue(type); | ||
String typeSegment = type.getName(); | ||
|
||
List<JaxRsMethodInfo> methodInfos = new ArrayList<>(); | ||
for (PsiMethod method : type.getMethods()) { | ||
|
||
if (method.isConstructor() || utils.isHiddenGeneratedElement(method)) { | ||
continue; | ||
} | ||
// ignore element if method range overlaps the type range, | ||
// happens for generated | ||
// bytecode, i.e. with lombok | ||
if (overlaps(type.getNameIdentifier().getTextRange(), method.getNameIdentifier().getTextRange())) { | ||
continue; | ||
} | ||
|
||
//if (method.getModifierList().hasExplicitModifier(PsiModifier.PUBLIC)) { | ||
|
||
PsiAnnotation routeAnnotation = getRouteAnnotation(method); | ||
if (routeAnnotation == null) { | ||
continue; | ||
} | ||
|
||
// @Route(path="/foo") | ||
String methodSegment = VertxWebUtils.getRouteAnnotationPath(routeAnnotation); | ||
if (methodSegment == null) { | ||
methodSegment = method.getName(); | ||
} | ||
String path; | ||
if (pathSegment == null) { | ||
path = methodSegment.startsWith("/") ? methodSegment : JaxRsUtils.buildURL(typeSegment, methodSegment); | ||
} else { | ||
path = JaxRsUtils.buildURL(pathSegment, methodSegment); | ||
} | ||
String url = JaxRsUtils.buildURL(jaxrsContext.getLocalBaseURL(), path); | ||
|
||
JaxRsMethodInfo methodInfo = createMethodInfo(method, routeAnnotation, url); | ||
if (methodInfo != null) { | ||
methodInfos.add(methodInfo); | ||
} | ||
//} | ||
} | ||
return methodInfos; | ||
} catch (ProcessCanceledException e) { | ||
throw e; | ||
} catch (Exception e) { | ||
LOGGER.log(Level.SEVERE, "Error while collecting JAX-RS methods for Vertx Web @Route", e); | ||
return Collections.emptyList(); | ||
} | ||
} | ||
|
||
private PsiClass findFirstClass(PsiFile typeRoot) { | ||
for (PsiElement element:typeRoot.getChildren()) { | ||
if (element instanceof PsiClass) { | ||
return (PsiClass) element; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
private static JaxRsMethodInfo createMethodInfo(PsiMethod method, PsiAnnotation routeAnnotation, String url) { | ||
|
||
PsiFile resource = method.getContainingFile(); | ||
if (resource == null) { | ||
return null; | ||
} | ||
String documentUri = LSPIJUtils.toUriAsString(resource); | ||
|
||
HttpMethod httpMethod = HttpMethod.GET; | ||
for (String methodAnnotationFQN : JaxRsConstants.HTTP_METHOD_ANNOTATIONS) { | ||
if (hasAnnotation(method, methodAnnotationFQN)) { | ||
httpMethod = VertxWebUtils.getHttpMethodForAnnotation(methodAnnotationFQN); | ||
break; | ||
} | ||
} | ||
|
||
return new JaxRsMethodInfo(url, httpMethod, method, documentUri); | ||
} | ||
|
||
} |
146 changes: 146 additions & 0 deletions
146
src/main/java/com/redhat/microprofile/psi/internal/quarkus/vertx/java/VertxWebUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2020 Red Hat Inc. and others. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 | ||
* which is available at https://www.apache.org/licenses/LICENSE-2.0. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 | ||
* | ||
* Contributors: | ||
* Red Hat Inc. - initial API and implementation | ||
*******************************************************************************/ | ||
package com.redhat.microprofile.psi.internal.quarkus.vertx.java; | ||
|
||
import com.intellij.openapi.util.TextRange; | ||
import com.intellij.psi.PsiAnnotation; | ||
import com.intellij.psi.PsiElement; | ||
import com.intellij.psi.PsiMethod; | ||
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.jaxrs.HttpMethod; | ||
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.jaxrs.JaxRsConstants; | ||
import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.utils.IPsiUtils; | ||
import org.eclipse.lsp4j.CodeLens; | ||
import org.eclipse.lsp4j.Command; | ||
import org.eclipse.lsp4j.Position; | ||
import org.eclipse.lsp4j.Range; | ||
|
||
import java.util.Collections; | ||
|
||
import static com.redhat.devtools.intellij.lsp4mp4ij.psi.core.jaxrs.JaxRsConstants.*; | ||
import static com.redhat.devtools.intellij.lsp4mp4ij.psi.core.utils.AnnotationUtils.*; | ||
import static com.redhat.microprofile.psi.internal.quarkus.vertx.java.VertxWebConstants.ROUTE_FQN; | ||
import static com.redhat.microprofile.psi.internal.quarkus.vertx.java.VertxWebConstants.ROUTE_PATH; | ||
|
||
|
||
/** | ||
* JAX-RS utilities. | ||
* | ||
* @author Angelo ZERR | ||
* | ||
*/ | ||
public class VertxWebUtils { | ||
|
||
private VertxWebUtils() { | ||
|
||
} | ||
|
||
public static PsiAnnotation getRouteAnnotation(PsiElement annotatable) { | ||
return getFirstAnnotation(annotatable, ROUTE_FQN); | ||
} | ||
|
||
public static String getRouteAnnotationPath(PsiAnnotation routeAnnotation) { | ||
return getAnnotationMemberValue(routeAnnotation, ROUTE_PATH); | ||
} | ||
|
||
/** | ||
* Returns the value of the JAX-RS/Jakarta Path annotation and null otherwise.. | ||
* | ||
* @param annotatable the annotatable that might be annotated with the | ||
* JAX-RS/Jakarta Path annotation | ||
* @return the value of the JAX-RS/Jakarta Path annotation and null otherwise.. | ||
*/ | ||
public static String getJaxRsPathValue(PsiElement annotatable) { | ||
PsiAnnotation annotationPath = getFirstAnnotation(annotatable, JAVAX_WS_RS_PATH_ANNOTATION, | ||
JAKARTA_WS_RS_PATH_ANNOTATION); | ||
if (annotationPath == null) { | ||
return null; | ||
} | ||
return getAnnotationMemberValue(annotationPath, PATH_VALUE); | ||
} | ||
|
||
/** | ||
* Returns the value of the JAX-RS/Jakarta ApplicationPath annotation and null | ||
* otherwise. | ||
* | ||
* @param annotatable the annotatable that might be annotated with the | ||
* JAX-RS/Jakarta ApplicationPath annotation | ||
* @return the value of the JAX-RS/Jakarta ApplicationPath annotation and null | ||
* otherwise. | ||
*/ | ||
public static String getJaxRsApplicationPathValue(PsiElement annotatable) { | ||
PsiAnnotation annotationApplicationPath = getFirstAnnotation(annotatable, JAVAX_WS_RS_APPLICATIONPATH_ANNOTATION, | ||
JAKARTA_WS_RS_APPLICATIONPATH_ANNOTATION); | ||
if (annotationApplicationPath == null) { | ||
return null; | ||
} | ||
return getAnnotationMemberValue(annotationApplicationPath, PATH_VALUE); | ||
} | ||
|
||
/** | ||
* Returns true if the given method has @GET annotation and false otherwise. | ||
* | ||
* @param method the method. | ||
* @return true if the given method has @GET annotation and false otherwise. | ||
*/ | ||
public static boolean isClickableJaxRsRequestMethod(PsiMethod method) { | ||
return hasAnyAnnotation(method, JAVAX_WS_RS_GET_ANNOTATION, JAKARTA_WS_RS_GET_ANNOTATION); | ||
} | ||
|
||
/** | ||
* Returns true if the given method | ||
* has @GET, @POST, @PUT, @DELETE, @HEAD, @OPTIONS, or @PATCH annotation | ||
* and false otherwise. | ||
* | ||
* @param method the method. | ||
* @return true if the given method | ||
* has @GET, @POST, @PUT, @DELETE, @HEAD, @OPTIONS, or @PATCH annotation and | ||
* false otherwise. | ||
*/ | ||
public static boolean isJaxRsRequestMethod(PsiMethod method) { | ||
return hasAnyAnnotation(method, HTTP_METHOD_ANNOTATIONS); | ||
} | ||
|
||
/** | ||
* Returns an HttpMethod given the FQN of a JAX-RS or Jakarta RESTful | ||
* annotation, nor null if the FQN doesn't match any HttpMethod. | ||
* | ||
* @param annotationFQN the FQN of the annotation to convert into a HttpMethod | ||
* @return an HttpMethod given the FQN of a JAX-RS or Jakarta RESTful | ||
* annotation, nor null if the FQN doesn't match any HttpMethod | ||
*/ | ||
public static HttpMethod getHttpMethodForAnnotation(String annotationFQN) { | ||
switch (annotationFQN) { | ||
case JaxRsConstants.JAKARTA_WS_RS_GET_ANNOTATION: | ||
case JaxRsConstants.JAVAX_WS_RS_GET_ANNOTATION: | ||
return HttpMethod.GET; | ||
case JaxRsConstants.JAKARTA_WS_RS_HEAD_ANNOTATION: | ||
case JaxRsConstants.JAVAX_WS_RS_HEAD_ANNOTATION: | ||
return HttpMethod.HEAD; | ||
case JaxRsConstants.JAKARTA_WS_RS_POST_ANNOTATION: | ||
case JaxRsConstants.JAVAX_WS_RS_POST_ANNOTATION: | ||
return HttpMethod.POST; | ||
case JaxRsConstants.JAKARTA_WS_RS_PUT_ANNOTATION: | ||
case JaxRsConstants.JAVAX_WS_RS_PUT_ANNOTATION: | ||
return HttpMethod.PUT; | ||
case JaxRsConstants.JAKARTA_WS_RS_DELETE_ANNOTATION: | ||
case JaxRsConstants.JAVAX_WS_RS_DELETE_ANNOTATION: | ||
return HttpMethod.DELETE; | ||
case JaxRsConstants.JAKARTA_WS_RS_PATCH_ANNOTATION: | ||
case JaxRsConstants.JAVAX_WS_RS_PATCH_ANNOTATION: | ||
return HttpMethod.PATCH; | ||
default: | ||
return null; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters