Skip to content

Commit 3d07697

Browse files
committed
(feat) Add a PMD specific marker property page
This shows more detailed information about the violation and the rule.
1 parent e15df4f commit 3d07697

File tree

6 files changed

+197
-2
lines changed

6 files changed

+197
-2
lines changed

net.sourceforge.pmd.eclipse.plugin.test/src/main/java/net/sourceforge/pmd/eclipse/runtime/cmd/ReviewCmdTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ public void testReviewCmdBasic() throws CoreException {
112112
Assert.assertEquals(markers.get(sourceFile).size(), imarkers.size());
113113
for (IMarker marker : imarkers) {
114114
Assert.assertTrue(marker.isSubtypeOf(IMarker.PROBLEM));
115-
Assert.assertTrue(marker.getAttribute(IMarker.MESSAGE, "")
116-
.startsWith(marker.getAttribute(PMDRuntimeConstants.KEY_MARKERATT_RULENAME, "missing rule name")));
115+
Assert.assertTrue(((String) marker.getAttribute(IMarker.MESSAGE))
116+
.startsWith((String) marker.getAttribute(PMDRuntimeConstants.KEY_MARKERATT_RULENAME)));
117117
}
118118
}
119119

net.sourceforge.pmd.eclipse.plugin/plugin.xml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,22 @@
359359
class="net.sourceforge.pmd.eclipse.ui.properties.PMDProjectPropertyPage"
360360
id="net.sourceforge.pmd.eclipse.ui.properties.pmdPropertyPage">
361361
</page>
362+
<page
363+
adaptable="true"
364+
class="net.sourceforge.pmd.eclipse.ui.properties.PMDMarkerPropertyPage"
365+
id="net.sourceforge.pmd.eclipse.ui.properties.markerPropertyPage"
366+
name="PMD Marker"
367+
nameFilter="*"
368+
objectClass="org.eclipse.core.resources.IMarker">
369+
<enabledWhen>
370+
<adapt
371+
type="org.eclipse.core.resources.IMarker">
372+
<test
373+
property="net.sourceforge.pmd.eclipse.plugin.isPMDMarker">
374+
</test>
375+
</adapt>
376+
</enabledWhen>
377+
</page>
362378
</extension>
363379

364380
<extension
@@ -803,5 +819,15 @@
803819
</public>
804820
</catalogContribution>
805821
</extension>
822+
<extension
823+
point="org.eclipse.core.expressions.propertyTesters">
824+
<propertyTester
825+
class="net.sourceforge.pmd.eclipse.ui.properties.MarkerPropertyTester"
826+
id="net.sourceforge.pmd.eclipse.isPMDMarker"
827+
namespace="net.sourceforge.pmd.eclipse.plugin"
828+
properties="isPMDMarker"
829+
type="org.eclipse.core.resources.IMarker">
830+
</propertyTester>
831+
</extension>
806832

807833
</plugin>

