Skip to content

Commit

Permalink
Merge pull request #173 from jborgers/master
Browse files Browse the repository at this point in the history
For PMD 7 version, deal properly with custom rules in PMD 6 format #172
  • Loading branch information
amitdev authored May 26, 2024
2 parents 3e4e7b5 + 6ae6d3c commit 5c251a2
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 42 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
# PMDPlugin Changelog

## [Unreleased]
### Added
- Update to PMD version 7.1.0
- NOTE: custom rules built on PMD 6 will *NOT* work, if needed: stay on 1.9.2 until they are migrated

## [1.9.2]
### Added
- Bugfixes and improved stability
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@

import static com.intellij.plugins.bodhi.pmd.actions.PreDefinedMenuGroup.RULESETS_FILENAMES_KEY;
import static com.intellij.plugins.bodhi.pmd.actions.PreDefinedMenuGroup.RULESETS_PROPERTY_FILE;
import static com.intellij.plugins.bodhi.pmd.PMDUtil.KNOWN_CUSTOM_RULES;

/**
* This class represents the UI for settings.
Expand All @@ -53,6 +52,7 @@ public class PMDConfigurationForm {
private final List<String> deletedRuleSetPaths = new ArrayList<>();
private boolean isModified;
private final Project project;
private Map<String, String> validKnownCustomRules;

private static final List<String> columnNames = List.of("Option", "Value");
private static final String STAT_URL_MSG_SUCCESS = "Connection success; will use Statistics URL to export anonymous usage statistics";
Expand All @@ -78,6 +78,8 @@ public PMDConfigurationForm(final Project project) {
inEditorAnnotationRuleSets.setModel(new RuleSetListModel(new ArrayList<>()));
inEditorAnnotationRuleSets.getSelectionModel().addListSelectionListener(new SelectionChangeListener());
skipTestsCheckBox.addChangeListener(new CheckBoxChangeListener());

validKnownCustomRules = PMDUtil.getValidKnownCustomRules();
}

/**
Expand Down Expand Up @@ -177,43 +179,49 @@ private void modifyRuleSet(final String defaultValue, AnActionEvent e) {
db.show();
//If ok is selected add the selected ruleset
if (db.getDialogWrapper().getExitCode() == DialogWrapper.OK_EXIT_CODE) {
String rulesPath = panel.getText().trim();
RuleSetListModel listModel = (RuleSetListModel) ruleSetPathJList.getModel();
// if ruleSet by name, change to the URL
if (KNOWN_CUSTOM_RULES.containsKey(rulesPath)) {
rulesPath = KNOWN_CUSTOM_RULES.get(rulesPath);
ruleSetPathJList.setSelectedIndex(listModel.getSize());
}
String err;
if ( (err = PMDResultCollector.isValidRuleSet(rulesPath)).length() > 0) {
// make sense of error
int lastPartToShow = err.indexOf("valid file or URL");
int lastPos = (lastPartToShow > 0) ? lastPartToShow + 17 : Math.min(err.length(), 170);
String errTxt = err.substring(0, lastPos); // prevent excessive useless length
JOptionPane.showMessageDialog(panel, "The selected file/URL is not valid. PMD: " + errTxt,
"Invalid File/URL", JOptionPane.ERROR_MESSAGE);
return;
}
int selectedIndex = ruleSetPathJList.getSelectedIndex();
if (listModel.list.contains(rulesPath.trim())) {
selectedIndex = listModel.list.indexOf(rulesPath.trim());
ruleSetPathJList.setSelectedIndex(selectedIndex);
listModel.set(selectedIndex, rulesPath.trim()); // trigger menu update
return;
}
if (defaultValue != null && defaultValue.trim().length() > 0 && selectedIndex >= 0) {
listModel.set(selectedIndex, rulesPath);
return;
}

int index = listModel.getSize();
listModel.add(index, rulesPath);
ruleSetPathJList.setSelectedIndex(index);
deletedRuleSetPaths.remove(rulesPath);
String rulesRef = panel.getText().trim();
if (!rulesRef.startsWith("Warn")) { // warnings are just to notify the user, ignore as rules reference
RuleSetListModel listModel = (RuleSetListModel) ruleSetPathJList.getModel();
// if ruleSet referenced by name, change to the URL
String rulesPath = rulesRef;
if (validKnownCustomRules.containsKey(rulesRef)) {
rulesPath = validKnownCustomRules.get(rulesRef);
ruleSetPathJList.setSelectedIndex(listModel.getSize());
}
String err;
if ((err = PMDResultCollector.isValidRuleSet(rulesPath)).length() > 0) {
String message = "The selected file/URL is not valid.";
if (err.contains("XML validation errors occurred")) {
message += " The ruleset seems of PMD 6, use plugin version 1.9.x.";
}
// make sense of error
int lastPartToShow = err.indexOf("valid file or URL");
int lastPos = (lastPartToShow > 0) ? lastPartToShow + 17 : Math.min(err.length(), 170);
String errTxt = err.substring(0, lastPos); // prevent excessive useless length
JOptionPane.showMessageDialog(panel, message + " PMD: " + errTxt,
"Invalid File/URL", JOptionPane.ERROR_MESSAGE);
return;
}
int selectedIndex = ruleSetPathJList.getSelectedIndex();
if (listModel.list.contains(rulesPath.trim())) {
selectedIndex = listModel.list.indexOf(rulesPath.trim());
ruleSetPathJList.setSelectedIndex(selectedIndex);
listModel.set(selectedIndex, rulesPath.trim()); // trigger menu update
return;
}
if (defaultValue != null && defaultValue.trim().length() > 0 && selectedIndex >= 0) {
listModel.set(selectedIndex, rulesPath);
return;
}

RuleSetListModel inEditorAnnotationRuleSetsModel = (RuleSetListModel) inEditorAnnotationRuleSets.getModel();
inEditorAnnotationRuleSetsModel.add(inEditorAnnotationRuleSetsModel.getSize(), rulesPath);
int index = listModel.getSize();
listModel.add(index, rulesPath);
ruleSetPathJList.setSelectedIndex(index);
deletedRuleSetPaths.remove(rulesPath);

RuleSetListModel inEditorAnnotationRuleSetsModel = (RuleSetListModel) inEditorAnnotationRuleSets.getModel();
inEditorAnnotationRuleSetsModel.add(inEditorAnnotationRuleSetsModel.getSize(), rulesPath);
}
ruleSetPathJList.repaint();
}
}
Expand Down Expand Up @@ -468,8 +476,14 @@ public BrowsePanel(String defaultValue, final DialogBuilder db, final Project pr
add(label);
final Vector<String> elements = new Vector<>();
elements.add(defaultValue);
for (String ruleSetName : KNOWN_CUSTOM_RULES.keySet()) {
elements.add(ruleSetName);
Set<String> ruleSetNames = PMDUtil.getValidKnownCustomRules().keySet();
if (ruleSetNames.isEmpty()) {
elements.add("Warn: No pmd7 compatible ruleset found, revert to plugin version 1.9.x");
}
else {
for (String ruleSetName : ruleSetNames) {
elements.add(ruleSetName);
}
}
ComboBoxModel<String> model = new DefaultComboBoxModel<>(elements);
model.setSelectedItem(defaultValue);
Expand Down
21 changes: 18 additions & 3 deletions src/main/java/com/intellij/plugins/bodhi/pmd/PMDUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileFilter;
import com.intellij.openapi.vfs.VirtualFileVisitor;
import com.intellij.plugins.bodhi.pmd.core.PMDResultCollector;
import org.jetbrains.annotations.NotNull;

import java.io.File;
Expand All @@ -21,6 +22,7 @@
import java.util.StringJoiner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static java.util.Arrays.asList;

Expand All @@ -34,16 +36,29 @@ public class PMDUtil {

public static final Pattern HOST_NAME_PATTERN = Pattern.compile(".+\\.([a-z]+\\.[a-z]+)/.+");
public static final int AVAILABLE_PROCESSORS = Runtime.getRuntime().availableProcessors();
private static final String JPINPOINT_RULES = "https://raw.githubusercontent.com/jborgers/PMD-jPinpoint-rules/master/rulesets/java/jpinpoint-rules.xml";
public static final Map<String, String> KNOWN_CUSTOM_RULES = Map.of("jpinpoint-rules", JPINPOINT_RULES);
private static final String JPINPOINT_RULES = "https://raw.githubusercontent.com/jborgers/PMD-jPinpoint-rules/pmd7/rulesets/java/jpinpoint-rules.xml";
private static final Map<String, String> KNOWN_CUSTOM_RULES = Map.of("jpinpoint-rules", JPINPOINT_RULES);
private static volatile Map<String, String> validCustomRules; // lazy initialized

/**
* Not to be instantiated
*/
private PMDUtil() {}

/**
* Get the the Project Component from given Action.
* Returns the valid known custom rules
* @return the valid known custom rules
*/
public static Map<String, String> getValidKnownCustomRules() {
if (validCustomRules == null) {
validCustomRules = KNOWN_CUSTOM_RULES.entrySet().stream().filter(e -> PMDResultCollector.isValidRuleSet(e.getValue()).isEmpty())
.collect(Collectors.toUnmodifiableMap(e -> e.getKey(), e -> e.getValue()));
}
return validCustomRules;
}

/**
* Get the Project Component from given Action.
* @param event AnAction event
* @return the Project component related to the action
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ else if (threads.equals("1")) {
}

/**
* Verifies whether the rule set specified at the path is a valid PMD rule set. Always loads from file.
* Verifies whether the rule set specified at the path is a valid PMD rule set. Always loads from file/URL.
*
* @param path path of the rule set
* @return empty String for valid, an error message for invalid.
Expand Down

0 comments on commit 5c251a2

Please sign in to comment.