Skip to content

Commit

Permalink
Show annotations in editor, and allow quick-fix to supress. Issue ami…
Browse files Browse the repository at this point in the history
  • Loading branch information
martenbohlin committed Oct 15, 2023
1 parent f920dfd commit 83d9448
Show file tree
Hide file tree
Showing 14 changed files with 371 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@
import com.intellij.plugins.bodhi.pmd.core.PMDResultCollector;
import com.intellij.ui.DocumentAdapter;
import com.intellij.util.PlatformIcons;
import net.sourceforge.pmd.util.ResourceLoader;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.text.BadLocationException;
Expand All @@ -27,9 +26,13 @@
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.*;

import static com.intellij.plugins.bodhi.pmd.actions.PreDefinedMenuGroup.RULESETS_FILENAMES;
import static com.intellij.plugins.bodhi.pmd.actions.PreDefinedMenuGroup.RULESETS_PROPERTY_FILE;

/**
* This class represents the UI for settings.
*
Expand All @@ -38,12 +41,13 @@
*/
public class PMDConfigurationForm {
private JPanel rootPanel;
private JList ruleList;
private JList<String> ruleList;
private JPanel buttonPanel;
private JTabbedPane tabbedPane1;
private JTable table1;
private JPanel mainPanel;
private JCheckBox skipTestsCheckBox;
private JList<String> inEditorAnnotationRuleSets;

private boolean isModified;
private final Project project;
Expand Down Expand Up @@ -71,7 +75,9 @@ public PMDConfigurationForm(final Project project) {
buttonPanel.add(toolbar.getComponent(), BorderLayout.CENTER);

table1.putClientProperty("terminateEditOnFocusLost", true); // fixes issue #45
ruleList.setModel(new MyListModel(new ArrayList<String>()));
ruleList.setModel(new MyListModel(new ArrayList<>()));
inEditorAnnotationRuleSets.setModel(new MyListModel(new ArrayList<>()));
inEditorAnnotationRuleSets.getSelectionModel().addListSelectionListener(new SelectionChangeListener());
skipTestsCheckBox.addChangeListener(new CheckBoxChangeListener());

table1.setToolTipText(STAT_URL_MSG);
Expand All @@ -90,7 +96,8 @@ public JPanel getRootPanel() {
* @param dataProjComp the data provider
*/
public void setDataOnUI(PMDProjectComponent dataProjComp) {
ruleList.setModel(new MyListModel(dataProjComp.getCustomRuleSetPaths()));
List<String> customRuleSetPaths = dataProjComp.getCustomRuleSetPaths();
ruleList.setModel(new MyListModel(customRuleSetPaths));
if (dataProjComp.getOptions().isEmpty()) {
String[][] dat = new String[optionNames.length][2];
for (int i = 0; i < optionNames.length; i++) {
Expand All @@ -102,6 +109,20 @@ public void setDataOnUI(PMDProjectComponent dataProjComp) {
}
table1.setModel(new MyTableModel(toArray(dataProjComp.getOptions()), columnNames));
skipTestsCheckBox.setSelected(dataProjComp.isSkipTestSources());

Properties props = new Properties();
try {
props.load(getClass().getClassLoader().getResourceAsStream(RULESETS_PROPERTY_FILE));
} catch (IOException e) {
throw new RuntimeException(e);
}
List<String> allRules = new ArrayList<>(List.of(props.getProperty(RULESETS_FILENAMES).split(PMDInvoker.RULE_DELIMITER)));
allRules.addAll(customRuleSetPaths);

MyListModel inEditorAnnotationModel = new MyListModel(allRules);
inEditorAnnotationRuleSets.setModel(inEditorAnnotationModel);
inEditorAnnotationRuleSets.setSelectedIndices(inEditorAnnotationModel.getIndexes(dataProjComp.getInEditorAnnotationRuleSets()));

isModified = false;
}

Expand All @@ -111,6 +132,8 @@ private Object[][] toArray(Map<String, String> options) {
res[i][0] = optionNames[i];
res[i][1] = options.get(optionNames[i]);
}


return res;
}

Expand All @@ -122,6 +145,8 @@ public void getDataFromUi(PMDProjectComponent data_ProjComp) {
data_ProjComp.setCustomRuleSets(((MyListModel) ruleList.getModel()).getData());
data_ProjComp.setOptions( toMap(table1.getModel()) );
data_ProjComp.skipTestSources(skipTestsCheckBox.isSelected());
data_ProjComp.setInEditorAnnotationRuleSets(inEditorAnnotationRuleSets.getSelectedValuesList());

isModified = false;
}

Expand Down Expand Up @@ -175,6 +200,10 @@ private void modifyRuleSet(final String defaultValue, AnActionEvent e) {
int index = listModel.getSize();
listModel.add(index, fileName);
ruleList.setSelectedIndex(index);

MyListModel inEditorAnnotationRuleSetsModel = (MyListModel) inEditorAnnotationRuleSets.getModel();
inEditorAnnotationRuleSetsModel.add(inEditorAnnotationRuleSetsModel.getSize(), fileName);

ruleList.repaint();
}
}
Expand Down Expand Up @@ -227,8 +256,11 @@ public DeleteRuleSetAction(String text, String description, Icon icon) {
public void actionPerformed(@NotNull AnActionEvent e) {
int index = ruleList.getSelectedIndex();
if (index != -1) {
String toRemove = ruleList.getModel().getElementAt(index);
((MyListModel)ruleList.getModel()).remove(index);
ruleList.setSelectedIndex(index);

((MyListModel) inEditorAnnotationRuleSets.getModel()).remove(toRemove);
}
ruleList.repaint();
}
Expand Down Expand Up @@ -313,7 +345,7 @@ private void validateThreads(String threads, int row, int column, Object orig, b
}
}

private class MyListModel extends AbstractListModel {
private class MyListModel extends AbstractListModel<String> {

private final List<String> data;

Expand All @@ -331,14 +363,18 @@ public synchronized void add(int index, Object item) {
isModified = true;
}

public synchronized Object getElementAt(int index) {
public synchronized String getElementAt(int index) {
return data.get(index);
}

public synchronized List<String> getData() {
return data;
}

public synchronized void remove(String objectToRemove) {
remove(data.indexOf(objectToRemove));
}

public synchronized void remove(int index) {
data.remove(index);
fireIntervalRemoved(this, index, index);
Expand All @@ -350,6 +386,16 @@ public synchronized void set(int selIndex, String fileName) {
fireContentsChanged(this, selIndex, selIndex);
isModified = true;
}

public int[] getIndexes(Set<String> selectedObjects) {
int[] selected = new int[selectedObjects.size()];
List<String> options = getData();
int i=0;
for (String selectedOption : selectedObjects) {
selected[i++] = options.indexOf(selectedOption);
}
return selected;
}
}

/**
Expand Down Expand Up @@ -418,4 +464,11 @@ public void stateChanged(ChangeEvent e)
isModified = true;
}
}

private class SelectionChangeListener implements ListSelectionListener {
@Override
public void valueChanged(ListSelectionEvent e) {
isModified = true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
<grid id="e0d33" binding="mainPanel" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="43" y="23" width="206" height="205"/>
<xy x="43" y="23" width="405" height="305"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<tabbedpane id="6c5e0" binding="tabbedPane1">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
<preferred-size width="200" height="200"/>
<preferred-size width="200" height="400"/>
</grid>
</constraints>
<properties>
Expand Down Expand Up @@ -61,7 +61,7 @@
</scrollpane>
</children>
</grid>
<grid id="c6276" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="c6276" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<tabbedpane title="Options"/>
Expand All @@ -71,14 +71,15 @@
<children>
<scrollpane id="8a8a3">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="3c5c7" class="javax.swing.JTable" binding="table1">
<constraints/>
<properties>
<preferredScrollableViewportSize width="450" height="100"/>
<toolTipText value=""/>
</properties>
</component>
Expand All @@ -92,6 +93,37 @@
<text value="Skip Test Sources"/>
</properties>
</component>
<grid id="b1b6e" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<scrollpane id="32246">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="line"/>
<children>
<component id="49c07" class="javax.swing.JList" binding="inEditorAnnotationRuleSets">
<constraints/>
<properties/>
</component>
</children>
</scrollpane>
</children>
</grid>
<component id="cf903" class="javax.swing.JLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Rules annotated in Editor (select multiple with ctrl/cmd)"/>
</properties>
</component>
</children>
</grid>
</children>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public class PMDProjectComponent implements ProjectComponent, PersistentStateCom
private final ToolWindowManager toolWindowManager;
private boolean skipTestSources;
private boolean scanFilesBeforeCheckin;
private Set<String> inEditorAnnotationRuleSets = new LinkedHashSet<>(); // avoid duplicates, maintain order

/**
* Creates a PMD Project component based on the project given.
Expand Down Expand Up @@ -261,6 +262,13 @@ public void setCustomRuleSets(List<String> customRuleSetPaths) {
this.customRuleSetPaths = new LinkedHashSet<>(customRuleSetPaths);
}

public Set<String> getInEditorAnnotationRuleSets() {
return inEditorAnnotationRuleSets;
}
public void setInEditorAnnotationRuleSets(List<String> inEditorAnnotationRules) {
this.inEditorAnnotationRuleSets = new LinkedHashSet<>(inEditorAnnotationRules);
}

public Map<String, String> getOptions() {
return options;
}
Expand All @@ -284,6 +292,10 @@ public PersistentData getState() {
}
pd.setSkipTestSources(skipTestSources);
pd.setScanFilesBeforeCheckin(scanFilesBeforeCheckin);

for (String item : inEditorAnnotationRuleSets) {
pd.getInEditorAnnotationRules().add(item);
}
return pd;
}

Expand All @@ -303,6 +315,9 @@ public void loadState(PersistentData state) {
options.put(PMDConfigurationForm.STATISTICS_URL, "");
}

inEditorAnnotationRuleSets.clear();
inEditorAnnotationRuleSets.addAll(state.getInEditorAnnotationRules());

this.skipTestSources = state.isSkipTestSources();
this.scanFilesBeforeCheckin = state.isScanFilesBeforeCheckin();
}
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/intellij/plugins/bodhi/pmd/PersistentData.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ public class PersistentData {
private Map<String, String> options;
private boolean skipTestSources = DEFAULT_SKIP_TEST_SRC;
private boolean scanFilesBeforeCheckin;
private List<String> inEditorAnnotationRules;


public PersistentData() {
this.customRuleSets = new ArrayList<>();
this.inEditorAnnotationRules = new ArrayList<>();
this.options = new HashMap<>();
}

Expand Down Expand Up @@ -41,6 +44,13 @@ public boolean isSkipTestSources() {
return skipTestSources;
}

public void setInEditorAnnotationRules(List<String> inEditorAnnotationRules) {
this.inEditorAnnotationRules = inEditorAnnotationRules;
}
public List<String> getInEditorAnnotationRules() {
return inEditorAnnotationRules;
}

public boolean isScanFilesBeforeCheckin() {
return scanFilesBeforeCheckin;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ public class PreDefinedMenuGroup extends ActionGroup {
private PMDProjectComponent component;

//The ruleset property file which lists all the predefined rulesets
private static final String RULESETS_PROPERTY_FILE = "rulesets/java/rulesets.properties";
private static final String RULESETS_FILENAMES = "rulesets.filenames";
public static final String RULESETS_PROPERTY_FILE = "rulesets/java/rulesets.properties";
public static final String RULESETS_FILENAMES = "rulesets.filenames";

/**
* Loads all the predefined rulesets in PMD and create actions for them.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.intellij.plugins.bodhi.pmd.annotator;

import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;

import java.io.File;

public class FileInfo {

private final PsiFile file;
private final Document document;

public FileInfo(PsiFile file, Document document) {
this.file = file;
this.document = document;
}

public Project getProject() {
return file.getProject();
}

public File getFile() {
return file.getVirtualFile().toNioPath().toFile();
}

public Document getDocument() {
return document;
}
}
Loading

0 comments on commit 83d9448

Please sign in to comment.