diff --git a/CHANGELOG.md b/CHANGELOG.md index 7246674..ea5813e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/main/java/com/intellij/plugins/bodhi/pmd/PMDConfigurationForm.java b/src/main/java/com/intellij/plugins/bodhi/pmd/PMDConfigurationForm.java index 61d2771..c9b4855 100644 --- a/src/main/java/com/intellij/plugins/bodhi/pmd/PMDConfigurationForm.java +++ b/src/main/java/com/intellij/plugins/bodhi/pmd/PMDConfigurationForm.java @@ -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. @@ -53,6 +52,7 @@ public class PMDConfigurationForm { private final List deletedRuleSetPaths = new ArrayList<>(); private boolean isModified; private final Project project; + private Map validKnownCustomRules; private static final List columnNames = List.of("Option", "Value"); private static final String STAT_URL_MSG_SUCCESS = "Connection success; will use Statistics URL to export anonymous usage statistics"; @@ -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(); } /** @@ -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(); } } @@ -468,8 +476,14 @@ public BrowsePanel(String defaultValue, final DialogBuilder db, final Project pr add(label); final Vector elements = new Vector<>(); elements.add(defaultValue); - for (String ruleSetName : KNOWN_CUSTOM_RULES.keySet()) { - elements.add(ruleSetName); + Set 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 model = new DefaultComboBoxModel<>(elements); model.setSelectedItem(defaultValue); diff --git a/src/main/java/com/intellij/plugins/bodhi/pmd/PMDUtil.java b/src/main/java/com/intellij/plugins/bodhi/pmd/PMDUtil.java index fc33e85..a913fa5 100644 --- a/src/main/java/com/intellij/plugins/bodhi/pmd/PMDUtil.java +++ b/src/main/java/com/intellij/plugins/bodhi/pmd/PMDUtil.java @@ -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; @@ -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; @@ -34,8 +36,9 @@ 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 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 KNOWN_CUSTOM_RULES = Map.of("jpinpoint-rules", JPINPOINT_RULES); + private static volatile Map validCustomRules; // lazy initialized /** * Not to be instantiated @@ -43,7 +46,19 @@ public class PMDUtil { 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 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 */ diff --git a/src/main/java/com/intellij/plugins/bodhi/pmd/core/PMDResultCollector.java b/src/main/java/com/intellij/plugins/bodhi/pmd/core/PMDResultCollector.java index ab43a54..2531326 100644 --- a/src/main/java/com/intellij/plugins/bodhi/pmd/core/PMDResultCollector.java +++ b/src/main/java/com/intellij/plugins/bodhi/pmd/core/PMDResultCollector.java @@ -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.