From 3a2b5173ebb5759d0bb4df502edf345ae08bcabc Mon Sep 17 00:00:00 2001 From: Michael Glavassevich Date: Thu, 27 Jul 2023 14:54:27 -0400 Subject: [PATCH 1/9] Proof-of-concept for unifying the design for MicroProfile and Jakarta EE code actions. Signed-off-by: Michael Glavassevich --- .../lsp4ij/PropertiesManagerForJakarta.java | 24 +++++++- .../NonPublicResourceMethodQuickFix.java | 60 +++++++++++++++---- .../psi/core/PropertiesManagerForJava.java | 2 +- .../java/codeaction/CodeActionHandler.java | 8 +++ .../codeaction/JavaCodeActionDefinition.java | 15 ++++- src/main/resources/META-INF/plugin.xml | 15 +++++ 6 files changed, 108 insertions(+), 16 deletions(-) diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/PropertiesManagerForJakarta.java b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/PropertiesManagerForJakarta.java index dd3fa994e..847b9d7ad 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/PropertiesManagerForJakarta.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/PropertiesManagerForJakarta.java @@ -41,6 +41,7 @@ import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.servlet.ServletDiagnosticsCollector; import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.websocket.WebSocketDiagnosticsCollector; import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.utils.IPsiUtils; +import io.openliberty.tools.intellij.lsp4mp4ij.psi.internal.core.java.codeaction.CodeActionHandler; import io.openliberty.tools.intellij.lsp4mp4ij.psi.internal.core.ls.PsiUtilsLSImpl; import org.eclipse.lsp4j.*; import org.eclipse.lsp4jakarta.commons.*; @@ -66,7 +67,7 @@ public static PropertiesManagerForJakarta getInstance() { } private List diagnosticsCollectors = new ArrayList<>(); - private JakartaCodeActionHandler codeActionHandler = new JakartaCodeActionHandler(); + private final CodeActionHandler codeActionHandler; private PropertiesManagerForJakarta() { diagnosticsCollectors.add(new ServletDiagnosticsCollector()); @@ -83,7 +84,7 @@ private PropertiesManagerForJakarta() { diagnosticsCollectors.add(new DependencyInjectionDiagnosticsCollector()); diagnosticsCollectors.add(new JsonpDiagnosticCollector()); diagnosticsCollectors.add(new WebSocketDiagnosticsCollector()); - codeActionHandler = new JakartaCodeActionHandler(); + codeActionHandler = new CodeActionHandler("jakarta"); } /** @@ -405,7 +406,24 @@ private static PsiFile resolveTypeRoot(String uri, Project project) { public List getCodeAction(JakartaJavaCodeActionParams params, IPsiUtils utils) { return ApplicationManager.getApplication().runReadAction((Computable>) () -> { - return codeActionHandler.codeAction(params, utils); + final List unresolvedCodeActions = codeActionHandler.codeAction(adapt(params), utils); + if (unresolvedCodeActions != null) { + final List resolvedCodeActions = new ArrayList<>(unresolvedCodeActions.size()); + unresolvedCodeActions.forEach(unresolvedCodeAction -> { + if (unresolvedCodeAction != null) { + resolvedCodeActions.add(codeActionHandler.resolveCodeAction(unresolvedCodeAction, utils)); + } + }); + return resolvedCodeActions; + } + return null; }); } + + private MicroProfileJavaCodeActionParams adapt(JakartaJavaCodeActionParams params) { + MicroProfileJavaCodeActionParams mpParams = new MicroProfileJavaCodeActionParams(params.getTextDocument(), params.getRange(), params.getContext()); + mpParams.setResourceOperationSupported(params.isResourceOperationSupported()); + mpParams.setResolveSupported(true); + return mpParams; + } } diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/jax_rs/NonPublicResourceMethodQuickFix.java b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/jax_rs/NonPublicResourceMethodQuickFix.java index 8beef5c88..581d38526 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/jax_rs/NonPublicResourceMethodQuickFix.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/jax_rs/NonPublicResourceMethodQuickFix.java @@ -18,13 +18,20 @@ import com.intellij.psi.PsiMethod; import com.intellij.psi.util.PsiTreeUtil; import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.codeAction.proposal.ModifyModifiersProposal; +import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.ExtendedCodeAction; +import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.IJavaCodeActionParticipant; import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.JavaCodeActionContext; +import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.JavaCodeActionResolveContext; import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.corrections.proposal.ChangeCorrectionProposal; import org.eclipse.lsp4j.CodeAction; +import org.eclipse.lsp4j.CodeActionKind; import org.eclipse.lsp4j.Diagnostic; +import org.eclipse.lsp4j.WorkspaceEdit; +import org.eclipse.lsp4mp.commons.CodeActionResolveData; -import java.util.Collections; -import java.util.List; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; /** * Quick fix for ResourceMethodDiagnosticsCollector that uses @@ -33,26 +40,57 @@ * @author Matthew Shocrylas * */ -public class NonPublicResourceMethodQuickFix { +public class NonPublicResourceMethodQuickFix implements IJavaCodeActionParticipant { + + private static final Logger LOGGER = Logger.getLogger(NonPublicResourceMethodQuickFix.class.getName()); private final static String TITLE_MESSAGE = "Make method public"; + @Override + public String getParticipantId() { + return NonPublicResourceMethodQuickFix.class.getName(); + } + public List getCodeActions(JavaCodeActionContext context, Diagnostic diagnostic) { final PsiElement node = context.getCoveredNode(); - final PsiClass parentType = PsiTreeUtil.getParentOfType(node, PsiClass.class); final PsiMethod parentMethod = PsiTreeUtil.getParentOfType(node, PsiMethod.class); if (parentMethod != null) { - ChangeCorrectionProposal proposal = new ModifyModifiersProposal(TITLE_MESSAGE, context.getSource().getCompilationUnit(), - context.getASTRoot(), parentType, 0, parentMethod.getModifierList(), Collections.singletonList("public")); - - // Convert the proposal to LSP4J CodeAction - CodeAction codeAction = context.convertToCodeAction(proposal, diagnostic); - codeAction.setTitle(TITLE_MESSAGE); - return Collections.singletonList(codeAction); + return Collections.singletonList(createCodeAction(context, diagnostic)); } return Collections.emptyList(); } + @Override + public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) { + + final CodeAction toResolve = context.getUnresolved(); + final PsiElement node = context.getCoveredNode(); + final PsiClass parentType = PsiTreeUtil.getParentOfType(node, PsiClass.class); + final PsiMethod parentMethod = PsiTreeUtil.getParentOfType(node, PsiMethod.class); + + assert parentMethod != null; + ChangeCorrectionProposal proposal = new ModifyModifiersProposal(TITLE_MESSAGE, context.getSource().getCompilationUnit(), + context.getASTRoot(), parentType, 0, parentMethod.getModifierList(), Collections.singletonList("public")); + try { + WorkspaceEdit we = context.convertToWorkspaceEdit(proposal); + toResolve.setEdit(we); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Unable to create workspace edit for code action to make method public", e); + } + return toResolve; + } + + private CodeAction createCodeAction(JavaCodeActionContext context, Diagnostic diagnostic) { + ExtendedCodeAction codeAction = new ExtendedCodeAction(TITLE_MESSAGE); + codeAction.setRelevance(0); + codeAction.setDiagnostics(Collections.singletonList(diagnostic)); + codeAction.setKind(CodeActionKind.QuickFix); + codeAction.setData(new CodeActionResolveData(context.getUri(), getParticipantId(), + context.getParams().getRange(), Collections.emptyMap(), + context.getParams().isResourceOperationSupported(), + context.getParams().isCommandConfigurationUpdateSupported())); + return codeAction; + } } diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4mp4ij/psi/core/PropertiesManagerForJava.java b/src/main/java/io/openliberty/tools/intellij/lsp4mp4ij/psi/core/PropertiesManagerForJava.java index 25592fe70..ffef54644 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4mp4ij/psi/core/PropertiesManagerForJava.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4mp4ij/psi/core/PropertiesManagerForJava.java @@ -87,7 +87,7 @@ public static PropertiesManagerForJava getInstance() { private final CodeActionHandler codeActionHandler; private PropertiesManagerForJava() { - this.codeActionHandler = new CodeActionHandler(); + this.codeActionHandler = new CodeActionHandler("mp"); } /** diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4mp4ij/psi/internal/core/java/codeaction/CodeActionHandler.java b/src/main/java/io/openliberty/tools/intellij/lsp4mp4ij/psi/internal/core/java/codeaction/CodeActionHandler.java index 713f36344..a6bf1347e 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4mp4ij/psi/internal/core/java/codeaction/CodeActionHandler.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4mp4ij/psi/internal/core/java/codeaction/CodeActionHandler.java @@ -47,6 +47,12 @@ */ public class CodeActionHandler { + private final String group; + + public CodeActionHandler(String group) { + this.group = group; + } + /** * Returns all the code actions applicable for the context given by the * parameters. @@ -98,6 +104,7 @@ public List codeAction(MicroProfileJavaCodeActionParams pa // Get list of code action definition for the given kind List codeActionDefinitions = io.openliberty.tools.intellij.lsp4mp4ij.psi.internal.core.java.codeaction.JavaCodeActionDefinition.EP.extensions() .filter(definition -> definition.isAdaptedForCodeAction(context)) + .filter(definition -> group.equals(definition.getGroup())) .filter(definition -> codeActionKind.equals(definition.getKind())) .collect(Collectors.toList()); if (codeActionDefinitions != null) { @@ -201,6 +208,7 @@ public CodeAction resolveCodeAction(CodeAction unresolved, IPsiUtils utils) { IJavaCodeActionParticipant participant = JavaCodeActionDefinition.EP.extensions() .filter(definition -> unresolved.getKind().startsWith(definition.getKind())) + .filter(definition -> group.equals(definition.getGroup())) .filter(definition -> participantId.equals(definition.getParticipantId())) .findFirst().orElse(null); return participant.resolveCodeAction(context.copy()); diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4mp4ij/psi/internal/core/java/codeaction/JavaCodeActionDefinition.java b/src/main/java/io/openliberty/tools/intellij/lsp4mp4ij/psi/internal/core/java/codeaction/JavaCodeActionDefinition.java index 6d48ae62f..e452bf9f2 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4mp4ij/psi/internal/core/java/codeaction/JavaCodeActionDefinition.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4mp4ij/psi/internal/core/java/codeaction/JavaCodeActionDefinition.java @@ -41,11 +41,15 @@ public class JavaCodeActionDefinition extends BaseKeyedLazyInstance + + From 686172be66407935e3867c9fd18c1170d4cdf833 Mon Sep 17 00:00:00 2001 From: dessina-devasia <143582034+dessina-devasia@users.noreply.github.com> Date: Wed, 4 Oct 2023 13:22:25 +0530 Subject: [PATCH 2/9] [feature/#23]: Refactor the implementation for FilterImplementationQuickFix and ListenerImplementationQuickFix --- .../codeAction/JakartaCodeActionHandler.java | 8 -- .../servlet/FilterImplementationQuickFix.java | 64 ++++++++++--- .../ListenerImplementationQuickFix.java | 96 +++++++++++++------ .../servlet/ServletDiagnosticsCollector.java | 19 ++++ src/main/resources/META-INF/plugin.xml | 10 ++ .../jdt/core/messages/messages.properties | 2 + .../it/servlet/JakartaServletTest.java | 52 ++++++++++ .../jakarta/servlet/DontImplementFilter.java | 8 ++ .../servlet/DontImplementListener.java | 8 ++ 9 files changed, 219 insertions(+), 48 deletions(-) create mode 100644 src/test/resources/projects/maven/jakarta-sample/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementFilter.java create mode 100644 src/test/resources/projects/maven/jakarta-sample/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementListener.java diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/codeAction/JakartaCodeActionHandler.java b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/codeAction/JakartaCodeActionHandler.java index ebf372a8a..f77ac7cc9 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/codeAction/JakartaCodeActionHandler.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/codeAction/JakartaCodeActionHandler.java @@ -91,8 +91,6 @@ public List codeAction(JakartaJavaCodeActionParams params, IPsiUtils List codeActions = new ArrayList<>(); HttpServletQuickFix HttpServletQuickFix = new HttpServletQuickFix(); - FilterImplementationQuickFix FilterImplementationQuickFix = new FilterImplementationQuickFix(); - ListenerImplementationQuickFix ListenerImplementationQuickFix = new ListenerImplementationQuickFix(); CompleteServletAnnotationQuickFix CompleteServletAnnotationQuickFix = new CompleteServletAnnotationQuickFix(); CompleteFilterAnnotationQuickFix CompleteFilterAnnotationQuickFix = new CompleteFilterAnnotationQuickFix(); PersistenceAnnotationQuickFix PersistenceAnnotationQuickFix = new PersistenceAnnotationQuickFix(); @@ -128,12 +126,6 @@ public List codeAction(JakartaJavaCodeActionParams params, IPsiUtils if (diagnostic.getCode().getLeft().equals(ServletConstants.DIAGNOSTIC_CODE)) { codeActions.addAll(HttpServletQuickFix.getCodeActions(context, diagnostic)); } - if (diagnostic.getCode().getLeft().equals(ServletConstants.DIAGNOSTIC_CODE_FILTER)) { - codeActions.addAll(FilterImplementationQuickFix.getCodeActions(context, diagnostic)); - } - if (diagnostic.getCode().getLeft().equals(ServletConstants.DIAGNOSTIC_CODE_LISTENER)) { - codeActions.addAll(ListenerImplementationQuickFix.getCodeActions(context, diagnostic)); - } if (diagnostic.getCode().getLeft().equals(AnnotationConstants.DIAGNOSTIC_CODE_MISSING_RESOURCE_NAME_ATTRIBUTE)) { codeActions.addAll(AddResourceMissingNameQuickFix.getCodeActions(context, diagnostic)); } diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java index 43ac52c03..2b47be14c 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java @@ -16,15 +16,26 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; import com.intellij.psi.util.PsiTreeUtil; +import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.Messages; +import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.ExtendedCodeAction; +import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.IJavaCodeActionParticipant; import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.JavaCodeActionContext; +import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.JavaCodeActionResolveContext; import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.corrections.proposal.ChangeCorrectionProposal; import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.corrections.proposal.ImplementInterfaceProposal; import org.eclipse.lsp4j.CodeAction; +import org.eclipse.lsp4j.CodeActionKind; import org.eclipse.lsp4j.Diagnostic; +import org.eclipse.lsp4j.WorkspaceEdit; +import org.eclipse.lsp4mp.commons.CodeActionResolveData; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; /** * QuickFix for fixing HttpServlet extension error by providing the code actions @@ -36,27 +47,58 @@ * @author Credit to Angelo ZERR * */ -public class FilterImplementationQuickFix { +public class FilterImplementationQuickFix implements IJavaCodeActionParticipant { + private static final Logger LOGGER = Logger.getLogger(FilterImplementationQuickFix.class.getName()); + + private final static String TITLE_MESSAGE = Messages.getMessage("LetClassImplement"); + @Override + public String getParticipantId() { + return FilterImplementationQuickFix.class.getName(); + } public List getCodeActions(JavaCodeActionContext context, Diagnostic diagnostic) { List codeActions = new ArrayList<>(); PsiElement node = context.getCoveredNode(); PsiClass parentType = getBinding(node); if (parentType != null) { - // Create code action - // interface - ChangeCorrectionProposal proposal = new ImplementInterfaceProposal( - null, parentType, context.getASTRoot(), - "jakarta.servlet.Filter", 0, context.getSource().getCompilationUnit()); - CodeAction codeAction = context.convertToCodeAction(proposal, diagnostic); - - if (codeAction != null) { - codeActions.add(codeAction); - } + codeActions.add(createCodeAction(context, diagnostic)); } return codeActions; } + @Override + public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) { + + final CodeAction toResolve = context.getUnresolved(); + final PsiElement node = context.getCoveredNode(); + final PsiClass parentType = getBinding(node); + final PsiMethod parentMethod = PsiTreeUtil.getParentOfType(node, PsiMethod.class); + + assert parentMethod != null; + ChangeCorrectionProposal proposal = new ImplementInterfaceProposal( + null, parentType, context.getASTRoot(), + "jakarta.servlet.Filter", 0, context.getSource().getCompilationUnit()); + try { + WorkspaceEdit we = context.convertToWorkspaceEdit(proposal); + toResolve.setEdit(we); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Unable to create workspace edit for code action to filter implementation", e); + } + return toResolve; + } + + private CodeAction createCodeAction(JavaCodeActionContext context, Diagnostic diagnostic) { + ExtendedCodeAction codeAction = new ExtendedCodeAction(TITLE_MESSAGE); + codeAction.setRelevance(0); + codeAction.setDiagnostics(Collections.singletonList(diagnostic)); + codeAction.setKind(CodeActionKind.QuickFix); + codeAction.setData(new CodeActionResolveData(context.getUri(), getParticipantId(), + context.getParams().getRange(), Collections.emptyMap(), + context.getParams().isResourceOperationSupported(), + context.getParams().isCommandConfigurationUpdateSupported())); + return codeAction; + } + private PsiClass getBinding(PsiElement node) { return PsiTreeUtil.getParentOfType(node, PsiClass.class); } diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java index 1b54e40dc..9645c9c6a 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java @@ -17,15 +17,27 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; import com.intellij.psi.util.PsiTreeUtil; +import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.Messages; +import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.ExtendedCodeAction; +import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.IJavaCodeActionParticipant; import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.JavaCodeActionContext; +import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.JavaCodeActionResolveContext; import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.corrections.proposal.ChangeCorrectionProposal; import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.corrections.proposal.ImplementInterfaceProposal; import org.eclipse.lsp4j.CodeAction; +import org.eclipse.lsp4j.CodeActionKind; import org.eclipse.lsp4j.Diagnostic; +import org.eclipse.lsp4j.WorkspaceEdit; +import org.eclipse.lsp4mp.commons.CodeActionResolveData; +import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; /** * QuickFix for fixing HttpServlet extension error by providing the code actions @@ -38,48 +50,74 @@ * */ -public class ListenerImplementationQuickFix { +public class ListenerImplementationQuickFix implements IJavaCodeActionParticipant { + + private static final Logger LOGGER = Logger.getLogger(ListenerImplementationQuickFix.class.getName()); + + private final static String TITLE_MESSAGE = Messages.getMessage("LetClassImplement"); + @Override + public String getParticipantId() { + return ListenerImplementationQuickFix.class.getName(); + } + public List getCodeActions(JavaCodeActionContext context, Diagnostic diagnostic) { List codeActions = new ArrayList<>(); - // Create code action - // interface - setUpCodeAction(codeActions, diagnostic, context, ServletConstants.SERVLET_CONTEXT_LISTENER, - "jakarta.servlet.ServletContextListener"); - setUpCodeAction(codeActions, diagnostic, context, + String[] listenerConstants = { + ServletConstants.SERVLET_CONTEXT_LISTENER, ServletConstants.SERVLET_CONTEXT_ATTRIBUTE_LISTENER, - "jakarta.servlet.ServletContextAttributeListener"); - setUpCodeAction(codeActions, diagnostic, context, ServletConstants.SERVLET_REQUEST_LISTENER, - "jakarta.servlet.ServletRequestListener"); - setUpCodeAction(codeActions, diagnostic, context, + ServletConstants.SERVLET_REQUEST_LISTENER, ServletConstants.SERVLET_REQUEST_ATTRIBUTE_LISTENER, - "jakarta.servlet.ServletRequestAttributeListener"); - setUpCodeAction(codeActions, diagnostic, context, ServletConstants.HTTP_SESSION_LISTENER, - "jakarta.servlet.http.HttpSessionListener"); - setUpCodeAction(codeActions, diagnostic, context, + ServletConstants.HTTP_SESSION_LISTENER, ServletConstants.HTTP_SESSION_ATTRIBUTE_LISTENER, - "jakarta.servlet.http.HttpSessionAttributeListener"); - setUpCodeAction(codeActions, diagnostic, context, ServletConstants.HTTP_SESSION_ID_LISTENER, - "jakarta.servlet.http.HttpSessionIdListener"); + ServletConstants.HTTP_SESSION_ID_LISTENER + }; + + for (String constant : listenerConstants) { + String httpExt = (constant.contains("HTTP")) ? "http." : ""; + String interfaceType = "jakarta.servlet." + httpExt + constant; + context.put("interface", interfaceType); + + codeActions.add(createCodeAction(context, diagnostic)); + } return codeActions; } + @Override + public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) { + final CodeAction toResolve = context.getUnresolved(); + final PsiElement node = context.getCoveredNode(); + final PsiClass parentType = getBinding(node); + final PsiMethod parentMethod = PsiTreeUtil.getParentOfType(node, PsiMethod.class); + String interfaceType = (String) context.get("interface"); + + assert parentMethod != null; + ChangeCorrectionProposal proposal = new ImplementInterfaceProposal( + null, parentType, context.getASTRoot(), interfaceType, 0, + context.getCompilationUnit()); + try { + WorkspaceEdit we = context.convertToWorkspaceEdit(proposal); + toResolve.setEdit(we); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Unable to create workspace edit for code action to listener implementation", e); + } + return toResolve; + } + private PsiClass getBinding(PsiElement node) { return PsiTreeUtil.getParentOfType(node, PsiClass.class); } - private void setUpCodeAction(List codeActions, Diagnostic diagnostic, JavaCodeActionContext sourceContext, - String interfaceName, String interfaceType) { - JavaCodeActionContext targetContext = sourceContext.copy(); - PsiElement node = targetContext.getCoveredNode(); // find covered node in the new context - PsiClass targetType = getBinding(node); - if (targetType != null) { - ChangeCorrectionProposal proposal = new ImplementInterfaceProposal( - null, targetType, targetContext.getASTRoot(), interfaceType, 0, - sourceContext.getCompilationUnit()); - CodeAction codeAction = targetContext.convertToCodeAction(proposal, diagnostic); - codeActions.add(codeAction); - } + private CodeAction createCodeAction(JavaCodeActionContext context, Diagnostic diagnostic) { + ExtendedCodeAction codeAction = new ExtendedCodeAction(TITLE_MESSAGE); + codeAction.setRelevance(0); + codeAction.setDiagnostics(Collections.singletonList(diagnostic)); + codeAction.setKind(CodeActionKind.QuickFix); + codeAction.setData(new CodeActionResolveData(context.getUri(), getParticipantId(), + context.getParams().getRange(), Collections.emptyMap(), + context.getParams().isResourceOperationSupported(), + context.getParams().isCommandConfigurationUpdateSupported())); + return codeAction; } } diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ServletDiagnosticsCollector.java b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ServletDiagnosticsCollector.java index 94f6f698e..3d56ef521 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ServletDiagnosticsCollector.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ServletDiagnosticsCollector.java @@ -112,6 +112,25 @@ public void collectDiagnostics(PsiJavaFile unit, List diagnostics) { ServletConstants.DIAGNOSTIC_CODE_DUPLICATE_ATTRIBUTES, null, DiagnosticSeverity.Error)); } + + + /* Filter implementation diagnostic check */ + PsiClass filterInterface = facade.findClass(ServletConstants.FILTER_FQ_NAME, + GlobalSearchScope.allScope(type.getProject())); + if (!type.isInheritor(filterInterface, true)) { + diagnostics.add(createDiagnostic(type, unit, + Messages.getMessage("WebServletMustImplementFilter"), + ServletConstants.DIAGNOSTIC_CODE_FILTER, null, DiagnosticSeverity.Error)); + } + + /* Listener implementation diagnostic check */ + /*PsiClass listenerInterface = facade.findClass(ServletConstants.LISTENER_FQ_NAME, + GlobalSearchScope.allScope(type.getProject())); + if (!type.isInheritor(filterInterface, true)) { + diagnostics.add(createDiagnostic(type, unit, + Messages.getMessage("WebServletMustImplementListener"), + ServletConstants.DIAGNOSTIC_CODE_LISTENER, null, DiagnosticSeverity.Error)); + }*/ } } } diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 46307861d..243c052b7 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -167,6 +167,16 @@ targetDiagnostic="jakarta-jax_rs#NonPublicResourceMethod" implementationClass="io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.jax_rs.NonPublicResourceMethodQuickFix"/> + + + + diff --git a/src/main/resources/org/eclipse/lsp4jakarta/jdt/core/messages/messages.properties b/src/main/resources/org/eclipse/lsp4jakarta/jdt/core/messages/messages.properties index e8a9d72e1..572480fe6 100644 --- a/src/main/resources/org/eclipse/lsp4jakarta/jdt/core/messages/messages.properties +++ b/src/main/resources/org/eclipse/lsp4jakarta/jdt/core/messages/messages.properties @@ -163,6 +163,8 @@ WebServletMustExtend = Annotated classes with @WebServlet must extend the HttpSe WebServletShouldExtend = Annotated classes with @WebServlet should extend the HttpServlet class. WebServletMustDefine = The @WebServlet annotation must define the attribute 'urlPatterns' or 'value'. WebServletCannotHaveBoth = The @WebServlet annotation cannot have both 'value' and 'urlPatterns' attributes specified at once. +WebServletMustImplementFilter = Annotated classes with @WebServlet must implement the Filter interface. +WebServletMustImplementListener = Annotated classes with @WebServlet must implement the Listener interface. # WebSocketDiagnosticsCollector WebSocketParamType = Invalid parameter type. When using {0}, parameter must be of type: \n- {1}\n- annotated with @PathParams and of type String or any Java primitive type or boxed version thereof. diff --git a/src/test/java/io/openliberty/tools/intellij/lsp4jakarta/it/servlet/JakartaServletTest.java b/src/test/java/io/openliberty/tools/intellij/lsp4jakarta/it/servlet/JakartaServletTest.java index 688fa6b62..13e5febba 100644 --- a/src/test/java/io/openliberty/tools/intellij/lsp4jakarta/it/servlet/JakartaServletTest.java +++ b/src/test/java/io/openliberty/tools/intellij/lsp4jakarta/it/servlet/JakartaServletTest.java @@ -95,4 +95,56 @@ public void CompleteWebServletAnnotation() throws Exception { } } + @Test + public void implementFilter() throws Exception { + Module module = createMavenModule(new File("src/test/resources/projects/maven/jakarta-sample")); + IPsiUtils utils = PsiUtilsLSImpl.getInstance(myProject); + + VirtualFile javaFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(ModuleUtilCore.getModuleDirPath(module) + + "/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementFilter.java"); + String uri = VfsUtilCore.virtualToIoFile(javaFile).toURI().toString(); + + JakartaDiagnosticsParams diagnosticsParams = new JakartaDiagnosticsParams(); + diagnosticsParams.setUris(Arrays.asList(uri)); + + Diagnostic d = JakartaForJavaAssert.d(5, 13, 34, "Annotated classes with @WebServlet must implement the Filter interface.", + DiagnosticSeverity.Error, "jakarta-servlet", "ImplementFilter"); + + JakartaForJavaAssert.assertJavaDiagnostics(diagnosticsParams, utils, d); + + if (CHECK_CODE_ACTIONS) { + // test associated quick-fix code action + JakartaJavaCodeActionParams codeActionParams = JakartaForJavaAssert.createCodeActionParams(uri, d); + TextEdit te = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Filter"); + CodeAction ca = JakartaForJavaAssert.ca(uri, "Let 'DontImplementFilter' implement 'Filter'", d, te); + JakartaForJavaAssert.assertJavaCodeAction(codeActionParams, utils, ca); + } + } + + @Test + public void implementListener() throws Exception { + Module module = createMavenModule(new File("src/test/resources/projects/maven/jakarta-sample")); + IPsiUtils utils = PsiUtilsLSImpl.getInstance(myProject); + + VirtualFile javaFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(ModuleUtilCore.getModuleDirPath(module) + + "/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementListener.java"); + String uri = VfsUtilCore.virtualToIoFile(javaFile).toURI().toString(); + + JakartaDiagnosticsParams diagnosticsParams = new JakartaDiagnosticsParams(); + diagnosticsParams.setUris(Arrays.asList(uri)); + + Diagnostic d = JakartaForJavaAssert.d(5, 13, 34, "Annotated classes with @WebServlet must implement the Listener interface.", + DiagnosticSeverity.Error, "jakarta-servlet", "ImplementListener"); + + JakartaForJavaAssert.assertJavaDiagnostics(diagnosticsParams, utils, d); + + if (CHECK_CODE_ACTIONS) { + // test associated quick-fix code action + JakartaJavaCodeActionParams codeActionParams = JakartaForJavaAssert.createCodeActionParams(uri, d); + TextEdit te = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); + CodeAction ca = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'Listener'", d, te); + JakartaForJavaAssert.assertJavaCodeAction(codeActionParams, utils, ca); + } + } + } diff --git a/src/test/resources/projects/maven/jakarta-sample/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementFilter.java b/src/test/resources/projects/maven/jakarta-sample/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementFilter.java new file mode 100644 index 000000000..91aaa9ea6 --- /dev/null +++ b/src/test/resources/projects/maven/jakarta-sample/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementFilter.java @@ -0,0 +1,8 @@ +package io.openliberty.sample.jakarta.servlet; + +import jakarta.servlet.annotation.WebServlet; + +@WebServlet(name = "filterdemo", urlPatterns = { "/filter" }) +public class DontImplementFilter { + +} \ No newline at end of file diff --git a/src/test/resources/projects/maven/jakarta-sample/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementListener.java b/src/test/resources/projects/maven/jakarta-sample/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementListener.java new file mode 100644 index 000000000..3c2eeae19 --- /dev/null +++ b/src/test/resources/projects/maven/jakarta-sample/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementListener.java @@ -0,0 +1,8 @@ +package io.openliberty.sample.jakarta.servlet; + +import jakarta.servlet.annotation.WebServlet; + +@WebServlet(name = "listenerdemo", urlPatterns = { "/listener" }) +public class DontImplementListener { + +} \ No newline at end of file From 8476a93a375b39c476193beabf315a67ecd3a78d Mon Sep 17 00:00:00 2001 From: dessina-devasia <143582034+dessina-devasia@users.noreply.github.com> Date: Thu, 12 Oct 2023 15:31:57 +0530 Subject: [PATCH 3/9] Refatoring FilterImplementationQuickFix and ListenerImplmentationQuickFix and wrote test cases for same --- .../servlet/FilterImplementationQuickFix.java | 15 ++++---- .../ListenerImplementationQuickFix.java | 16 ++++----- .../servlet/ServletDiagnosticsCollector.java | 19 ---------- .../jdt/core/messages/messages.properties | 2 -- .../it/servlet/JakartaServletTest.java | 36 ++++++++++++++----- .../jakarta/servlet/DontImplementFilter.java | 4 +-- .../servlet/DontImplementListener.java | 4 +-- 7 files changed, 49 insertions(+), 47 deletions(-) diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java index 2b47be14c..23897174a 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java @@ -50,7 +50,6 @@ public class FilterImplementationQuickFix implements IJavaCodeActionParticipant { private static final Logger LOGGER = Logger.getLogger(FilterImplementationQuickFix.class.getName()); - private final static String TITLE_MESSAGE = Messages.getMessage("LetClassImplement"); @Override public String getParticipantId() { return FilterImplementationQuickFix.class.getName(); @@ -60,8 +59,12 @@ public List getCodeActions(JavaCodeActionContext context, List codeActions = new ArrayList<>(); PsiElement node = context.getCoveredNode(); PsiClass parentType = getBinding(node); + if (parentType != null) { - codeActions.add(createCodeAction(context, diagnostic)); + String title = Messages.getMessage("LetClassImplement", + parentType.getName(), + ServletConstants.FILTER); + codeActions.add(createCodeAction(context, diagnostic, title)); } return codeActions; } @@ -72,9 +75,9 @@ public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) { final CodeAction toResolve = context.getUnresolved(); final PsiElement node = context.getCoveredNode(); final PsiClass parentType = getBinding(node); - final PsiMethod parentMethod = PsiTreeUtil.getParentOfType(node, PsiMethod.class); + //final PsiMethod parentMethod = PsiTreeUtil.getParentOfType(node, PsiMethod.class); - assert parentMethod != null; + assert parentType != null; ChangeCorrectionProposal proposal = new ImplementInterfaceProposal( null, parentType, context.getASTRoot(), "jakarta.servlet.Filter", 0, context.getSource().getCompilationUnit()); @@ -87,8 +90,8 @@ public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) { return toResolve; } - private CodeAction createCodeAction(JavaCodeActionContext context, Diagnostic diagnostic) { - ExtendedCodeAction codeAction = new ExtendedCodeAction(TITLE_MESSAGE); + private CodeAction createCodeAction(JavaCodeActionContext context, Diagnostic diagnostic, String title) { + ExtendedCodeAction codeAction = new ExtendedCodeAction(title); codeAction.setRelevance(0); codeAction.setDiagnostics(Collections.singletonList(diagnostic)); codeAction.setKind(CodeActionKind.QuickFix); diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java index 9645c9c6a..1e2faab64 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java @@ -32,7 +32,6 @@ import org.eclipse.lsp4j.WorkspaceEdit; import org.eclipse.lsp4mp.commons.CodeActionResolveData; -import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -54,7 +53,6 @@ public class ListenerImplementationQuickFix implements IJavaCodeActionParticipan private static final Logger LOGGER = Logger.getLogger(ListenerImplementationQuickFix.class.getName()); - private final static String TITLE_MESSAGE = Messages.getMessage("LetClassImplement"); @Override public String getParticipantId() { return ListenerImplementationQuickFix.class.getName(); @@ -62,6 +60,8 @@ public String getParticipantId() { public List getCodeActions(JavaCodeActionContext context, Diagnostic diagnostic) { List codeActions = new ArrayList<>(); + PsiElement node = context.getCoveredNode(); + PsiClass parentType = getBinding(node); String[] listenerConstants = { ServletConstants.SERVLET_CONTEXT_LISTENER, @@ -77,8 +77,8 @@ public List getCodeActions(JavaCodeActionContext context, String httpExt = (constant.contains("HTTP")) ? "http." : ""; String interfaceType = "jakarta.servlet." + httpExt + constant; context.put("interface", interfaceType); - - codeActions.add(createCodeAction(context, diagnostic)); + String title = Messages.getMessage("LetClassImplement", parentType.getName(), constant); + codeActions.add(createCodeAction(context, diagnostic, title)); } return codeActions; @@ -89,10 +89,10 @@ public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) { final CodeAction toResolve = context.getUnresolved(); final PsiElement node = context.getCoveredNode(); final PsiClass parentType = getBinding(node); - final PsiMethod parentMethod = PsiTreeUtil.getParentOfType(node, PsiMethod.class); + //final PsiMethod parentMethod = PsiTreeUtil.getParentOfType(node, PsiMethod.class); String interfaceType = (String) context.get("interface"); - assert parentMethod != null; + assert parentType != null; ChangeCorrectionProposal proposal = new ImplementInterfaceProposal( null, parentType, context.getASTRoot(), interfaceType, 0, context.getCompilationUnit()); @@ -109,8 +109,8 @@ private PsiClass getBinding(PsiElement node) { return PsiTreeUtil.getParentOfType(node, PsiClass.class); } - private CodeAction createCodeAction(JavaCodeActionContext context, Diagnostic diagnostic) { - ExtendedCodeAction codeAction = new ExtendedCodeAction(TITLE_MESSAGE); + private CodeAction createCodeAction(JavaCodeActionContext context, Diagnostic diagnostic, String title) { + ExtendedCodeAction codeAction = new ExtendedCodeAction(title); codeAction.setRelevance(0); codeAction.setDiagnostics(Collections.singletonList(diagnostic)); codeAction.setKind(CodeActionKind.QuickFix); diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ServletDiagnosticsCollector.java b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ServletDiagnosticsCollector.java index 3d56ef521..94f6f698e 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ServletDiagnosticsCollector.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ServletDiagnosticsCollector.java @@ -112,25 +112,6 @@ public void collectDiagnostics(PsiJavaFile unit, List diagnostics) { ServletConstants.DIAGNOSTIC_CODE_DUPLICATE_ATTRIBUTES, null, DiagnosticSeverity.Error)); } - - - /* Filter implementation diagnostic check */ - PsiClass filterInterface = facade.findClass(ServletConstants.FILTER_FQ_NAME, - GlobalSearchScope.allScope(type.getProject())); - if (!type.isInheritor(filterInterface, true)) { - diagnostics.add(createDiagnostic(type, unit, - Messages.getMessage("WebServletMustImplementFilter"), - ServletConstants.DIAGNOSTIC_CODE_FILTER, null, DiagnosticSeverity.Error)); - } - - /* Listener implementation diagnostic check */ - /*PsiClass listenerInterface = facade.findClass(ServletConstants.LISTENER_FQ_NAME, - GlobalSearchScope.allScope(type.getProject())); - if (!type.isInheritor(filterInterface, true)) { - diagnostics.add(createDiagnostic(type, unit, - Messages.getMessage("WebServletMustImplementListener"), - ServletConstants.DIAGNOSTIC_CODE_LISTENER, null, DiagnosticSeverity.Error)); - }*/ } } } diff --git a/src/main/resources/org/eclipse/lsp4jakarta/jdt/core/messages/messages.properties b/src/main/resources/org/eclipse/lsp4jakarta/jdt/core/messages/messages.properties index 572480fe6..e8a9d72e1 100644 --- a/src/main/resources/org/eclipse/lsp4jakarta/jdt/core/messages/messages.properties +++ b/src/main/resources/org/eclipse/lsp4jakarta/jdt/core/messages/messages.properties @@ -163,8 +163,6 @@ WebServletMustExtend = Annotated classes with @WebServlet must extend the HttpSe WebServletShouldExtend = Annotated classes with @WebServlet should extend the HttpServlet class. WebServletMustDefine = The @WebServlet annotation must define the attribute 'urlPatterns' or 'value'. WebServletCannotHaveBoth = The @WebServlet annotation cannot have both 'value' and 'urlPatterns' attributes specified at once. -WebServletMustImplementFilter = Annotated classes with @WebServlet must implement the Filter interface. -WebServletMustImplementListener = Annotated classes with @WebServlet must implement the Listener interface. # WebSocketDiagnosticsCollector WebSocketParamType = Invalid parameter type. When using {0}, parameter must be of type: \n- {1}\n- annotated with @PathParams and of type String or any Java primitive type or boxed version thereof. diff --git a/src/test/java/io/openliberty/tools/intellij/lsp4jakarta/it/servlet/JakartaServletTest.java b/src/test/java/io/openliberty/tools/intellij/lsp4jakarta/it/servlet/JakartaServletTest.java index 13e5febba..2d8f6a125 100644 --- a/src/test/java/io/openliberty/tools/intellij/lsp4jakarta/it/servlet/JakartaServletTest.java +++ b/src/test/java/io/openliberty/tools/intellij/lsp4jakarta/it/servlet/JakartaServletTest.java @@ -107,7 +107,7 @@ public void implementFilter() throws Exception { JakartaDiagnosticsParams diagnosticsParams = new JakartaDiagnosticsParams(); diagnosticsParams.setUris(Arrays.asList(uri)); - Diagnostic d = JakartaForJavaAssert.d(5, 13, 34, "Annotated classes with @WebServlet must implement the Filter interface.", + Diagnostic d = JakartaForJavaAssert.d(5, 13, 32, "Annotated classes with @WebFilter must implement the Filter interface.", DiagnosticSeverity.Error, "jakarta-servlet", "ImplementFilter"); JakartaForJavaAssert.assertJavaDiagnostics(diagnosticsParams, utils, d); @@ -115,7 +115,7 @@ public void implementFilter() throws Exception { if (CHECK_CODE_ACTIONS) { // test associated quick-fix code action JakartaJavaCodeActionParams codeActionParams = JakartaForJavaAssert.createCodeActionParams(uri, d); - TextEdit te = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Filter"); + TextEdit te = JakartaForJavaAssert.te(5, 32, 5, 32, " implements Filter"); CodeAction ca = JakartaForJavaAssert.ca(uri, "Let 'DontImplementFilter' implement 'Filter'", d, te); JakartaForJavaAssert.assertJavaCodeAction(codeActionParams, utils, ca); } @@ -133,17 +133,37 @@ public void implementListener() throws Exception { JakartaDiagnosticsParams diagnosticsParams = new JakartaDiagnosticsParams(); diagnosticsParams.setUris(Arrays.asList(uri)); - Diagnostic d = JakartaForJavaAssert.d(5, 13, 34, "Annotated classes with @WebServlet must implement the Listener interface.", + Diagnostic d = JakartaForJavaAssert.d(5, 13, 34, "Annotated classes with @WebListener must implement one or more of the following interfaces: ServletContextListener, ServletContextAttributeListener, ServletRequestListener, ServletRequestAttributeListener, HttpSessionListener, HttpSessionAttributeListener, or HttpSessionIdListener.", DiagnosticSeverity.Error, "jakarta-servlet", "ImplementListener"); JakartaForJavaAssert.assertJavaDiagnostics(diagnosticsParams, utils, d); if (CHECK_CODE_ACTIONS) { - // test associated quick-fix code action - JakartaJavaCodeActionParams codeActionParams = JakartaForJavaAssert.createCodeActionParams(uri, d); - TextEdit te = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); - CodeAction ca = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'Listener'", d, te); - JakartaForJavaAssert.assertJavaCodeAction(codeActionParams, utils, ca); + // test associated quick-fix code action + JakartaJavaCodeActionParams codeActionParams = JakartaForJavaAssert.createCodeActionParams(uri, d); + + TextEdit te1 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); + CodeAction ca1 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'ServletContextListener'", d, te1); + + TextEdit te2 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); + CodeAction ca2 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'ServletContextAttributeListener'", d, te2); + + TextEdit te3 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); + CodeAction ca3 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'ServletRequestListener'", d, te3); + + TextEdit te4 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); + CodeAction ca4 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'ServletRequestAttributeListener'", d, te4); + + TextEdit te5 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); + CodeAction ca5 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'HttpSessionListener'", d, te5); + + TextEdit te6 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); + CodeAction ca6 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'HttpSessionAttributeListener'", d, te6); + + TextEdit te7 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); + CodeAction ca7 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'HttpSessionIdListener'", d, te7); + + JakartaForJavaAssert.assertJavaCodeAction(codeActionParams, utils, ca1, ca2, ca3, ca4, ca5, ca6, ca7); } } diff --git a/src/test/resources/projects/maven/jakarta-sample/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementFilter.java b/src/test/resources/projects/maven/jakarta-sample/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementFilter.java index 91aaa9ea6..4f00c71e5 100644 --- a/src/test/resources/projects/maven/jakarta-sample/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementFilter.java +++ b/src/test/resources/projects/maven/jakarta-sample/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementFilter.java @@ -1,8 +1,8 @@ package io.openliberty.sample.jakarta.servlet; -import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.annotation.WebFilter; -@WebServlet(name = "filterdemo", urlPatterns = { "/filter" }) +@WebFilter(urlPatterns = { "/filter" }) public class DontImplementFilter { } \ No newline at end of file diff --git a/src/test/resources/projects/maven/jakarta-sample/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementListener.java b/src/test/resources/projects/maven/jakarta-sample/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementListener.java index 3c2eeae19..0d2383687 100644 --- a/src/test/resources/projects/maven/jakarta-sample/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementListener.java +++ b/src/test/resources/projects/maven/jakarta-sample/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementListener.java @@ -1,8 +1,8 @@ package io.openliberty.sample.jakarta.servlet; -import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.annotation.WebListener; -@WebServlet(name = "listenerdemo", urlPatterns = { "/listener" }) +@WebListener public class DontImplementListener { } \ No newline at end of file From f4713312d4fa2aba66df9dba2b93603219974cf6 Mon Sep 17 00:00:00 2001 From: dessina-devasia <143582034+dessina-devasia@users.noreply.github.com> Date: Thu, 12 Oct 2023 15:32:36 +0530 Subject: [PATCH 4/9] Refatoring FilterImplementationQuickFix and ListenerImplmentationQuickFix and wrote test cases for same --- .../lsp4ij/servlet/FilterImplementationQuickFix.java | 2 -- .../lsp4ij/servlet/ListenerImplementationQuickFix.java | 1 - 2 files changed, 3 deletions(-) diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java index 23897174a..54c13912c 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java @@ -59,7 +59,6 @@ public List getCodeActions(JavaCodeActionContext context, List codeActions = new ArrayList<>(); PsiElement node = context.getCoveredNode(); PsiClass parentType = getBinding(node); - if (parentType != null) { String title = Messages.getMessage("LetClassImplement", parentType.getName(), @@ -75,7 +74,6 @@ public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) { final CodeAction toResolve = context.getUnresolved(); final PsiElement node = context.getCoveredNode(); final PsiClass parentType = getBinding(node); - //final PsiMethod parentMethod = PsiTreeUtil.getParentOfType(node, PsiMethod.class); assert parentType != null; ChangeCorrectionProposal proposal = new ImplementInterfaceProposal( diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java index 1e2faab64..35050b77c 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java @@ -89,7 +89,6 @@ public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) { final CodeAction toResolve = context.getUnresolved(); final PsiElement node = context.getCoveredNode(); final PsiClass parentType = getBinding(node); - //final PsiMethod parentMethod = PsiTreeUtil.getParentOfType(node, PsiMethod.class); String interfaceType = (String) context.get("interface"); assert parentType != null; From d57b62311b1f2a6688dce0c9c82f32a548ed5caf Mon Sep 17 00:00:00 2001 From: Aparna Michael Date: Wed, 17 Apr 2024 19:24:55 +0530 Subject: [PATCH 5/9] Resolved the conflicts after merging from code unification 2 branch --- .../it/servlet/JakartaServletTest.java | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/test/java/io/openliberty/tools/intellij/lsp4jakarta/it/servlet/JakartaServletTest.java b/src/test/java/io/openliberty/tools/intellij/lsp4jakarta/it/servlet/JakartaServletTest.java index d9eb6828e..5a3805394 100644 --- a/src/test/java/io/openliberty/tools/intellij/lsp4jakarta/it/servlet/JakartaServletTest.java +++ b/src/test/java/io/openliberty/tools/intellij/lsp4jakarta/it/servlet/JakartaServletTest.java @@ -219,4 +219,77 @@ public void RemoveDuplicateWebFilterAttributes() throws Exception { CodeAction ca2 = JakartaForJavaAssert.ca(uri, "Remove the `value` attribute from @WebFilter", d, te2); JakartaForJavaAssert.assertJavaCodeAction(codeActionParams, utils, ca1, ca2); } + + @Test + public void implementFilter() throws Exception { + Module module = createMavenModule(new File("src/test/resources/projects/maven/jakarta-sample")); + IPsiUtils utils = PsiUtilsLSImpl.getInstance(myProject); + + VirtualFile javaFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(ModuleUtilCore.getModuleDirPath(module) + + "/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementFilter.java"); + String uri = VfsUtilCore.virtualToIoFile(javaFile).toURI().toString(); + + JakartaDiagnosticsParams diagnosticsParams = new JakartaDiagnosticsParams(); + diagnosticsParams.setUris(Arrays.asList(uri)); + + Diagnostic d = JakartaForJavaAssert.d(5, 13, 32, "Annotated classes with @WebFilter must implement the Filter interface.", + DiagnosticSeverity.Error, "jakarta-servlet", "ImplementFilter"); + + JakartaForJavaAssert.assertJavaDiagnostics(diagnosticsParams, utils, d); + + if (CHECK_CODE_ACTIONS) { + // test associated quick-fix code action + JakartaJavaCodeActionParams codeActionParams = JakartaForJavaAssert.createCodeActionParams(uri, d); + TextEdit te = JakartaForJavaAssert.te(5, 32, 5, 32, " implements Filter"); + CodeAction ca = JakartaForJavaAssert.ca(uri, "Let 'DontImplementFilter' implement 'Filter'", d, te); + JakartaForJavaAssert.assertJavaCodeAction(codeActionParams, utils, ca); + } + } + + @Test + public void implementListener() throws Exception { + Module module = createMavenModule(new File("src/test/resources/projects/maven/jakarta-sample")); + IPsiUtils utils = PsiUtilsLSImpl.getInstance(myProject); + + VirtualFile javaFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(ModuleUtilCore.getModuleDirPath(module) + + "/src/main/java/io/openliberty/sample/jakarta/servlet/DontImplementListener.java"); + String uri = VfsUtilCore.virtualToIoFile(javaFile).toURI().toString(); + + JakartaDiagnosticsParams diagnosticsParams = new JakartaDiagnosticsParams(); + diagnosticsParams.setUris(Arrays.asList(uri)); + + Diagnostic d = JakartaForJavaAssert.d(5, 13, 34, "Annotated classes with @WebListener must implement one or more of the following interfaces: ServletContextListener, ServletContextAttributeListener, ServletRequestListener, ServletRequestAttributeListener, HttpSessionListener, HttpSessionAttributeListener, or HttpSessionIdListener.", + DiagnosticSeverity.Error, "jakarta-servlet", "ImplementListener"); + + JakartaForJavaAssert.assertJavaDiagnostics(diagnosticsParams, utils, d); + + if (CHECK_CODE_ACTIONS) { + // test associated quick-fix code action + JakartaJavaCodeActionParams codeActionParams = JakartaForJavaAssert.createCodeActionParams(uri, d); + + TextEdit te1 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); + CodeAction ca1 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'ServletContextListener'", d, te1); + + TextEdit te2 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); + CodeAction ca2 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'ServletContextAttributeListener'", d, te2); + + TextEdit te3 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); + CodeAction ca3 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'ServletRequestListener'", d, te3); + + TextEdit te4 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); + CodeAction ca4 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'ServletRequestAttributeListener'", d, te4); + + TextEdit te5 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); + CodeAction ca5 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'HttpSessionListener'", d, te5); + + TextEdit te6 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); + CodeAction ca6 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'HttpSessionAttributeListener'", d, te6); + + TextEdit te7 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); + CodeAction ca7 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'HttpSessionIdListener'", d, te7); + + JakartaForJavaAssert.assertJavaCodeAction(codeActionParams, utils, ca1, ca2, ca3, ca4, ca5, ca6, ca7); + } + } + } From 527ce26cb0476c949618439062b33ea7830ff047 Mon Sep 17 00:00:00 2001 From: Aparna Michael Date: Thu, 18 Apr 2024 18:39:02 +0530 Subject: [PATCH 6/9] Removed the duplicates of createCodeAction methods and updated Plugin xml 1. Updated plugin.xml with correct targetDiagnostics. 2. Removed the createCodeAction method written in quick fix file and used the method from JDTUtils. --- .../servlet/FilterImplementationQuickFix.java | 14 ++------------ .../servlet/ListenerImplementationQuickFix.java | 15 ++------------- src/main/resources/META-INF/plugin.xml | 15 ++++++++++----- 3 files changed, 14 insertions(+), 30 deletions(-) diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java index 54c13912c..3bb8f548f 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java @@ -18,6 +18,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.psi.util.PsiTreeUtil; +import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.JDTUtils; import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.Messages; import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.ExtendedCodeAction; import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.IJavaCodeActionParticipant; @@ -63,7 +64,7 @@ public List getCodeActions(JavaCodeActionContext context, String title = Messages.getMessage("LetClassImplement", parentType.getName(), ServletConstants.FILTER); - codeActions.add(createCodeAction(context, diagnostic, title)); + codeActions.add(JDTUtils.createCodeAction(context, diagnostic, title,getParticipantId())); } return codeActions; } @@ -88,17 +89,6 @@ public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) { return toResolve; } - private CodeAction createCodeAction(JavaCodeActionContext context, Diagnostic diagnostic, String title) { - ExtendedCodeAction codeAction = new ExtendedCodeAction(title); - codeAction.setRelevance(0); - codeAction.setDiagnostics(Collections.singletonList(diagnostic)); - codeAction.setKind(CodeActionKind.QuickFix); - codeAction.setData(new CodeActionResolveData(context.getUri(), getParticipantId(), - context.getParams().getRange(), Collections.emptyMap(), - context.getParams().isResourceOperationSupported(), - context.getParams().isCommandConfigurationUpdateSupported())); - return codeAction; - } private PsiClass getBinding(PsiElement node) { return PsiTreeUtil.getParentOfType(node, PsiClass.class); diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java index 35050b77c..e280c1b7e 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java @@ -19,6 +19,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.psi.util.PsiTreeUtil; +import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.JDTUtils; import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.Messages; import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.ExtendedCodeAction; import io.openliberty.tools.intellij.lsp4mp4ij.psi.core.java.codeaction.IJavaCodeActionParticipant; @@ -78,7 +79,7 @@ public List getCodeActions(JavaCodeActionContext context, String interfaceType = "jakarta.servlet." + httpExt + constant; context.put("interface", interfaceType); String title = Messages.getMessage("LetClassImplement", parentType.getName(), constant); - codeActions.add(createCodeAction(context, diagnostic, title)); + codeActions.add(JDTUtils.createCodeAction(context, diagnostic, title, getParticipantId())); } return codeActions; @@ -107,16 +108,4 @@ public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) { private PsiClass getBinding(PsiElement node) { return PsiTreeUtil.getParentOfType(node, PsiClass.class); } - - private CodeAction createCodeAction(JavaCodeActionContext context, Diagnostic diagnostic, String title) { - ExtendedCodeAction codeAction = new ExtendedCodeAction(title); - codeAction.setRelevance(0); - codeAction.setDiagnostics(Collections.singletonList(diagnostic)); - codeAction.setKind(CodeActionKind.QuickFix); - codeAction.setData(new CodeActionResolveData(context.getUri(), getParticipantId(), - context.getParams().getRange(), Collections.emptyMap(), - context.getParams().isResourceOperationSupported(), - context.getParams().isCommandConfigurationUpdateSupported())); - return codeAction; - } } diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 390f28526..850646a48 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -211,11 +211,6 @@ group="mp" implementationClass="io.openliberty.tools.intellij.lsp4mp4ij.psi.internal.openapi.java.MicroProfileGenerateOpenAPIOperation"/> - - + + + + From e66048d7800d16f6e5a8b04a7b8e22b86b0c82b4 Mon Sep 17 00:00:00 2001 From: Aparna Michael Date: Mon, 22 Apr 2024 21:03:28 +0530 Subject: [PATCH 7/9] Fixed issue with the resolve code action and modified the tests --- .../servlet/FilterImplementationQuickFix.java | 6 +- .../ListenerImplementationQuickFix.java | 45 +++++----- .../it/servlet/JakartaServletTest.java | 89 ++++++++++++------- 3 files changed, 86 insertions(+), 54 deletions(-) diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java index 3bb8f548f..cd87c06c2 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020, 2023 Red Hat Inc. and others. + * Copyright (c) 2020, 2023, 2024 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 @@ -64,7 +64,7 @@ public List getCodeActions(JavaCodeActionContext context, String title = Messages.getMessage("LetClassImplement", parentType.getName(), ServletConstants.FILTER); - codeActions.add(JDTUtils.createCodeAction(context, diagnostic, title,getParticipantId())); + codeActions.add(JDTUtils.createCodeAction(context, diagnostic, title, getParticipantId())); } return codeActions; } @@ -78,7 +78,7 @@ public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) { assert parentType != null; ChangeCorrectionProposal proposal = new ImplementInterfaceProposal( - null, parentType, context.getASTRoot(), + context.getCompilationUnit(), parentType, context.getASTRoot(), "jakarta.servlet.Filter", 0, context.getSource().getCompilationUnit()); try { WorkspaceEdit we = context.convertToWorkspaceEdit(proposal); diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java index e280c1b7e..b71e421a4 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020, 2023 Red Hat Inc. and others. + * Copyright (c) 2020, 2023, 2024 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 @@ -33,9 +33,7 @@ import org.eclipse.lsp4j.WorkspaceEdit; import org.eclipse.lsp4mp.commons.CodeActionResolveData; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; @@ -54,6 +52,8 @@ public class ListenerImplementationQuickFix implements IJavaCodeActionParticipan private static final Logger LOGGER = Logger.getLogger(ListenerImplementationQuickFix.class.getName()); + private final static String INTERFACE_NAME_KEY = "interface"; + @Override public String getParticipantId() { return ListenerImplementationQuickFix.class.getName(); @@ -65,21 +65,20 @@ public List getCodeActions(JavaCodeActionContext context, PsiClass parentType = getBinding(node); String[] listenerConstants = { - ServletConstants.SERVLET_CONTEXT_LISTENER, - ServletConstants.SERVLET_CONTEXT_ATTRIBUTE_LISTENER, - ServletConstants.SERVLET_REQUEST_LISTENER, - ServletConstants.SERVLET_REQUEST_ATTRIBUTE_LISTENER, - ServletConstants.HTTP_SESSION_LISTENER, - ServletConstants.HTTP_SESSION_ATTRIBUTE_LISTENER, - ServletConstants.HTTP_SESSION_ID_LISTENER + ServletConstants.SERVLET_CONTEXT_LISTENER_FQ_NAME, + ServletConstants.SERVLET_CONTEXT_ATTRIBUTE_LISTENER_FQ_NAME, + ServletConstants.SERVLET_REQUEST_LISTENER_FQ_NAME, + ServletConstants.SERVLET_REQUEST_ATTRIBUTE_LISTENER_FQ_NAME, + ServletConstants.HTTP_SESSION_LISTENER_FQ_NAME, + ServletConstants.HTTP_SESSION_ATTRIBUTE_LISTENER_FQ_NAME, + ServletConstants.HTTP_SESSION_ID_LISTENER_FQ_NAME }; - for (String constant : listenerConstants) { - String httpExt = (constant.contains("HTTP")) ? "http." : ""; - String interfaceType = "jakarta.servlet." + httpExt + constant; - context.put("interface", interfaceType); - String title = Messages.getMessage("LetClassImplement", parentType.getName(), constant); - codeActions.add(JDTUtils.createCodeAction(context, diagnostic, title, getParticipantId())); + for (String interfaceType : listenerConstants) { + Map extendedData = new HashMap<>(); + extendedData.put(INTERFACE_NAME_KEY, interfaceType); + String title = getLabel(interfaceType, parentType); + codeActions.add(JDTUtils.createCodeAction(context, diagnostic, title, getParticipantId(), extendedData)); } return codeActions; @@ -90,12 +89,13 @@ public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) { final CodeAction toResolve = context.getUnresolved(); final PsiElement node = context.getCoveredNode(); final PsiClass parentType = getBinding(node); - String interfaceType = (String) context.get("interface"); + CodeActionResolveData data = (CodeActionResolveData) toResolve.getData(); + String interfaceType = (String) data.getExtendedDataEntry(INTERFACE_NAME_KEY); assert parentType != null; ChangeCorrectionProposal proposal = new ImplementInterfaceProposal( - null, parentType, context.getASTRoot(), interfaceType, 0, - context.getCompilationUnit()); + context.getCompilationUnit(), parentType, context.getASTRoot(), + interfaceType, 0, context.getSource().getCompilationUnit()); try { WorkspaceEdit we = context.convertToWorkspaceEdit(proposal); toResolve.setEdit(we); @@ -108,4 +108,9 @@ public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) { private PsiClass getBinding(PsiElement node) { return PsiTreeUtil.getParentOfType(node, PsiClass.class); } + + private static String getLabel(String fqAnnotation, PsiClass parentType) { + String annotationName = fqAnnotation.substring(fqAnnotation.lastIndexOf('.') + 1, fqAnnotation.length()); + return Messages.getMessage("LetClassImplement", parentType.getName(), annotationName); + } } diff --git a/src/test/java/io/openliberty/tools/intellij/lsp4jakarta/it/servlet/JakartaServletTest.java b/src/test/java/io/openliberty/tools/intellij/lsp4jakarta/it/servlet/JakartaServletTest.java index 5a3805394..c900e6360 100644 --- a/src/test/java/io/openliberty/tools/intellij/lsp4jakarta/it/servlet/JakartaServletTest.java +++ b/src/test/java/io/openliberty/tools/intellij/lsp4jakarta/it/servlet/JakartaServletTest.java @@ -237,13 +237,19 @@ public void implementFilter() throws Exception { JakartaForJavaAssert.assertJavaDiagnostics(diagnosticsParams, utils, d); - if (CHECK_CODE_ACTIONS) { + //TODO: this condition will be enabled when all quickfixes are refactored. +// if (CHECK_CODE_ACTIONS) { // test associated quick-fix code action JakartaJavaCodeActionParams codeActionParams = JakartaForJavaAssert.createCodeActionParams(uri, d); - TextEdit te = JakartaForJavaAssert.te(5, 32, 5, 32, " implements Filter"); - CodeAction ca = JakartaForJavaAssert.ca(uri, "Let 'DontImplementFilter' implement 'Filter'", d, te); + String newText = "package io.openliberty.sample.jakarta.servlet;" + + "\n\nimport jakarta.servlet.Filter;\nimport jakarta.servlet.annotation.WebFilter;" + + "\n\n@WebFilter(urlPatterns = {\"/filter\"})\npublic class DontImplementFilter implements " + + "Filter {\n\n}"; + TextEdit te = JakartaForJavaAssert.te(0, 0, 7, 1, newText); + + CodeAction ca = JakartaForJavaAssert.ca(uri, "Let 'DontImplementFilter' implement 'Filter'", d, te); JakartaForJavaAssert.assertJavaCodeAction(codeActionParams, utils, ca); - } +// } } @Test @@ -263,33 +269,54 @@ public void implementListener() throws Exception { JakartaForJavaAssert.assertJavaDiagnostics(diagnosticsParams, utils, d); - if (CHECK_CODE_ACTIONS) { - // test associated quick-fix code action - JakartaJavaCodeActionParams codeActionParams = JakartaForJavaAssert.createCodeActionParams(uri, d); - - TextEdit te1 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); - CodeAction ca1 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'ServletContextListener'", d, te1); - - TextEdit te2 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); - CodeAction ca2 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'ServletContextAttributeListener'", d, te2); - - TextEdit te3 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); - CodeAction ca3 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'ServletRequestListener'", d, te3); - - TextEdit te4 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); - CodeAction ca4 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'ServletRequestAttributeListener'", d, te4); - - TextEdit te5 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); - CodeAction ca5 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'HttpSessionListener'", d, te5); - - TextEdit te6 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); - CodeAction ca6 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'HttpSessionAttributeListener'", d, te6); - - TextEdit te7 = JakartaForJavaAssert.te(5, 34, 5, 34, " implements Listener"); - CodeAction ca7 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'HttpSessionIdListener'", d, te7); + //TODO: this condition will be enabled when all quickfixes are refactored. +// if (CHECK_CODE_ACTIONS) { + // test associated quick-fix code action + JakartaJavaCodeActionParams codeActionParams = JakartaForJavaAssert.createCodeActionParams(uri, d); - JakartaForJavaAssert.assertJavaCodeAction(codeActionParams, utils, ca1, ca2, ca3, ca4, ca5, ca6, ca7); - } + String newText = "package io.openliberty.sample.jakarta.servlet;\n\nimport jakarta.servlet.annotation." + + "WebListener;\nimport jakarta.servlet.http.HttpSessionAttributeListener;\n\n@WebListener\n" + + "public class DontImplementListener implements HttpSessionAttributeListener {\n\n}"; + TextEdit te1 = JakartaForJavaAssert.te(0, 0, 7, 1, newText); + CodeAction ca1 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'HttpSessionAttributeListener'", d, te1); + + newText = "package io.openliberty.sample.jakarta.servlet;\n\nimport jakarta.servlet.annotation." + + "WebListener;\nimport jakarta.servlet.http.HttpSessionIdListener;\n\n@WebListener\n" + + "public class DontImplementListener implements HttpSessionIdListener {\n\n}"; + TextEdit te2 = JakartaForJavaAssert.te(0, 0, 7, 1, newText); + CodeAction ca2 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'HttpSessionIdListener'", d, te2); + + newText = "package io.openliberty.sample.jakarta.servlet;\n\nimport jakarta.servlet.annotation." + + "WebListener;\nimport jakarta.servlet.http.HttpSessionListener;\n\n@WebListener\npublic" + + " class DontImplementListener implements HttpSessionListener {\n\n}"; + TextEdit te3 = JakartaForJavaAssert.te(0, 0, 7, 1, newText); + CodeAction ca3 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'HttpSessionListener'", d, te3); + + newText = "package io.openliberty.sample.jakarta.servlet;\n\nimport jakarta.servlet." + + "ServletContextAttributeListener;\nimport jakarta.servlet.annotation.WebListener;\n\n" + + "@WebListener\npublic class DontImplementListener implements ServletContextAttributeListener {\n\n}"; + TextEdit te4 = JakartaForJavaAssert.te(0, 0, 7, 1, newText); + CodeAction ca4 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'ServletContextAttributeListener'", d, te4); + + newText = "package io.openliberty.sample.jakarta.servlet;\n\nimport jakarta.servlet.ServletContextListener;" + + "\nimport jakarta.servlet.annotation.WebListener;\n\n@WebListener\npublic class DontImplementListener" + + " implements ServletContextListener {\n\n}"; + TextEdit te5 = JakartaForJavaAssert.te(0, 0, 7, 1, newText); + CodeAction ca5 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'ServletContextListener'", d, te5); + + newText = "package io.openliberty.sample.jakarta.servlet;\n\nimport jakarta.servlet." + + "ServletRequestAttributeListener;\nimport jakarta.servlet.annotation.WebListener;\n\n" + + "@WebListener\npublic class DontImplementListener implements ServletRequestAttributeListener {\n\n}"; + TextEdit te6 = JakartaForJavaAssert.te(0, 0, 7, 1, newText); + CodeAction ca6 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'ServletRequestAttributeListener'", d, te6); + + newText = "package io.openliberty.sample.jakarta.servlet;\n\nimport jakarta.servlet.ServletRequestListener;" + + "\nimport jakarta.servlet.annotation.WebListener;\n\n@WebListener\npublic class DontImplementListener" + + " implements ServletRequestListener {\n\n}"; + TextEdit te7 = JakartaForJavaAssert.te(0, 0, 7, 1, newText); + CodeAction ca7 = JakartaForJavaAssert.ca(uri, "Let 'DontImplementListener' implement 'ServletRequestListener'", d, te7); + + JakartaForJavaAssert.assertJavaCodeAction(codeActionParams, utils, ca1, ca2, ca3, ca4, ca5, ca6, ca7); } - +// } } From c05d101c11689cf33580a69a79ace83fe02eb801 Mon Sep 17 00:00:00 2001 From: Aparna Michael Date: Tue, 23 Apr 2024 18:27:12 +0530 Subject: [PATCH 8/9] Reverted changes in JakartaCodeActionHandler and modified the header --- .../lsp4ij/codeAction/JakartaCodeActionHandler.java | 8 ++++++++ .../lsp4ij/servlet/FilterImplementationQuickFix.java | 2 +- .../lsp4ij/servlet/ListenerImplementationQuickFix.java | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/codeAction/JakartaCodeActionHandler.java b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/codeAction/JakartaCodeActionHandler.java index f77ac7cc9..ebf372a8a 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/codeAction/JakartaCodeActionHandler.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/codeAction/JakartaCodeActionHandler.java @@ -91,6 +91,8 @@ public List codeAction(JakartaJavaCodeActionParams params, IPsiUtils List codeActions = new ArrayList<>(); HttpServletQuickFix HttpServletQuickFix = new HttpServletQuickFix(); + FilterImplementationQuickFix FilterImplementationQuickFix = new FilterImplementationQuickFix(); + ListenerImplementationQuickFix ListenerImplementationQuickFix = new ListenerImplementationQuickFix(); CompleteServletAnnotationQuickFix CompleteServletAnnotationQuickFix = new CompleteServletAnnotationQuickFix(); CompleteFilterAnnotationQuickFix CompleteFilterAnnotationQuickFix = new CompleteFilterAnnotationQuickFix(); PersistenceAnnotationQuickFix PersistenceAnnotationQuickFix = new PersistenceAnnotationQuickFix(); @@ -126,6 +128,12 @@ public List codeAction(JakartaJavaCodeActionParams params, IPsiUtils if (diagnostic.getCode().getLeft().equals(ServletConstants.DIAGNOSTIC_CODE)) { codeActions.addAll(HttpServletQuickFix.getCodeActions(context, diagnostic)); } + if (diagnostic.getCode().getLeft().equals(ServletConstants.DIAGNOSTIC_CODE_FILTER)) { + codeActions.addAll(FilterImplementationQuickFix.getCodeActions(context, diagnostic)); + } + if (diagnostic.getCode().getLeft().equals(ServletConstants.DIAGNOSTIC_CODE_LISTENER)) { + codeActions.addAll(ListenerImplementationQuickFix.getCodeActions(context, diagnostic)); + } if (diagnostic.getCode().getLeft().equals(AnnotationConstants.DIAGNOSTIC_CODE_MISSING_RESOURCE_NAME_ATTRIBUTE)) { codeActions.addAll(AddResourceMissingNameQuickFix.getCodeActions(context, diagnostic)); } diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java index cd87c06c2..6eb21697c 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/FilterImplementationQuickFix.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020, 2023, 2024 Red Hat Inc. and others. + * Copyright (c) 2020, 2024 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 diff --git a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java index b71e421a4..28dd026fd 100644 --- a/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java +++ b/src/main/java/io/openliberty/tools/intellij/lsp4jakarta/lsp4ij/servlet/ListenerImplementationQuickFix.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020, 2023, 2024 Red Hat Inc. and others. + * Copyright (c) 2020, 2024 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 From c733b6adc70e2854016e87fc0f0622e337d27c78 Mon Sep 17 00:00:00 2001 From: Aparna Michael Date: Wed, 24 Apr 2024 11:48:19 +0530 Subject: [PATCH 9/9] Removing unwanted entry in plugin.xml --- src/main/resources/META-INF/plugin.xml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 850646a48..994071043 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -210,12 +210,7 @@ - - - +