Skip to content

Commit 09126a8

Browse files
committed
Merge branch 'master' of https://github.com/amitdev/PMD-Intellij
2 parents 289ad93 + 4e98cfe commit 09126a8

File tree

6 files changed

+138
-60
lines changed

6 files changed

+138
-60
lines changed

src/com/intellij/plugins/bodhi/pmd/PMDInvoker.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,9 @@ public void run() {
180180
if (results.size() != 0) {
181181
if (isCustomRuleSet) {
182182
//For custom rulesets, using a separate format for rendering
183-
rules[i] = PMDUtil.getRuleNameFromPath(rules[i]) + ";" + rules[i];
183+
rules[i] = PMDUtil.getBareFileNameFromPath(rules[i]) + ";" + rules[i];
184184
} else {
185-
rules[i] = PMDUtil.getRuleName(rules[i]);
185+
rules[i] = PMDUtil.getBareFileNameFromPath(rules[i]);
186186
}
187187
DefaultMutableTreeNode node = resultPanel.addNode(rules[i]);
188188
//Add all nodes to the tree

src/com/intellij/plugins/bodhi/pmd/PMDProjectComponent.java

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import com.intellij.openapi.components.State;
1010
import com.intellij.openapi.components.Storage;
1111
import com.intellij.openapi.project.Project;
12-
import com.intellij.openapi.util.Pair;
1312
import com.intellij.openapi.wm.ToolWindow;
1413
import com.intellij.openapi.wm.ToolWindowAnchor;
1514
import com.intellij.openapi.wm.ToolWindowManager;
@@ -24,12 +23,7 @@
2423
import org.jetbrains.annotations.NotNull;
2524

2625
import javax.swing.*;
27-
import java.util.ArrayList;
28-
import java.util.HashMap;
29-
import java.util.Iterator;
30-
import java.util.List;
31-
import java.util.Locale;
32-
import java.util.Map;
26+
import java.util.*;
3327

3428
/**
3529
*
@@ -61,9 +55,8 @@ public class PMDProjectComponent implements ProjectComponent, PersistentStateCom
6155
private String lastRunRules;
6256
private boolean lastRunRulesCustom;
6357
private AnActionEvent lastRunActionEvent;
64-
private List<String> customRuleSetPaths = new ArrayList<String>();
58+
private Set<String> customRuleSetPaths = new LinkedHashSet<>(); // avoid duplicates, maintain order
6559
private Map<String, String> options = new HashMap<>();
66-
private Map<String, Pair<String, AnAction>> customActionsMap = new HashMap<String, Pair<String, AnAction>>();
6760
private ToolWindowManager toolWindowManager;
6861
private boolean skipTestSources;
6962
private boolean scanFilesBeforeCheckin;
@@ -100,36 +93,48 @@ private ActionGroup registerActions(String actionName) {
10093
return actionGroup;
10194
}
10295

96+
private boolean hasDuplicateBareFileName(Iterable<String> paths) {
97+
boolean duplicate = false;
98+
List fileNames = new ArrayList();
99+
for (String path : paths) {
100+
String fileName = PMDUtil.getBareFileNameFromPath(path);
101+
if (fileNames.contains(fileName)) {
102+
duplicate = true;
103+
break;
104+
}
105+
fileNames.add(fileName);
106+
}
107+
return duplicate;
108+
}
109+
110+
/**
111+
* Reflect customRuleSetPaths into actionGroup (ActionManager singleton instance)
112+
*/
103113
void updateCustomRulesMenu() {
104114
PMDCustom actionGroup = (PMDCustom) ActionManager.getInstance().getAction("PMDCustom");
115+
actionGroup.removeAll(); // start clean
116+
boolean hasDuplicate = hasDuplicateBareFileName(customRuleSetPaths);
105117
for (final String rulePath : customRuleSetPaths) {
106-
if (customActionsMap.containsKey(rulePath)) {
107-
continue;
108-
}
109118
try {
110119
RuleSet ruleSet = PMDResultCollector.loadRuleSet(rulePath);
111-
String ruleFileName = PMDUtil.getRuleNameFromPath(rulePath);
112-
AnAction action = new AnAction(String.format(Locale.ENGLISH, "%s (%s)",ruleSet.getName() , ruleFileName)) {
120+
String ruleSetName = ruleSet.getName(); // from the xml
121+
String extFileName = PMDUtil.getExtendedFileNameFromPath(rulePath);
122+
String bareFileName = PMDUtil.getBareFileNameFromPath(rulePath);
123+
String actionText = ruleSetName;
124+
if (!ruleSetName.equals(bareFileName) || hasDuplicate) {
125+
actionText += " (" + extFileName + ")";
126+
}
127+
AnAction action = new AnAction(actionText) {
113128
public void actionPerformed(AnActionEvent e) {
114129
PMDInvoker.getInstance().runPMD(e, rulePath, true);
115130
setLastRunActionAndRules(e, rulePath, true);
116131
}
117132
};
118-
customActionsMap.put(rulePath, Pair.create(ruleFileName, action));
119133
actionGroup.add(action);
120134
} catch (PMDResultCollector.InvalidRuleSetException e) {
121135
JOptionPane.showMessageDialog(resultPanel,
122-
"The ruleset file is not available or not a valid PMD ruleset:\n"
123-
+ e.getMessage(),
124-
"Invalid File", JOptionPane.ERROR_MESSAGE);
125-
}
126-
}
127-
for (Iterator<Map.Entry<String, Pair<String, AnAction>>> iterator = customActionsMap.entrySet().iterator(); iterator.hasNext();) {
128-
Map.Entry<String, Pair<String, AnAction>> entry = iterator.next();
129-
String rulePath = entry.getKey();
130-
if (!customRuleSetPaths.contains(rulePath)) {
131-
actionGroup.remove(entry.getValue().getSecond());
132-
iterator.remove();
136+
"The ruleset file is not available or not a valid PMD ruleset:\n" + e.getMessage(),
137+
"Invalid File", JOptionPane.ERROR_MESSAGE);
133138
}
134139
}
135140
}
@@ -239,7 +244,7 @@ public List<String> getCustomRuleSets() {
239244
}
240245

241246
public void setCustomRuleSets(List<String> customRuleSetPaths) {
242-
this.customRuleSetPaths = new ArrayList(customRuleSetPaths);
247+
this.customRuleSetPaths = new LinkedHashSet(customRuleSetPaths);
243248
}
244249

245250
public Map<String, String> getOptions() {
@@ -250,6 +255,10 @@ public void setOptions(Map<String, String> options) {
250255
this.options = options;
251256
}
252257

258+
/**
259+
* Return fields in a PersistentData object
260+
* @return
261+
*/
253262
@NotNull
254263
public PersistentData getState() {
255264
final PersistentData pd = new PersistentData();
@@ -259,11 +268,15 @@ public PersistentData getState() {
259268
for (String key : options.keySet()) {
260269
pd.getOptions().put(key, options.get(key));
261270
}
262-
pd.skipTestSources(skipTestSources);
271+
pd.setSkipTestSources(skipTestSources);
263272
pd.setScanFilesBeforeCheckin(scanFilesBeforeCheckin);
264273
return pd;
265274
}
266275

276+
/**
277+
* load state into fields
278+
* @param state
279+
*/
267280
public void loadState(PersistentData state) {
268281
customRuleSetPaths.clear();
269282
options.clear();

src/com/intellij/plugins/bodhi/pmd/PMDUtil.java

Lines changed: 73 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
import com.intellij.openapi.actionSystem.AnActionEvent;
44
import com.intellij.openapi.actionSystem.PlatformDataKeys;
5-
import com.intellij.openapi.module.Module;
65
import com.intellij.openapi.module.ModuleManager;
6+
import com.intellij.openapi.module.Module;
77
import com.intellij.openapi.project.Project;
88
import com.intellij.openapi.roots.OrderEnumerator;
99
import com.intellij.openapi.vfs.VfsUtilCore;
@@ -16,6 +16,8 @@
1616
import java.io.FileFilter;
1717
import java.util.List;
1818
import java.util.StringJoiner;
19+
import java.util.regex.Matcher;
20+
import java.util.regex.Pattern;
1921

2022
import static java.util.Arrays.asList;
2123

@@ -27,6 +29,8 @@
2729
*/
2830
public class PMDUtil {
2931

32+
public static final Pattern HOST_NAME_PATTERN = Pattern.compile(".+\\.([a-z]+\\.[a-z]+)/.+");
33+
3034
/**
3135
* Get the the Project Component from given Action.
3236
* @param event AnAction event
@@ -121,24 +125,83 @@ public String getDescription() {
121125
}
122126

123127
/**
124-
* Parses and returns the rule name from path.
128+
* Parses and returns the rule file name without extension from path.
125129
* Rulename is got by getting the filename from path and stripping off
126130
* the extension.
127131
*
128132
* @param rulePath the path
129133
* @return the rule name
130134
*/
131-
public static String getRuleNameFromPath(String rulePath) {
135+
public static String getBareFileNameFromPath(String rulePath) {
136+
String fileName = getFileNameFromPath(rulePath);
137+
int indexDot = fileName.indexOf('.');
138+
if (indexDot == -1) { // not found
139+
return fileName;
140+
}
141+
return fileName.substring(0, indexDot);
142+
}
143+
144+
/**
145+
* Returns the file name including extension from path.
146+
*
147+
* @param rulePath the path
148+
* @return the rule file name including extension
149+
*/
150+
public static String getFileNameFromPath(String rulePath) {
132151
int index = rulePath.lastIndexOf(File.separatorChar);
133-
int indexDot = rulePath.indexOf('.', index);
134-
if (indexDot == -1) {
135-
indexDot = rulePath.length();
152+
return rulePath.substring(index + 1); // if not found (-1), start from 0
153+
}
154+
155+
/**
156+
* Parses and returns the extended rule file name from path, to include part of the path to distinguish between
157+
* the same ruleset in different locations. Include the file extension.
158+
*
159+
* @param rulePath the path of the rule set
160+
* @return the extended rule file name
161+
*/
162+
public static String getExtendedFileNameFromPath(String rulePath) {
163+
int index = rulePath.lastIndexOf(File.separatorChar); // index of last '/'
164+
if (index == -1) {
165+
return rulePath;
166+
}
167+
String shortPathDesc = "";
168+
if (rulePath.startsWith("http")) {
169+
shortPathDesc = getHostNameFromPath(rulePath) + ": " + rulePath.substring(index + 1);
170+
}
171+
else {
172+
shortPathDesc = getFileBaseFromPath(rulePath) + ": " + rulePath.substring(index + 1);
136173
}
137-
String ruleName = rulePath;
138-
if (index != -1) {
139-
ruleName = rulePath.substring(index+1, indexDot);
174+
return shortPathDesc;
175+
}
176+
177+
/**
178+
* Returns the hostname like: githubusercontent.com from the path
179+
* @param rulePath
180+
* @return the hostname like: githubusercontent.com
181+
*/
182+
private static String getHostNameFromPath(String rulePath) {
183+
String hostName = "";
184+
Matcher m = HOST_NAME_PATTERN.matcher(rulePath);
185+
if (m.matches()) {
186+
hostName = m.group(1);
187+
}
188+
return hostName;
189+
}
190+
191+
/**
192+
* Returns the file base path like: /Users/john from the path
193+
* @param rulePath
194+
* @return the hostname like: githubusercontent.com
195+
*/
196+
private static String getFileBaseFromPath(String rulePath) {
197+
int sepIndex1 = rulePath.indexOf(File.separatorChar);
198+
int sepIndex2 = rulePath.indexOf(File.separatorChar, sepIndex1 + 1);
199+
int sepIndex3 = rulePath.indexOf(File.separatorChar, sepIndex2 + 1);
200+
String fileBase = "";
201+
if (sepIndex3 > -1) {
202+
fileBase = rulePath.substring(0, sepIndex3);
140203
}
141-
return ruleName;
204+
return fileBase;
142205
}
143206

144207
private static boolean isMatchingExtension(File pathname, String extension) {

src/com/intellij/plugins/bodhi/pmd/PersistentData.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
import java.util.Map;
77

88
public class PersistentData {
9+
private static final boolean DEFAULT_SKIP_TEST_SRC = true;
910
private List<String> customRuleSets;
1011
private Map<String, String> options;
11-
private String skipTestSources;
12+
private boolean skipTestSources = DEFAULT_SKIP_TEST_SRC;
1213
private boolean scanFilesBeforeCheckin;
1314

1415
public PersistentData() {
@@ -20,33 +21,32 @@ public List<String> getCustomRuleSets() {
2021
return customRuleSets;
2122
}
2223

23-
public void setCustomRuleSets(List<String> customRuleSets) {
24-
this.customRuleSets = customRuleSets;
24+
public void setCustomRuleSets(List<String> rules) {
25+
this.customRuleSets = rules;
2526
}
2627

2728
public Map<String, String> getOptions() {
2829
return options;
2930
}
3031

31-
public void setOptions(Map<String, String> options) {
32-
this.options = options;
32+
public void setOptions(Map<String, String> opts) {
33+
options = opts;
3334
}
3435

35-
public void skipTestSources(boolean skipTestSources)
36-
{
37-
this.skipTestSources = String.valueOf(skipTestSources);
36+
public void setSkipTestSources(boolean skip) {
37+
skipTestSources = skip;
3838
}
3939

40-
public boolean isSkipTestSources()
41-
{
42-
return Boolean.valueOf(skipTestSources);
40+
public boolean isSkipTestSources() {
41+
return skipTestSources;
4342
}
4443

4544
public boolean isScanFilesBeforeCheckin() {
4645
return scanFilesBeforeCheckin;
4746
}
4847

49-
public void setScanFilesBeforeCheckin(boolean scanFilesBeforeCheckin) {
50-
this.scanFilesBeforeCheckin = scanFilesBeforeCheckin;
48+
public void setScanFilesBeforeCheckin(boolean scan) {
49+
scanFilesBeforeCheckin = scan;
5150
}
51+
5252
}

src/com/intellij/plugins/bodhi/pmd/actions/PreDefinedMenuGroup.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
package com.intellij.plugins.bodhi.pmd.actions;
22

3-
import com.intellij.openapi.actionSystem.*;
4-
import com.intellij.plugins.bodhi.pmd.PMDUtil;
3+
import com.intellij.openapi.actionSystem.ActionGroup;
4+
import com.intellij.openapi.actionSystem.AnAction;
5+
import com.intellij.openapi.actionSystem.AnActionEvent;
6+
import com.intellij.openapi.actionSystem.DefaultActionGroup;
57
import com.intellij.plugins.bodhi.pmd.PMDInvoker;
68
import com.intellij.plugins.bodhi.pmd.PMDProjectComponent;
9+
import com.intellij.plugins.bodhi.pmd.PMDUtil;
10+
import net.sourceforge.pmd.util.ResourceLoader;
711
import org.jetbrains.annotations.Nullable;
812

9-
import java.util.Properties;
1013
import java.io.IOException;
11-
12-
import net.sourceforge.pmd.util.ResourceLoader;
14+
import java.util.Properties;
1315

1416
/**
1517
* This ActionGroup defines the actions for pre defined rulesets that
@@ -55,7 +57,7 @@ public void actionPerformed(AnActionEvent e) {
5557

5658
for (int i=0; i < rulesetFilenames.length; ++i) {
5759
final String ruleFileName = rulesetFilenames[i];
58-
final String ruleName = PMDUtil.getRuleName(ruleFileName);
60+
final String ruleName = PMDUtil.getBareFileNameFromPath(ruleFileName);
5961
allRules += ruleFileName;
6062
allRules += (i == rulesetFilenames.length - 1) ? "" : PMDInvoker.RULE_DELIMITER;
6163
AnAction ruleAction = new AnAction(ruleName) {

src/com/intellij/plugins/bodhi/pmd/handlers/PMDCheckinHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ private DefaultMutableTreeNode scanFiles(String ruleSet, PMDProjectComponent plu
127127
}
128128

129129
private DefaultMutableTreeNode createRuleSetNode(String ruleSet, List<DefaultMutableTreeNode> results) {
130-
ruleSet = PMDUtil.getRuleNameFromPath(ruleSet) + ";" + ruleSet;
130+
ruleSet = PMDUtil.getFileNameFromPath(ruleSet) + ";" + ruleSet;
131131
DefaultMutableTreeNode ruleSetNode = PMDTreeNodeFactory.getInstance().createNode(ruleSet);
132132

133133
int childCount = 0;

0 commit comments

Comments
 (0)