net.sourceforge.pmd.eclipse.plugin/src/main/java/net/sourceforge/pmd/eclipse/runtime/PMDRuntimeConstants.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ public class PMDRuntimeConstants {
4141
public static final String KEY_MARKERATT_LINE2 = "line2";
4242
public static final String KEY_MARKERATT_VARIABLE = "variable";
4343
public static final String KEY_MARKERATT_METHODNAME = "method";
44+
/**
45+
* The message from the rule violation. This is additionally here, since IMarker.MESSAGE will
46+
* contain both rule name + message.
47+
*/
48+
public static final String KEY_MARKERATT_MESSAGE = "pmd_message";
4449

4550
public static final String PLUGIN_STYLE_REVIEW_COMMENT = "// @PMD:REVIEWED:";
4651
public static final String PMD_STYLE_REVIEW_COMMENT = "// NOPMD";

net.sourceforge.pmd.eclipse.plugin/src/main/java/net/sourceforge/pmd/eclipse/runtime/cmd/BaseVisitor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,7 @@ private MarkerInfo2 getMarkerInfo(RuleViolation violation, String type) throws P
630630
MarkerInfo2 info = new MarkerInfo2(type, 7);
631631

632632
info.add(IMarker.MESSAGE, rule.getName() + ": " + violation.getDescription());
633+
info.add(PMDRuntimeConstants.KEY_MARKERATT_MESSAGE, violation.getDescription());
633634
info.add(IMarker.LINE_NUMBER, violation.getBeginLine());
634635
info.add(PMDRuntimeConstants.KEY_MARKERATT_LINE2, violation.getEndLine());
635636
info.add(PMDRuntimeConstants.KEY_MARKERATT_RULENAME, rule.getName());
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3+
*/
4+
5+
package net.sourceforge.pmd.eclipse.ui.properties;
6+
7+
import org.eclipse.core.expressions.PropertyTester;
8+
import org.eclipse.core.resources.IMarker;
9+
import org.eclipse.core.runtime.CoreException;
10+
11+
import net.sourceforge.pmd.eclipse.plugin.PMDPlugin;
12+
13+
public class MarkerPropertyTester extends PropertyTester {
14+
@Override
15+
public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
16+
if (!(receiver instanceof IMarker)) {
17+
return false;
18+
}
19+
20+
IMarker marker = (IMarker) receiver;
21+
22+
try {
23+
return marker.getType().startsWith(PMDPlugin.PLUGIN_ID);
24+
} catch (CoreException e) {
25+
PMDPlugin.getDefault().logError(e.getMessage(), e);
26+
}
27+
return false;
28+
}
29+
30+
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/**
2+
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3+
*/
4+
5+
package net.sourceforge.pmd.eclipse.ui.properties;
6+
7+
import java.net.MalformedURLException;
8+
import java.net.URL;
9+
10+
import org.eclipse.core.resources.IMarker;
11+
import org.eclipse.core.runtime.CoreException;
12+
import org.eclipse.swt.SWT;
13+
import org.eclipse.swt.events.SelectionEvent;
14+
import org.eclipse.swt.events.SelectionListener;
15+
import org.eclipse.swt.layout.GridData;
16+
import org.eclipse.swt.layout.GridLayout;
17+
import org.eclipse.swt.widgets.Composite;
18+
import org.eclipse.swt.widgets.Control;
19+
import org.eclipse.swt.widgets.Label;
20+
import org.eclipse.swt.widgets.Link;
21+
import org.eclipse.swt.widgets.Text;
22+
import org.eclipse.ui.PartInitException;
23+
import org.eclipse.ui.PlatformUI;
24+
import org.eclipse.ui.browser.IWebBrowser;
25+
import org.eclipse.ui.dialogs.PropertyPage;
26+
27+
import net.sourceforge.pmd.Rule;
28+
import net.sourceforge.pmd.eclipse.plugin.PMDPlugin;
29+
import net.sourceforge.pmd.eclipse.runtime.PMDRuntimeConstants;
30+
import net.sourceforge.pmd.eclipse.runtime.builder.MarkerUtil;
31+
32+
public class PMDMarkerPropertyPage extends PropertyPage {
33+
34+
@Override
35+
protected Control createContents(Composite parent) {
36+
noDefaultAndApplyButton();
37+
38+
Composite composite = new Composite(parent, SWT.NULL);
39+
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
40+
GridLayout layout = new GridLayout();
41+
layout.numColumns = 2;
42+
composite.setLayout(layout);
43+
44+
45+
IMarker marker = (IMarker) getElement();
46+
Rule rule = PMDPlugin.getDefault().getPreferencesManager().getRuleSet()
47+
.getRuleByName(MarkerUtil.ruleNameFor(marker));
48+
49+
try {
50+
addLabel(composite, "Rule:");
51+
addText(composite, rule.getName());
52+
53+
addLabel(composite, "Category:");
54+
addText(composite, rule.getRuleSetName());
55+
56+
addLabel(composite, "Priority:");
57+
addText(composite, rule.getPriority().name());
58+
59+
addLabel(composite, "Message:");
60+
addText(composite, getViolationMessage(marker));
61+
62+
addLabel(composite, "Description:", 2);
63+
addDescription(composite, rule);
64+
65+
addLabel(composite, "External URL Info:");
66+
addLink(composite, rule);
67+
} catch (CoreException e) {
68+
PMDPlugin.getDefault().logError(e.getMessage(), e);
69+
}
70+
71+
return composite;
72+
}
73+
74+
private String getViolationMessage(IMarker marker) throws CoreException {
75+
String defaultMessage = marker.getAttribute(IMarker.MESSAGE, "");
76+
return marker.getAttribute(PMDRuntimeConstants.KEY_MARKERATT_MESSAGE, defaultMessage);
77+
}
78+
79+
private void addDescription(Composite composite, Rule rule) {
80+
Text descriptionText = new Text(composite, SWT.MULTI | SWT.WRAP | SWT.READ_ONLY);
81+
GridData gridData = new GridData(GridData.FILL_BOTH);
82+
gridData.horizontalSpan = 2;
83+
gridData.heightHint = 50;
84+
descriptionText.setLayoutData(gridData);
85+
descriptionText.setText(rule.getDescription());
86+
}
87+
88+
private void addLink(Composite composite, Rule rule) {
89+
Link link = new Link(composite, SWT.NONE);
90+
link.setText("<a href=\"" + rule.getExternalInfoUrl() + "\">" + rule.getExternalInfoUrl() + "</a>");
91+
link.addSelectionListener(new LinkClickListener());
92+
}
93+
94+
private void addText(Composite parent, String value) {
95+
Text text = new Text(parent, SWT.READ_ONLY | SWT.SINGLE);
96+
text.setBackground(parent.getBackground());
97+
GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
98+
text.setLayoutData(gridData);
99+
text.setText(value);
100+
}
101+
102+
private void addLabel(Composite parent, String label) {
103+
addLabel(parent, label, 1);
104+
}
105+
106+
private void addLabel(Composite parent, String text, int columnSpan) {
107+
Label label = new Label(parent, SWT.NONE);
108+
if (columnSpan > 1) {
109+
GridData gridData = new GridData();
110+
gridData.horizontalSpan = columnSpan;
111+
label.setLayoutData(gridData);
112+
}
113+
label.setText(text);
114+
}
115+
116+
private static final class LinkClickListener implements SelectionListener {
117+
@Override
118+
public void widgetSelected(SelectionEvent e) {
119+
try {
120+
URL url = new URL(e.text);
121+
IWebBrowser browser = PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser();
122+
browser.openURL(url);
123+
} catch (MalformedURLException | PartInitException e1) {
124+
PMDPlugin.getDefault().logError(e1.getMessage(), e1);
125+
}
126+
}
127+
128+
@Override
129+
public void widgetDefaultSelected(SelectionEvent e) {
130+
widgetSelected(e);
131+
}
132+
}
133+
}

0 commit comments

Comments
 (0)