Skip to content

Commit 0daad64

Browse files
authored
Merge pull request #179 from adangel/show-violation-details
Implement new dialog to show violation details
2 parents 98dd831 + 03d154a commit 0daad64

33 files changed

+706
-3034
lines changed

ReleaseNotes.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,30 @@ This is a minor release.
1515

1616
### Fixed Issues
1717

18+
* [#178](https://github.com/pmd/pmd-eclipse-plugin/issues/178): Message not interpolated in "Show details..." dialog
19+
1820
### API Changes
1921

22+
The following packages are no longer public API and are not exported anymore:
23+
* name.herlin.command
24+
* net.sourceforge.pmd.eclipse.core.impl
25+
* net.sourceforge.pmd.eclipse.ui
26+
* net.sourceforge.pmd.eclipse.ui.actions
27+
* net.sourceforge.pmd.eclipse.ui.model
28+
* net.sourceforge.pmd.eclipse.ui.preferences.br
29+
* net.sourceforge.pmd.eclipse.ui.properties
30+
* net.sourceforge.pmd.eclipse.ui.views.actions
31+
32+
The following classes have finally been removed. Most of them have been deprecated before:
33+
* net.sourceforge.pmd.eclipse.ui.preferences.PMDPreferencePage
34+
* net.sourceforge.pmd.eclipse.ui.preferences.RuleCellModifier
35+
* net.sourceforge.pmd.eclipse.ui.preferences.RuleDialog
36+
* net.sourceforge.pmd.eclipse.ui.preferences.RulePropertyCellModifier (was not deprecated)
37+
* net.sourceforge.pmd.eclipse.ui.preferences.RuleSetExcludeIncludePatternCellModifier (was not deprecated)
38+
* net.sourceforge.pmd.eclipse.ui.properties.PMDPropertyPage
39+
* net.sourceforge.pmd.eclipse.ui.views.actions.ShowRuleAction (was not deprecated)
40+
* net.sourceforge.pmd.eclipse.ui.views.rules.RuleEditorView
41+
2042
### External Contributions
2143

2244
## 02-May-2023: 7.0.0.v20230502-1028-rc2

net.sourceforge.pmd.eclipse.plugin.test/META-INF/MANIFEST.MF

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ Require-Bundle: org.eclipse.ui,
1313
org.eclipse.jdt.core,
1414
org.eclipse.jdt.launching,
1515
org.junit,
16-
org.apache.commons.io
16+
org.apache.commons.io,
17+
org.eclipse.swtbot.go,
18+
org.eclipse.jdt.ui,
19+
org.eclipse.ui.navigator.resources
1720
Bundle-Activator: net.sourceforge.pmd.eclipse.internal.TestActivator
1821
Bundle-ActivationPolicy: lazy
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
/*
2+
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3+
*/
4+
5+
package net.sourceforge.pmd.eclipse.ui.dialogs;
6+
7+
import static org.junit.Assert.assertEquals;
8+
9+
import java.io.InputStream;
10+
11+
import org.eclipse.core.resources.IMarker;
12+
import org.eclipse.core.resources.IProject;
13+
import org.eclipse.core.resources.IResource;
14+
import org.eclipse.core.resources.IncrementalProjectBuilder;
15+
import org.eclipse.core.runtime.CoreException;
16+
import org.eclipse.core.runtime.NullProgressMonitor;
17+
import org.eclipse.jdt.ui.JavaUI;
18+
import org.eclipse.swt.widgets.Display;
19+
import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
20+
import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView;
21+
import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
22+
import org.eclipse.swtbot.swt.finder.waits.DefaultCondition;
23+
import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell;
24+
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTableItem;
25+
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTree;
26+
import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem;
27+
import org.eclipse.ui.IWorkbench;
28+
import org.eclipse.ui.IWorkbenchPage;
29+
import org.eclipse.ui.IWorkbenchWindow;
30+
import org.eclipse.ui.PlatformUI;
31+
import org.eclipse.ui.WorkbenchException;
32+
import org.eclipse.ui.navigator.resources.ProjectExplorer;
33+
import org.junit.After;
34+
import org.junit.AfterClass;
35+
import org.junit.Assert;
36+
import org.junit.Before;
37+
import org.junit.BeforeClass;
38+
import org.junit.Test;
39+
import org.junit.runner.RunWith;
40+
41+
import net.sourceforge.pmd.eclipse.EclipseUtils;
42+
import net.sourceforge.pmd.eclipse.plugin.PMDPlugin;
43+
import net.sourceforge.pmd.eclipse.runtime.PMDRuntimeConstants;
44+
import net.sourceforge.pmd.eclipse.runtime.properties.IProjectProperties;
45+
46+
@RunWith(SWTBotJunit4ClassRunner.class)
47+
public class ViolationDetailsDialogTest {
48+
private static SWTWorkbenchBot bot;
49+
private static final String PROJECT_NAME = ViolationDetailsDialogTest.class.getSimpleName();
50+
51+
private IProject testProject;
52+
53+
@BeforeClass
54+
public static void initBot() throws InterruptedException {
55+
bot = new SWTWorkbenchBot();
56+
for (SWTBotView view : bot.views()) {
57+
if ("Welcome".equals(view.getTitle())) {
58+
view.close();
59+
}
60+
}
61+
}
62+
63+
@AfterClass
64+
public static void afterClass() {
65+
try {
66+
bot.resetWorkbench();
67+
} catch (Exception e) {
68+
e.printStackTrace();
69+
}
70+
}
71+
72+
73+
@Before
74+
public void setUp() throws Exception {
75+
// 1. Create a Java project
76+
this.testProject = EclipseUtils.createJavaProject(PROJECT_NAME);
77+
Assert.assertTrue("A test project cannot be created; the tests cannot be performed.",
78+
this.testProject != null && this.testProject.exists() && this.testProject.isAccessible());
79+
80+
// 2. Create a test source file inside that project
81+
EclipseUtils.createTestSourceFile(testProject, "/src/MyInterface.java", "public interface MyInterface {\n public void run();\n}\n".replaceAll("\\R", System.lineSeparator()));
82+
try (InputStream is = EclipseUtils.getResourceStream(this.testProject, "/src/MyInterface.java")) {
83+
Assert.assertNotNull("Cannot find the test source file", is);
84+
}
85+
86+
// 3. Enable PMD for the test project
87+
IProjectProperties properties = PMDPlugin.getDefault().getPropertiesManager()
88+
.loadProjectProperties(testProject);
89+
properties.setPmdEnabled(true);
90+
properties.sync();
91+
}
92+
93+
@After
94+
public void tearDown() throws Exception {
95+
try {
96+
if (this.testProject != null) {
97+
if (this.testProject.exists() && this.testProject.isAccessible()) {
98+
EclipseUtils.removePMDNature(this.testProject);
99+
this.testProject.refreshLocal(IResource.DEPTH_INFINITE, null);
100+
this.testProject.delete(true, true, null);
101+
this.testProject = null;
102+
}
103+
}
104+
} catch (final Exception e) {
105+
System.out.println("Exception " + e.getClass().getName() + " when tearing down. Ignored.");
106+
}
107+
}
108+
109+
@Test
110+
public void openDialogViaProblemView() throws Exception {
111+
buildAndWaitForViolations();
112+
openJavaPerspective();
113+
114+
SWTBotView problemsView = bot.viewByPartName("Problems");
115+
problemsView.bot().tree().getTreeItem("Warnings (4 items)").expand();
116+
SWTBotTreeItem item = problemsView.bot().tree().getTreeItem("Warnings (4 items)").getNode("UnnecessaryModifier: Unnecessary modifier 'public' on method 'run': the method is declared in an interface type").select();
117+
item.contextMenu("Show details...").click();
118+
119+
assertDialog();
120+
}
121+
122+
@Test
123+
public void openDialogViaViolationOutlineView() throws Exception {
124+
buildAndWaitForViolations();
125+
openPMDPerspective();
126+
127+
SWTBotTree projectTree = bot.viewByPartName("Package Explorer").bot().tree();
128+
SWTBotTreeItem item = projectTree.getTreeItem("ViolationDetailsDialogTest").expand();
129+
item = item.getNode("src").expand();
130+
item = item.getNode("(default package)").expand();
131+
item = item.getNode("MyInterface.java").select();
132+
item.doubleClick();
133+
134+
SWTBotView outlineView = bot.viewByPartName("Violations Outline");
135+
int row = outlineView.bot().table().indexOf("UnnecessaryModifier", 3);
136+
SWTBotTableItem tableItem = outlineView.bot().table().getTableItem(row);
137+
tableItem.select();
138+
tableItem.contextMenu("Show details ...").click();
139+
140+
assertDialog();
141+
}
142+
143+
private void assertDialog() {
144+
SWTBotShell dialog = bot.shell("PMD Plugin: Violation Details");
145+
String message = dialog.bot().text(0).getText();
146+
dialog.bot().button("Close").click();
147+
148+
assertEquals("Unnecessary modifier 'public' on method 'run': the method is declared in an interface type", message);
149+
}
150+
151+
private void buildAndWaitForViolations() throws CoreException {
152+
testProject.build(IncrementalProjectBuilder.FULL_BUILD, new NullProgressMonitor());
153+
154+
bot.waitUntil(new DefaultCondition() {
155+
@Override
156+
public boolean test() throws Exception {
157+
IMarker[] markers = testProject.findMarkers(PMDRuntimeConstants.PMD_MARKER, true, IResource.DEPTH_INFINITE);
158+
return markers.length > 0;
159+
}
160+
161+
@Override
162+
public String getFailureMessage() {
163+
return "At least one marker is expected";
164+
}
165+
});
166+
}
167+
168+
private static void openPMDPerspective() throws InterruptedException {
169+
Display.getDefault().syncExec(new Runnable() {
170+
@Override
171+
public void run() {
172+
try {
173+
IWorkbench workbench = PlatformUI.getWorkbench();
174+
IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow();
175+
workbench.showPerspective(PMDRuntimeConstants.ID_PERSPECTIVE, activeWorkbenchWindow);
176+
} catch (WorkbenchException e) {
177+
e.printStackTrace();
178+
}
179+
}
180+
});
181+
}
182+
183+
private static void openJavaPerspective() throws InterruptedException {
184+
Display.getDefault().syncExec(new Runnable() {
185+
@Override
186+
public void run() {
187+
try {
188+
IWorkbench workbench = PlatformUI.getWorkbench();
189+
IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow();
190+
workbench.showPerspective(JavaUI.ID_PERSPECTIVE, activeWorkbenchWindow);
191+
IWorkbenchPage activePage = activeWorkbenchWindow.getActivePage();
192+
activePage.showView(ProjectExplorer.VIEW_ID);
193+
} catch (WorkbenchException e) {
194+
e.printStackTrace();
195+
}
196+
}
197+
});
198+
}
199+
}

net.sourceforge.pmd.eclipse.plugin/META-INF/MANIFEST.MF

Lines changed: 7 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ Bundle-ClassPath: .,
8989
target/lib/upickle-implicits_2.13.jar
9090
Bundle-Localization: plugin
9191
Export-Package: ch.qos.logback.classic;x-friends:="net.sourceforge.pmd.eclipse.plugin.test",
92-
name.herlin.command,
9392
net.sourceforge.pmd;
9493
uses:="net.sourceforge.pmd.lang,
9594
net.sourceforge.pmd.util.datasource,
@@ -99,7 +98,7 @@ Export-Package: ch.qos.logback.classic;x-friends:="net.sourceforge.pmd.eclipse.p
9998
net.sourceforge.pmd.cpd,
10099
net.sourceforge.pmd.cpd.renderer,
101100
net.sourceforge.pmd.eclipse.core;uses:="net.sourceforge.pmd",
102-
net.sourceforge.pmd.eclipse.core.impl,
101+
net.sourceforge.pmd.eclipse.core.impl;x-friends:="net.sourceforge.pmd.eclipse.plugin.test",
103102
net.sourceforge.pmd.eclipse.plugin;
104103
uses:="org.eclipse.core.runtime,
105104
net.sourceforge.pmd.eclipse.runtime.properties,
@@ -120,55 +119,17 @@ Export-Package: ch.qos.logback.classic;x-friends:="net.sourceforge.pmd.eclipse.p
120119
org.eclipse.swt.widgets,
121120
net.sourceforge.pmd.eclipse.util",
122121
net.sourceforge.pmd.eclipse.runtime;uses:="net.sourceforge.pmd.lang.rule.properties",
123-
net.sourceforge.pmd.eclipse.runtime.builder;uses:="org.eclipse.core.runtime,org.eclipse.core.resources,net.sourceforge.pmd.eclipse.ui.model",
122+
net.sourceforge.pmd.eclipse.runtime.builder,
124123
net.sourceforge.pmd.eclipse.runtime.cmd,
125124
net.sourceforge.pmd.eclipse.runtime.preferences,
126125
net.sourceforge.pmd.eclipse.runtime.properties;uses:="org.eclipse.ui,org.eclipse.core.resources,net.sourceforge.pmd",
127-
net.sourceforge.pmd.eclipse.runtime.properties.impl;x-internal:=true,
126+
net.sourceforge.pmd.eclipse.runtime.properties.impl;x-friends:="net.sourceforge.pmd.eclipse.plugin.test",
128127
net.sourceforge.pmd.eclipse.runtime.writer;uses:="net.sourceforge.pmd.lang.java.ast,net.sourceforge.pmd",
129-
net.sourceforge.pmd.eclipse.ui,
130-
net.sourceforge.pmd.eclipse.ui.actions;
131-
uses:="org.eclipse.jface.action,
132-
org.eclipse.jface.operation,
133-
org.eclipse.core.runtime,
134-
org.eclipse.ui,
135-
org.eclipse.core.resources,
136-
org.eclipse.jface.viewers,
137-
net.sourceforge.pmd,
138-
org.eclipse.core.commands",
128+
net.sourceforge.pmd.eclipse.ui;x-friends:="net.sourceforge.pmd.eclipse.plugin.test",
129+
net.sourceforge.pmd.eclipse.ui.actions;x-friends:="net.sourceforge.pmd.eclipse.plugin.test",
139130
net.sourceforge.pmd.eclipse.ui.actions.internal;x-friends:="net.sourceforge.pmd.eclipse.plugin.test",
140-
net.sourceforge.pmd.eclipse.ui.model;uses:="org.eclipse.jdt.core,org.eclipse.core.resources,net.sourceforge.pmd.lang.ast",
141-
net.sourceforge.pmd.eclipse.ui.preferences.br;
142-
uses:="net.sourceforge.pmd.eclipse.ui.preferences,
143-
net.sourceforge.pmd.eclipse.plugin,
144-
net.sourceforge.pmd.eclipse.ui.views,
145-
org.eclipse.ui,
146-
org.eclipse.swt.events,
147-
net.sourceforge.pmd,
148-
net.sourceforge.pmd.eclipse.runtime.preferences,
149-
net.sourceforge.pmd.lang.rule.properties,
150-
org.eclipse.jface.preference,
151-
net.sourceforge.pmd.lang,
152-
net.sourceforge.pmd.eclipse.ui,
153-
org.eclipse.jface.viewers,
154-
org.eclipse.swt.graphics,
155-
org.eclipse.ui.dialogs,
156-
org.eclipse.swt.widgets,
157-
net.sourceforge.pmd.eclipse.util",
158-
net.sourceforge.pmd.eclipse.ui.properties,
159-
net.sourceforge.pmd.eclipse.ui.views.actions;
160-
uses:="org.eclipse.ui.texteditor,
161-
org.eclipse.core.runtime,
162-
net.sourceforge.pmd.eclipse.ui.views,
163-
org.eclipse.ui.menus,
164-
net.sourceforge.pmd,
165-
net.sourceforge.pmd.eclipse.runtime.preferences,
166-
org.eclipse.jface.action,
167-
org.eclipse.core.resources,
168-
org.eclipse.ui.services,
169-
net.sourceforge.pmd.eclipse.ui.model,
170-
org.eclipse.jface.viewers,
171-
org.eclipse.swt.widgets",
131+
net.sourceforge.pmd.eclipse.ui.preferences.br;x-friends:="net.sourceforge.pmd.eclipse.plugin.test",
132+
net.sourceforge.pmd.eclipse.ui.properties;x-friends:="net.sourceforge.pmd.eclipse.plugin.test",
172133
net.sourceforge.pmd.eclipse.util.internal;x-friends:="net.sourceforge.pmd.eclipse.plugin.test",
173134
net.sourceforge.pmd.lang,
174135
net.sourceforge.pmd.lang.ast,

net.sourceforge.pmd.eclipse.plugin/messages.properties

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,6 @@ property.button.include_derived_files = Include derived files
1313
property.button.full_build_enabled = Full build enabled
1414
property.button.violations_as_errors = Handle high priority violations as Eclipse errors
1515

16-
# Marker Property Page
17-
markerPropertyPage.label.rulename = Rule:
18-
markerPropertyPage.label.category = Category:
19-
markerPropertyPage.label.priority = Priority:
20-
markerPropertyPage.label.message = Message:
21-
markerPropertyPage.label.description = Description:
22-
markerPropertyPage.label.externalInfoUrl = External Info URL:
23-
2416
# General preferences page
2517
preference.pmd.header = PMD-Plugin Options
2618
preference.pmd.title = PMD General Preferences
@@ -285,6 +277,17 @@ dialog.cpd.no_results.body = CPD has now finished with no matches.
285277

286278
dialog.preferences.add_new_property = Add new property
287279

280+
# Violation Details Dialog -> net.sourceforge.pmd.eclipse.ui.dialogs.ViolationDetailsDialogPage
281+
dialog.violation_details.title = PMD Plugin: Violation Details
282+
dialog.violation_details.location = Location:
283+
dialog.violation_details.examples = Examples:
284+
dialog.violation_details.rulename = Rule:
285+
dialog.violation_details.category = Category:
286+
dialog.violation_details.priority = Priority:
287+
dialog.violation_details.message = Message:
288+
dialog.violation_details.description = Description:
289+
dialog.violation_details.infourl = External Info URL:
290+
288291
# Monitor messages
289292
monitor.job_title = Checking Code with PMD
290293
monitor.begintask = PMD Processing...

net.sourceforge.pmd.eclipse.plugin/nl/fr/messages.properties

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,6 @@ property.button.include_derived_files = Inclure les fichiers d
1313
property.button.full_build_enabled = Full build enabled
1414
property.button.violations_as_errors = Traiter les violations de haute priorité comme des erreurs d'Eclipse
1515

16-
# Marker Property Page
17-
markerPropertyPage.label.rulename = Règle:
18-
markerPropertyPage.label.category = Catégorie:
19-
markerPropertyPage.label.priority = Priorité:
20-
markerPropertyPage.label.message = Message:
21-
markerPropertyPage.label.description = Description:
22-
markerPropertyPage.label.externalInfoUrl = URL d'information externe:
23-
2416
# General preferences page
2517
preference.pmd.header = Préférences Générales PMD
2618
preference.pmd.title = Préférences Générales PMD
@@ -285,6 +277,14 @@ dialog.cpd.no_results.body = CPD a fini son ex
285277

286278
dialog.preferences.add_new_property = Ajouter une propriété
287279

280+
# Violation Details Dialog -> net.sourceforge.pmd.eclipse.ui.dialogs.ViolationDetailsDialogPage
281+
dialog.violation_details.rulename = Règle:
282+
dialog.violation_details.category = Catégorie:
283+
dialog.violation_details.priority = Priorité:
284+
dialog.violation_details.message = Message:
285+
dialog.violation_details.description = Description:
286+
dialog.violation_details.infourl = URL d'information externe:
287+
288288
# Monitor messages
289289
monitor.job_title = Vérifier le code avec PMD
290290
monitor.begintask = PMD en cours...

net.sourceforge.pmd.eclipse.plugin/plugin.properties

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,6 @@ view.violation = PMD Violations
4343
view.outline = Violations Outline
4444
view.overview = Violations Overview
4545
view.dataflowview = Dataflow View
46-
view.cpd = CPD View
46+
view.cpd = CPD View
47+
48+
action.show_details = Show details...

0 commit comments

Comments
 (0)