Skip to content

Commit

Permalink
Fixes OpenLiberty#577 - Refactoring classes
Browse files Browse the repository at this point in the history
Base Class InsertAnnotationMissingQuickFix and child classes
PersistenceAnnotationQuickFix, CompleteFilterAnnotationQuickFix, CompleteServletAnnotationQuickFix refactored.

Added test classes for CompleteFilterAnnotationQuickFix and CompleteServletAnnotationQuickFix.
  • Loading branch information
anusreelakshmi934 committed Jan 20, 2024
1 parent 563529b commit 7c8963c
Show file tree
Hide file tree
Showing 10 changed files with 369 additions and 142 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,19 @@

import com.intellij.psi.*;
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.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.InsertAnnotationProposal;
import org.eclipse.lsp4j.CodeAction;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.WorkspaceEdit;

import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
Expand All @@ -33,9 +38,8 @@
* @author Angelo ZERR
*
*/
public class InsertAnnotationMissingQuickFix {
public abstract class InsertAnnotationMissingQuickFix implements IJavaCodeActionParticipant {
private static final Logger LOGGER = Logger.getLogger(InsertAnnotationMissingQuickFix.class.getName());
private static final String ANNOTATION_KEY = "annotation";

private final String[] annotations;

Expand Down Expand Up @@ -73,6 +77,25 @@ public List<? extends CodeAction> getCodeActions(JavaCodeActionContext context,
return codeActions;
}

@Override
public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) {
final CodeAction toResolve = context.getUnresolved();
String name = getLabel(annotations);
PsiElement node = context.getCoveringNode();
PsiModifierListOwner parentType = getBinding(node);

ChangeCorrectionProposal proposal = new InsertAnnotationProposal(name, context.getCompilationUnit(),
context.getASTRoot(), parentType, 0, context.getSource().getCompilationUnit(),
annotations);
try {
WorkspaceEdit we = context.convertToWorkspaceEdit(proposal);
toResolve.setEdit(we);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Unable to create workspace edit for code action", e);
}
return toResolve;
}

protected static PsiModifierListOwner getBinding(PsiElement node) {
PsiModifierListOwner binding = PsiTreeUtil.getParentOfType(node, PsiVariable.class);
if (binding != null) {
Expand Down Expand Up @@ -103,17 +126,8 @@ protected void insertAnnotations(Diagnostic diagnostic, JavaCodeActionContext co

protected void insertAnnotation(Diagnostic diagnostic, JavaCodeActionContext context,
List<CodeAction> codeActions, String... annotations) {
String name = getLabel(annotations);
PsiElement node = context.getCoveringNode();
PsiModifierListOwner parentType = getBinding(node);

ChangeCorrectionProposal proposal = new InsertAnnotationProposal(name, context.getCompilationUnit(),
context.getASTRoot(), parentType, 0, context.getSource().getCompilationUnit(),
annotations);
CodeAction codeAction = context.convertToCodeAction(proposal, diagnostic);
if (codeAction != null) {
codeActions.add(codeAction);
}
String label = getLabel(annotations);
codeActions.add(JDTUtils.createCodeAction(context, diagnostic, label, getParticipantId()));
}

private static String getLabel(String[] annotations) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,22 @@


import com.intellij.psi.*;
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.lsp4jakarta.lsp4ij.codeAction.proposal.ModifyAnnotationProposal;
import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.codeAction.proposal.quickfix.InsertAnnotationMissingQuickFix;
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.Diagnostic;
import org.eclipse.lsp4j.WorkspaceEdit;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;

/**
Expand All @@ -43,6 +47,7 @@
* * Or only one code action to fix all annotations.
*/
public class PersistenceAnnotationQuickFix extends InsertAnnotationMissingQuickFix {
private static final Logger LOGGER = Logger.getLogger(PersistenceAnnotationQuickFix.class.getName());

public PersistenceAnnotationQuickFix() {
super("jakarta.persistence.MapKeyJoinColumn");
Expand All @@ -52,32 +57,38 @@ public PersistenceAnnotationQuickFix() {
protected void insertAnnotations(Diagnostic diagnostic, JavaCodeActionContext context,
List<CodeAction> codeActions) {
String[] annotations = getAnnotations();
insertAndReplaceAnnotation(diagnostic, context, codeActions, annotations);
insertAndReplaceAnnotation(diagnostic, context, codeActions);
}

private static void insertAndReplaceAnnotation(Diagnostic diagnostic, JavaCodeActionContext context,
List<CodeAction> codeActions, String... annotations) {
@Override
public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) {
final CodeAction toResolve = context.getUnresolved();
ArrayList<String> attributes = new ArrayList<>();
attributes.add("name");
attributes.add("referencedColumnName");
String name = Messages.getMessage("AddTheMissingAttributes");
PsiElement node = context.getCoveredNode();
PsiModifierListOwner binding = getBinding(node); // field or method in this case
List<PsiAnnotation> annotationNodes = getAnnotations(binding, annotations);
CodeAction codeAction = null;

PsiModifierListOwner binding = getBinding(node);
List<PsiAnnotation> annotationNodes = getAnnotations(binding, this.getAnnotations());
for (PsiAnnotation annotationNode : annotationNodes) {
ChangeCorrectionProposal proposal = new ModifyAnnotationProposal(name, context.getSource().getCompilationUnit(),
context.getASTRoot(), binding, annotationNode, 0, attributes, annotations);

// Convert the proposal to LSP4J CodeAction
// We need to fix all the annotations so all the changes are combined in this one context.
// Therefore, we only need to save the last code action.
codeAction = context.convertToCodeAction(proposal, diagnostic);
}
if (codeAction != null) {
codeActions.add(codeAction);
context.getASTRoot(), binding, annotationNode, 0, attributes, this.getAnnotations());
try {
WorkspaceEdit we = context.convertToWorkspaceEdit(proposal);
toResolve.setEdit(we);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Unable to create workspace edit for code action.", e);
}
}

return toResolve;
}

private void insertAndReplaceAnnotation(Diagnostic diagnostic, JavaCodeActionContext context,
List<CodeAction> codeActions) {
String name = Messages.getMessage("AddTheMissingAttributes");
codeActions.add(JDTUtils.createCodeAction(context, diagnostic, name, getParticipantId()));

}

private static List<PsiAnnotation> getAnnotations(PsiElement e, String... names) {
Expand All @@ -94,4 +105,9 @@ private static List<PsiAnnotation> getAnnotations(PsiElement e, String... names)
}
return result;
}

@Override
public String getParticipantId() {
return PersistenceAnnotationQuickFix.class.getName();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,24 @@
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiModifierListOwner;
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.lsp4jakarta.lsp4ij.codeAction.proposal.ModifyAnnotationProposal;
import io.openliberty.tools.intellij.lsp4jakarta.lsp4ij.codeAction.proposal.quickfix.InsertAnnotationMissingQuickFix;
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.Diagnostic;
import org.eclipse.lsp4j.WorkspaceEdit;
import org.eclipse.lsp4mp.commons.CodeActionResolveData;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* QuickFix for fixing {@link ServletConstants#DIAGNOSTIC_CODE_FILTER_MISSING_ATTRIBUTE} error
Expand All @@ -52,6 +60,10 @@
*
*/
public class CompleteFilterAnnotationQuickFix extends InsertAnnotationMissingQuickFix {
private static final Logger LOGGER = Logger.getLogger(CompleteServletAnnotationQuickFix.class.getName());
private static final String DIAGNOSTIC_CODE_KEY = "diagnosticCode";
private static final String ATTRIBUTE_KEY = "attribute";
private static final String ANNOTATION_KEY = "annotation";

public CompleteFilterAnnotationQuickFix() {
super("jakarta.servlet.annotation.WebFilter");
Expand All @@ -66,66 +78,82 @@ protected void insertAnnotations(Diagnostic diagnostic, JavaCodeActionContext co
}
}

private static void insertAndReplaceAnnotation(Diagnostic diagnostic, JavaCodeActionContext context,
List<CodeAction> codeActions, String annotation) {

// Insert the annotation and the proper import by using JDT Core Manipulation
// API


// if missing an attribute, do value insertion
@Override
public CodeAction resolveCodeAction(JavaCodeActionResolveContext context) {
final CodeAction toResolve = context.getUnresolved();
PsiElement node = null;
PsiModifierListOwner parentType = null;
PsiAnnotation annotationNode = null;
if (diagnostic.getCode().getLeft().equals(ServletConstants.DIAGNOSTIC_CODE_FILTER_MISSING_ATTRIBUTE)) {
ArrayList<String> attributes = new ArrayList<>();
attributes.add("value"); attributes.add("urlPatterns");attributes.add("servletNames");
// Code Action 1: add value attribute to the WebServlet annotation
// Code Action 2: add urlPatterns attribute to the WebServlet annotation
for (int i = 0; i < attributes.size(); i++) {
String attribute = attributes.get(i);
JavaCodeActionContext targetContext = context.copy();
node = targetContext.getCoveringNode();
parentType = getBinding(node);
annotationNode = getAnnotation(node);

ArrayList<String> attributesToAdd = new ArrayList<>();
attributesToAdd.add(attribute);
CodeActionResolveData data = (CodeActionResolveData) toResolve.getData();
String diagnosticCode = (String) data.getExtendedDataEntry(DIAGNOSTIC_CODE_KEY);
String attribute = (String) data.getExtendedDataEntry(ATTRIBUTE_KEY);
String annotation = (String) data.getExtendedDataEntry(ANNOTATION_KEY);

if (diagnosticCode.equals(ServletConstants.DIAGNOSTIC_CODE_FILTER_MISSING_ATTRIBUTE)) {
node = context.getCoveringNode();
parentType = getBinding(node);
annotationNode = getAnnotation(node);

ArrayList<String> attributesToAdd = new ArrayList<>();
attributesToAdd.add(attribute);
String name = getLabel(annotation, attribute, "Add");
ChangeCorrectionProposal proposal = new ModifyAnnotationProposal(name, context.getSource().getCompilationUnit(),
context.getASTRoot(), parentType, annotationNode, 0, annotation, attributesToAdd);
try {
WorkspaceEdit we = context.convertToWorkspaceEdit(proposal);
toResolve.setEdit(we);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Unable to create workspace edit for code action.", e);
}
}

if (diagnosticCode.equals(ServletConstants.DIAGNOSTIC_CODE_FILTER_DUPLICATE_ATTRIBUTES)) {
node = context.getCoveringNode();
parentType = getBinding(node);
annotationNode = getAnnotation(node);

ArrayList<String> attributesToRemove = new ArrayList<>();
attributesToRemove.add(attribute);
String name = getLabel(annotation, attribute, "Remove");
ChangeCorrectionProposal proposal = new ModifyAnnotationProposal(name, context.getSource().getCompilationUnit(),
context.getASTRoot(), parentType, annotationNode, 0, annotation, new ArrayList<String>(), attributesToRemove);
try {
WorkspaceEdit we = context.convertToWorkspaceEdit(proposal);
toResolve.setEdit(we);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Unable to create workspace edit for code action.", e);
}
}
return toResolve;
}

private void insertAndReplaceAnnotation(Diagnostic diagnostic, JavaCodeActionContext context,
List<CodeAction> codeActions, String annotation) {

ArrayList<String> attributes = new ArrayList<>();
attributes.add("value");
attributes.add("urlPatterns");
attributes.add("servletNames");

String diagnosticCode = diagnostic.getCode().getLeft();
if (diagnosticCode.equals(ServletConstants.DIAGNOSTIC_CODE_FILTER_MISSING_ATTRIBUTE)) {
for (String attribute : attributes) {
String name = getLabel(annotation, attribute, "Add");
ChangeCorrectionProposal proposal = new ModifyAnnotationProposal(name, targetContext.getSource().getCompilationUnit(),
targetContext.getASTRoot(), parentType, annotationNode, 0, annotation, attributesToAdd);
// Convert the proposal to LSP4J CodeAction
CodeAction codeAction = targetContext.convertToCodeAction(proposal, diagnostic);
codeAction.setTitle(name);
if (codeAction != null) {
codeActions.add(codeAction);
}
Map<String, Object> extendedData = new HashMap<>();
extendedData.put(DIAGNOSTIC_CODE_KEY, diagnosticCode);
extendedData.put(ATTRIBUTE_KEY, attribute);
extendedData.put(ANNOTATION_KEY, annotation);
codeActions.add(JDTUtils.createCodeAction(context, diagnostic, name, getParticipantId(), extendedData));
}
}
// if duplicate attributes exist in annotations, remove attributes from annotation
if (diagnostic.getCode().getLeft().equals(ServletConstants.DIAGNOSTIC_CODE_FILTER_DUPLICATE_ATTRIBUTES)) {
ArrayList<String> attributes = new ArrayList<>();
attributes.add("value"); attributes.add("urlPatterns");
// Code Action 1: remove value attribute from the WebServlet annotation
// Code Action 2: remove urlPatterns attribute from the WebServlet annotation
for (int i = 0; i < attributes.size(); i++) {
String attribute = attributes.get(i);
JavaCodeActionContext targetContext = context.copy();
node = targetContext.getCoveringNode();
parentType = getBinding(node);
annotationNode = getAnnotation(node);

ArrayList<String> attributesToRemove = new ArrayList<>();
attributesToRemove.add(attribute);
if (diagnosticCode.equals(ServletConstants.DIAGNOSTIC_CODE_FILTER_DUPLICATE_ATTRIBUTES)) {
for (String attribute : attributes) {
String name = getLabel(annotation, attribute, "Remove");
ChangeCorrectionProposal proposal = new ModifyAnnotationProposal(name, targetContext.getSource().getCompilationUnit(),
targetContext.getASTRoot(), parentType, annotationNode, 0, annotation, new ArrayList<String>(), attributesToRemove);
// Convert the proposal to LSP4J CodeAction
CodeAction codeAction = targetContext.convertToCodeAction(proposal, diagnostic);
codeAction.setTitle(name);
if (codeAction != null) {
codeActions.add(codeAction);
}
Map<String, Object> extendedData = new HashMap<>();
extendedData.put(DIAGNOSTIC_CODE_KEY, diagnosticCode);
extendedData.put(ATTRIBUTE_KEY, attribute);
extendedData.put(ANNOTATION_KEY, annotation);
codeActions.add(JDTUtils.createCodeAction(context, diagnostic, name, getParticipantId(), extendedData));
}
}
}
Expand All @@ -134,9 +162,10 @@ private static String getLabel(String annotation, String attribute, String label
String annotationName = annotation.substring(annotation.lastIndexOf('.') + 1, annotation.length());
annotationName = "@" + annotationName;
if (labelType.equals("Remove")) {
return Messages.getMessage("RemoveTheAttriubuteFrom", attribute, annotationName);
return Messages.getMessage("RemoveTheAttributeFrom", attribute, annotationName);
}
return Messages.getMessage("AddTheAttributeTo", attribute, annotationName); }
return Messages.getMessage("AddTheAttributeTo", attribute, annotationName);
}

private static PsiAnnotation getAnnotation(PsiElement e) {
if (e instanceof PsiAnnotation) {
Expand Down
Loading

0 comments on commit 7c8963c

Please sign in to comment.