Skip to content

Commit 8b840f0

Browse files
committed
Merge branch 'pr-123'
Support external configuration changes #123
2 parents bfbb34c + 48ae04d commit 8b840f0

File tree

29 files changed

+813
-287
lines changed

29 files changed

+813
-287
lines changed

ReleaseNotes.md

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

1616
### Fixed Issues
1717

18+
* [#123](https://github.com/pmd/pmd-eclipse-plugin/pull/123): Support external configuration changes
19+
1820
### API Changes
1921

2022
### External Contributions

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
22
Bundle-ManifestVersion: 2
33
Bundle-Version: 4.14.0.qualifier
44
Bundle-Name: PMD Test Plugin
5-
Bundle-SymbolicName: net.sourceforge.pmd.eclipse.plugin.test;singleton=true
5+
Bundle-SymbolicName: net.sourceforge.pmd.eclipse.plugin.test;singleton:=true
66
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
77
Bundle-Vendor: PMD Development Team
88
Require-Bundle: org.eclipse.ui,
@@ -17,3 +17,4 @@ Require-Bundle: org.eclipse.ui,
1717
Import-Package: ch.qos.logback.classic,
1818
org.slf4j
1919
Bundle-Activator: net.sourceforge.pmd.eclipse.internal.TestActivator
20+
Bundle-ActivationPolicy: lazy

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
<artifactId>tycho-surefire-plugin</artifactId>
2020
<configuration>
2121
<useUIHarness>true</useUIHarness>
22+
<showEclipseLog>true</showEclipseLog>
23+
<trimStackTrace>false</trimStackTrace>
2224
</configuration>
2325
</plugin>
2426
<plugin>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3+
*/
4+
5+
package net.sourceforge.pmd.eclipse.internal;
6+
7+
import java.io.File;
8+
import java.io.FileOutputStream;
9+
import java.io.IOException;
10+
import java.io.InputStream;
11+
12+
public class ResourceUtil {
13+
private ResourceUtil() {
14+
// utility
15+
}
16+
17+
public static void copyResource(Object context, String resource, File target) throws IOException {
18+
try (FileOutputStream out = new FileOutputStream(target);
19+
InputStream in = context.getClass().getResourceAsStream(resource)) {
20+
int count;
21+
byte[] buffer = new byte[8192];
22+
count = in.read(buffer);
23+
while (count > -1) {
24+
out.write(buffer, 0, count);
25+
count = in.read(buffer);
26+
}
27+
}
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3+
*/
4+
5+
package net.sourceforge.pmd.eclipse.runtime.preferences.impl;
6+
7+
import java.io.File;
8+
9+
import org.eclipse.core.runtime.IPath;
10+
import org.junit.After;
11+
import org.junit.Assert;
12+
import org.junit.Test;
13+
14+
import net.sourceforge.pmd.RuleSet;
15+
import net.sourceforge.pmd.eclipse.internal.ResourceUtil;
16+
import net.sourceforge.pmd.eclipse.plugin.PMDPlugin;
17+
import net.sourceforge.pmd.eclipse.runtime.preferences.IPreferencesManager;
18+
19+
20+
public class ChangeGlobalRuleSetExternallyTest {
21+
22+
@Test
23+
public void changeRuleSetExternally() throws Exception {
24+
IPreferencesManager preferencesManager = PMDPlugin.getDefault().getPreferencesManager();
25+
RuleSet ruleSet = preferencesManager.getRuleSet();
26+
int numberOfRules = ruleSet.size();
27+
Assert.assertTrue(numberOfRules > 1);
28+
29+
// Now change the ruleset on disk
30+
IPath ruleSetFile = PMDPlugin.getDefault().getStateLocation().append("/ruleset.xml");
31+
File ruleSetRealFile = ruleSetFile.toFile();
32+
ResourceUtil.copyResource(this, "test-ruleset.xml", ruleSetRealFile);
33+
34+
RuleSet ruleSet2 = preferencesManager.getRuleSet();
35+
Assert.assertEquals(1, ruleSet2.size());
36+
}
37+
38+
@After
39+
public void cleanup() {
40+
IPreferencesManager preferencesManager = PMDPlugin.getDefault().getPreferencesManager();
41+
preferencesManager.setRuleSet(preferencesManager.getDefaultRuleSet());
42+
}
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3+
*/
4+
5+
package net.sourceforge.pmd.eclipse.runtime.preferences.impl;
6+
7+
import java.io.File;
8+
9+
import org.eclipse.core.resources.IWorkspaceRoot;
10+
import org.eclipse.core.resources.ResourcesPlugin;
11+
import org.eclipse.core.runtime.IPath;
12+
import org.junit.Assert;
13+
import org.junit.Test;
14+
15+
import net.sourceforge.pmd.eclipse.internal.ResourceUtil;
16+
import net.sourceforge.pmd.eclipse.plugin.PMDPlugin;
17+
import net.sourceforge.pmd.eclipse.runtime.preferences.IPreferences;
18+
import net.sourceforge.pmd.eclipse.runtime.preferences.IPreferencesManager;
19+
20+
public class PreferencesChangedExternallyTest {
21+
22+
@Test
23+
public void changePreferenceExternally() throws Exception {
24+
IPreferencesManager preferencesManager = PMDPlugin.getDefault().getPreferencesManager();
25+
IPreferences preferences = preferencesManager.loadPreferences();
26+
try {
27+
Assert.assertTrue(preferences.isActive("AbstractClassWithoutAbstractMethod"));
28+
29+
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
30+
IPath prefsFile = workspaceRoot.getLocation().append(".metadata/.plugins/org.eclipse.core.runtime/.settings/net.sourceforge.pmd.eclipse.plugin.prefs");
31+
File prefsFileReal = prefsFile.toFile();
32+
ResourceUtil.copyResource(this, "pmd.prefs", prefsFileReal);
33+
34+
IPreferences preferences2 = preferencesManager.loadPreferences();
35+
Assert.assertFalse(preferences2.isActive("AbstractClassWithoutAbstractMethod"));
36+
Assert.assertTrue(preferences2.isActive("DoNotCallSystemExit"));
37+
Assert.assertNotSame(preferences, preferences2);
38+
} finally {
39+
preferencesManager.storePreferences(preferences);
40+
}
41+
}
42+
}

net.sourceforge.pmd.eclipse.plugin.test/src/main/java/net/sourceforge/pmd/eclipse/runtime/properties/ProjectPropertiesModelTest.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,6 @@ public class ProjectPropertiesModelTest {
4444
private IProject testProject;
4545
private RuleSet initialPluginRuleSet;
4646

47-
/**
48-
* @see junit.framework.TestCase#setUp()
49-
*/
5047
@Before
5148
public void setUp() throws Exception {
5249

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
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.io.File;
8+
import java.io.InputStream;
9+
10+
import org.eclipse.core.resources.IFile;
11+
import org.eclipse.core.resources.IProject;
12+
import org.eclipse.core.runtime.CoreException;
13+
import org.junit.After;
14+
import org.junit.Assert;
15+
import org.junit.Test;
16+
import org.slf4j.Logger;
17+
import org.slf4j.LoggerFactory;
18+
19+
import net.sourceforge.pmd.RuleSet;
20+
import net.sourceforge.pmd.RuleSets;
21+
import net.sourceforge.pmd.eclipse.EclipseUtils;
22+
import net.sourceforge.pmd.eclipse.internal.ResourceUtil;
23+
import net.sourceforge.pmd.eclipse.plugin.PMDPlugin;
24+
import net.sourceforge.pmd.eclipse.runtime.cmd.BuildProjectCommand;
25+
import net.sourceforge.pmd.eclipse.runtime.cmd.JobCommandProcessor;
26+
import net.sourceforge.pmd.eclipse.runtime.properties.IProjectProperties;
27+
import net.sourceforge.pmd.eclipse.runtime.properties.IProjectPropertiesManager;
28+
import net.sourceforge.pmd.eclipse.ui.actions.RuleSetUtil;
29+
30+
public class ExternalRuleSetFileTest {
31+
private static final Logger LOG = LoggerFactory.getLogger(ExternalRuleSetFileTest.class);
32+
33+
private static final String PMD_PROPERTIES_FILENAME = ".pmd";
34+
35+
private static final String PROJECT_RULESET_FILENAME = ".pmd-ruleset.xml";
36+
37+
private IProject testProject;
38+
39+
40+
private void setUpProject(String projectName) {
41+
try {
42+
this.testProject = EclipseUtils.createJavaProject(projectName);
43+
Assert.assertTrue("A test project cannot be created; the tests cannot be performed.",
44+
this.testProject != null && this.testProject.exists() && this.testProject.isAccessible());
45+
} catch (CoreException e) {
46+
throw new RuntimeException(e);
47+
}
48+
}
49+
50+
@After
51+
public void tearDown() throws Exception {
52+
try {
53+
if (this.testProject != null) {
54+
if (this.testProject.exists() && this.testProject.isAccessible()) {
55+
this.testProject.delete(true, true, null);
56+
this.testProject = null;
57+
}
58+
}
59+
} catch (CoreException e) {
60+
throw new RuntimeException(e);
61+
}
62+
}
63+
64+
@Test
65+
public void changedExternalRulesetShouldBeReloaded() throws Exception {
66+
setUpProject("ExternalRulesetTest");
67+
InputStream ruleset1 = ExternalRuleSetFileTest.class.getResourceAsStream("ruleset1.xml");
68+
69+
// create the ruleset file in the project
70+
IFile ruleSetFile = this.testProject.getFile(PROJECT_RULESET_FILENAME);
71+
if (ruleSetFile.exists()) {
72+
Assert.fail("File " + PROJECT_RULESET_FILENAME + " already exists!");
73+
}
74+
try {
75+
ruleSetFile.create(ruleset1, true, null);
76+
} finally {
77+
ruleset1.close();
78+
}
79+
80+
// configure the project to use this
81+
final UpdateProjectPropertiesCmd cmd = new UpdateProjectPropertiesCmd();
82+
cmd.setPmdEnabled(true);
83+
cmd.setProject(this.testProject);
84+
cmd.setProjectWorkingSet(null);
85+
cmd.setProjectRuleSets(new RuleSets(RuleSetUtil.newEmpty("empty", "empty")));
86+
cmd.setRuleSetStoredInProject(true);
87+
cmd.setRuleSetFile(PROJECT_RULESET_FILENAME);
88+
cmd.execute();
89+
90+
// load the project settings - it should have this ruleset now active (1 rule)
91+
final IProjectPropertiesManager mgr = PMDPlugin.getDefault().getPropertiesManager();
92+
final IProjectProperties model = mgr.loadProjectProperties(this.testProject);
93+
RuleSet projectRuleSet = model.getProjectRuleSet();
94+
Assert.assertEquals(1, projectRuleSet.getRules().size());
95+
96+
// now let's change the ruleSetFile without eclipse knowing about it ("externally")
97+
File ruleSetFileReal = ruleSetFile.getLocation().toFile();
98+
ResourceUtil.copyResource(this, "ruleset2.xml", ruleSetFileReal);
99+
100+
// the file has changed, this should be detected
101+
Assert.assertTrue(model.isNeedRebuild());
102+
// the model is not updated yet...
103+
Assert.assertEquals(1, model.getProjectRuleSet().getRules().size());
104+
// but it will be when requesting the project properties again
105+
final IProjectProperties model2 = mgr.loadProjectProperties(testProject);
106+
Assert.assertEquals(2, model2.getProjectRuleSet().getRules().size());
107+
// the model is still cached, but the rules are updated
108+
Assert.assertSame(model, model2);
109+
}
110+
111+
@Test
112+
public void changedExternalRulesetShouldBeReloadedForPmdDisabledProjects() throws Exception {
113+
setUpProject("ExternalRulesetTestPmdDisabled");
114+
115+
// load the project properties - pmd is not enabled, it uses the default ruleset (more than 1 active rule)
116+
final IProjectPropertiesManager mgr = PMDPlugin.getDefault().getPropertiesManager();
117+
final IProjectProperties model = mgr.loadProjectProperties(this.testProject);
118+
RuleSet projectRuleSet = model.getProjectRuleSet();
119+
Assert.assertNotEquals(1, projectRuleSet.getRules().size());
120+
121+
// now let's change the ruleSetFile without eclipse knowing about it ("externally")
122+
IFile ruleSetFile = this.testProject.getFile(PROJECT_RULESET_FILENAME);
123+
if (ruleSetFile.exists()) {
124+
Assert.fail("File " + PROJECT_RULESET_FILENAME + " already exists!");
125+
}
126+
File ruleSetFileReal = ruleSetFile.getLocation().toFile();
127+
ResourceUtil.copyResource(this, "ruleset1.xml", ruleSetFileReal);
128+
129+
// now create the .pmd project properties without eclipse knowing about it ("externally")
130+
IFile projectPropertiesFile = this.testProject.getFile(PMD_PROPERTIES_FILENAME);
131+
if (projectPropertiesFile.exists()) {
132+
Assert.fail("File .pmd does already exist!");
133+
}
134+
File projectPropertiesFileReal = projectPropertiesFile.getLocation().toFile();
135+
ResourceUtil.copyResource(this, "pmd-properties", projectPropertiesFileReal);
136+
137+
// the files have been created, but the .pmd file is not reloaded yet, so:
138+
Assert.assertFalse(model.isNeedRebuild());
139+
// the model is not updated yet...
140+
Assert.assertNotEquals(1, model.getProjectRuleSet().getRules().size());
141+
// but it will be when requesting the project properties again
142+
final IProjectProperties model2 = mgr.loadProjectProperties(testProject);
143+
// PMD is still not enabled
144+
Assert.assertFalse(model.isPmdEnabled());
145+
// but rebuild is needed (because ruleset changed)
146+
Assert.assertTrue(model.isNeedRebuild());
147+
// and the ruleset is loaded
148+
Assert.assertEquals(1, model2.getProjectRuleSet().getRules().size());
149+
// the model is still cached, but the rules are updated
150+
Assert.assertSame(model, model2);
151+
}
152+
153+
@Test
154+
public void externallyChangedProjectPropertiesShouldBeReloaded() throws Exception {
155+
setUpProject("ProjectPropertiesChanged");
156+
// configure the project to use PMD
157+
final UpdateProjectPropertiesCmd cmd = new UpdateProjectPropertiesCmd();
158+
cmd.setPmdEnabled(true);
159+
cmd.setProject(this.testProject);
160+
cmd.setProjectWorkingSet(null);
161+
RuleSets rulesets = new RuleSets(PMDPlugin.getDefault().getPreferencesManager().getRuleSet());
162+
cmd.setProjectRuleSets(rulesets);
163+
cmd.setRuleSetStoredInProject(false);
164+
cmd.execute();
165+
166+
if (cmd.isNeedRebuild()) {
167+
final BuildProjectCommand rebuildCmd = new BuildProjectCommand();
168+
rebuildCmd.setProject(this.testProject);
169+
rebuildCmd.setUserInitiated(true);
170+
rebuildCmd.execute();
171+
JobCommandProcessor.getInstance().waitCommandToFinish(null);
172+
}
173+
174+
175+
// load the project settings - it should have this ruleset now active (many rules)
176+
final IProjectPropertiesManager mgr = PMDPlugin.getDefault().getPropertiesManager();
177+
final IProjectProperties model = mgr.loadProjectProperties(this.testProject);
178+
RuleSet projectRuleSet = model.getProjectRuleSet();
179+
int numberOfRules = rulesets.getAllRules().size();
180+
Assert.assertEquals(numberOfRules, projectRuleSet.getRules().size());
181+
// after the rebuild above, the project should be in a consistent state
182+
Assert.assertFalse(model.isNeedRebuild());
183+
184+
// now create a .pmd-ruleset.xml file without eclipse knowing about it ("externally")
185+
IFile ruleSetFile = this.testProject.getFile(PROJECT_RULESET_FILENAME);
186+
if (ruleSetFile.exists()) {
187+
Assert.fail("File " + PROJECT_RULESET_FILENAME + " already exists!");
188+
}
189+
File ruleSetFileReal = ruleSetFile.getLocation().toFile();
190+
ResourceUtil.copyResource(this, "ruleset1.xml", ruleSetFileReal);
191+
192+
// now overwrite and change the .pmd project properties without eclipse knowing about it ("externally")
193+
IFile projectPropertiesFile = this.testProject.getFile(PMD_PROPERTIES_FILENAME);
194+
if (!projectPropertiesFile.exists()) {
195+
Assert.fail("File .pmd does not exist!");
196+
}
197+
File projectPropertiesFileReal = projectPropertiesFile.getLocation().toFile();
198+
ResourceUtil.copyResource(this, "pmd-properties", projectPropertiesFileReal);
199+
LOG.debug("Overwritten {}", projectPropertiesFile);
200+
201+
// the model is not updated yet...
202+
Assert.assertEquals(numberOfRules, model.getProjectRuleSet().getRules().size());
203+
// but it will be when requesting the project properties again
204+
final IProjectProperties model2 = mgr.loadProjectProperties(testProject);
205+
// the file and the ruleset have changed, this should be detected
206+
Assert.assertTrue(model2.isNeedRebuild());
207+
// the new rule set should be active now
208+
Assert.assertEquals(1, model2.getProjectRuleSet().getRules().size());
209+
// the model is still cached, but the rules are updated
210+
Assert.assertSame(model, model2);
211+
212+
// rebuild again
213+
final BuildProjectCommand rebuildCmd = new BuildProjectCommand();
214+
rebuildCmd.setProject(this.testProject);
215+
rebuildCmd.setUserInitiated(true);
216+
rebuildCmd.execute();
217+
JobCommandProcessor.getInstance().waitCommandToFinish(null);
218+
// need rebuild flag should be reset now
219+
Assert.assertFalse(model.isNeedRebuild());
220+
}
221+
}

net.sourceforge.pmd.eclipse.plugin.test/src/main/java/net/sourceforge/pmd/eclipse/ui/properties/UpdateProjectPropertiesCmdTest.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
import net.sourceforge.pmd.Rule;
1414
import net.sourceforge.pmd.RuleSet;
15-
import net.sourceforge.pmd.RuleSetFactory;
1615
import net.sourceforge.pmd.eclipse.EclipseUtils;
1716
import net.sourceforge.pmd.eclipse.plugin.PMDPlugin;
1817
import net.sourceforge.pmd.eclipse.runtime.properties.IProjectProperties;
@@ -51,8 +50,6 @@ public void tearDown() throws Exception {
5150
*/
5251
@Test
5352
public void testBug() throws PropertiesException {
54-
final RuleSetFactory factory = new RuleSetFactory();
55-
5653
// First ensure that the plugin initial ruleset is equal to the project
5754
// ruleset
5855
final IProjectPropertiesManager mgr = PMDPlugin.getDefault().getPropertiesManager();

0 commit comments

Comments
 (0)