소스 검색

SONAR-1766 : The PMD plugin uses the new Sonar rule API

tags/2.6
fmallet 13 년 전
부모
커밋
5ac2f4fb7d
26개의 변경된 파일701개의 추가작업 그리고 693개의 파일을 삭제
  1. 1
    1
      plugins/sonar-pmd-plugin/pmd-result.xml
  2. 14
    11
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdConfiguration.java
  3. 67
    0
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdLevelUtils.java
  4. 11
    1
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdPlugin.java
  5. 6
    26
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdProfileExporter.java
  6. 90
    0
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdProfileImporter.java
  7. 0
    168
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdRulesRepository.java
  8. 46
    0
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/SonarWayProfile.java
  9. 44
    0
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/SonarWayWithFindbugsProfile.java
  10. 47
    0
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/SunConventionsProfile.java
  11. 2
    2
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/xml/PmdProperty.java
  12. 5
    5
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/xml/PmdRule.java
  13. 1
    1
      plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/xml/PmdRuleset.java
  14. 11
    17
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdConfigurationTest.java
  15. 159
    0
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdProfileImporterTest.java
  16. 0
    396
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdRulesRepositoryTest.java
  17. 66
    0
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SonarWayProfileTest.java
  18. 65
    0
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SonarWayWithFindbugsProfileTest.java
  19. 65
    0
      plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SunConventionsProfileTest.java
  20. 0
    15
      plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/PmdRulesRepositoryTest/shouldImportPmdLevelsAsSonarLevels.xml
  21. 0
    7
      plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/PmdRulesRepositoryTest/shouldImportWithDefaultRuleLevelWhenNoExplicitPriority.xml
  22. 0
    0
      plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/complex-with-unknown-nodes.xml
  23. 1
    1
      plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/simple.xml
  24. 0
    3
      plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/test_header.xml
  25. 0
    11
      plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/test_xml_utf8.xml
  26. 0
    28
      plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/test_xml_with_class_param.xml

+ 1
- 1
plugins/sonar-pmd-plugin/pmd-result.xml 파일 보기

@@ -1,3 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<pmd version="4.2.5" timestamp="2010-09-14T13:20:30.108">
<pmd version="4.2.5" timestamp="2010-09-15T13:59:35.931">
</pmd>

+ 14
- 11
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdConfiguration.java 파일 보기

@@ -19,6 +19,12 @@
*/
package org.sonar.plugins.pmd;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.List;

import org.sonar.api.BatchExtension;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.maven.MavenPlugin;
@@ -26,19 +32,14 @@ import org.sonar.api.batch.maven.MavenUtils;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Project;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

public class PmdConfiguration implements BatchExtension {

private PmdRulesRepository pmdRulesRepository;
private PmdProfileExporter pmdProfileExporter;
private RulesProfile rulesProfile;
private Project project;

public PmdConfiguration(PmdRulesRepository pmdRulesRepository, RulesProfile rulesProfile, Project project) {
this.pmdRulesRepository = pmdRulesRepository;
public PmdConfiguration(PmdProfileExporter pmdRulesRepository, RulesProfile rulesProfile, Project project) {
this.pmdProfileExporter = pmdRulesRepository;
this.rulesProfile = rulesProfile;
this.project = project;
}
@@ -60,15 +61,17 @@ public class PmdConfiguration implements BatchExtension {
}
}
if (rulesets == null || rulesets.isEmpty()) {
throw new RuntimeException("The PMD configuration to reuse can not be found. Check the property " + CoreProperties.REUSE_RULES_CONFIGURATION_PROPERTY + " or add the property rulesets/ruleset to the Maven PMD plugin");
throw new RuntimeException("The PMD configuration to reuse can not be found. Check the property "
+ CoreProperties.REUSE_RULES_CONFIGURATION_PROPERTY + " or add the property rulesets/ruleset to the Maven PMD plugin");
}
return rulesets;
}

private File saveXmlFile() {
try {
String xml = pmdRulesRepository.exportConfiguration(rulesProfile);
return project.getFileSystem().writeToWorkingDirectory(xml, "pmd.xml");
StringWriter pmdConfiguration = new StringWriter();
pmdProfileExporter.exportProfile(rulesProfile, pmdConfiguration);
return project.getFileSystem().writeToWorkingDirectory(pmdConfiguration.toString(), "pmd.xml");

} catch (IOException e) {
throw new RuntimeException("Fail to save the PMD configuration", e);

+ 67
- 0
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdLevelUtils.java 파일 보기

@@ -0,0 +1,67 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2009 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* Sonar is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* Sonar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.pmd;

import org.sonar.api.rules.RulePriority;

public final class PmdLevelUtils {

private PmdLevelUtils() {
// only static methods
}

public static RulePriority fromLevel(String level) {
if ("1".equals(level)) {
return RulePriority.BLOCKER;
}
if ("2".equals(level)) {
return RulePriority.CRITICAL;
}
if ("3".equals(level)) {
return RulePriority.MAJOR;
}
if ("4".equals(level)) {
return RulePriority.MINOR;
}
if ("5".equals(level)) {
return RulePriority.INFO;
}
return null;
}

public static String toLevel(RulePriority priority) {
if (priority.equals(RulePriority.BLOCKER)) {
return "1";
}
if (priority.equals(RulePriority.CRITICAL)) {
return "2";
}
if (priority.equals(RulePriority.MAJOR)) {
return "3";
}
if (priority.equals(RulePriority.MINOR)) {
return "4";
}
if (priority.equals(RulePriority.INFO)) {
return "5";
}
throw new IllegalArgumentException("Level not supported: " + priority);
}
}

+ 11
- 1
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdPlugin.java 파일 보기

@@ -39,6 +39,16 @@ public class PmdPlugin implements Plugin {
}

public List getExtensions() {
return Arrays.asList(PmdSensor.class, PmdConfiguration.class, PmdExecutor.class, PmdRulesRepository.class);
return Arrays.asList(
PmdSensor.class,
PmdConfiguration.class,
PmdExecutor.class,
PmdRuleRepository.class,
PmdProfileExporter.class,
PmdProfileImporter.class,
SonarWayProfile.class,
SonarWayWithFindbugsProfile.class,
SunConventionsProfile.class
);
}
}

+ 6
- 26
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdProfileExporter.java 파일 보기

@@ -32,7 +32,7 @@ import org.sonar.api.rules.ActiveRule;
import org.sonar.api.rules.ActiveRuleParam;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.utils.SonarException;
import org.sonar.plugins.pmd.xml.Property;
import org.sonar.plugins.pmd.xml.PmdProperty;
import org.sonar.plugins.pmd.xml.PmdRule;
import org.sonar.plugins.pmd.xml.PmdRuleset;

@@ -62,12 +62,12 @@ public class PmdProfileExporter extends ProfileExporter {
for (ActiveRule activeRule : activeRules) {
if (activeRule.getRule().getPluginName().equals(CoreProperties.PMD_PLUGIN)) {
String configKey = activeRule.getRule().getConfigKey();
PmdRule rule = new PmdRule(configKey, to(activeRule.getPriority()));
List<Property> properties = null;
PmdRule rule = new PmdRule(configKey, PmdLevelUtils.toLevel(activeRule.getPriority()));
List<PmdProperty> properties = null;
if (activeRule.getActiveRuleParams() != null && !activeRule.getActiveRuleParams().isEmpty()) {
properties = new ArrayList<Property>();
properties = new ArrayList<PmdProperty>();
for (ActiveRuleParam activeRuleParam : activeRule.getActiveRuleParams()) {
properties.add(new Property(activeRuleParam.getRuleParam().getKey(), activeRuleParam.getValue()));
properties.add(new PmdProperty(activeRuleParam.getRuleParam().getKey(), activeRuleParam.getValue()));
}
}
rule.setProperties(properties);
@@ -82,27 +82,7 @@ public class PmdProfileExporter extends ProfileExporter {
xstream.setClassLoader(getClass().getClassLoader());
xstream.processAnnotations(PmdRuleset.class);
xstream.processAnnotations(PmdRule.class);
xstream.processAnnotations(Property.class);
xstream.processAnnotations(PmdProperty.class);
return xstream.toXML(tree);
}

private String to(RulePriority priority) {
if (priority.equals(RulePriority.BLOCKER)) {
return "1";
}
if (priority.equals(RulePriority.CRITICAL)) {
return "2";
}
if (priority.equals(RulePriority.MAJOR)) {
return "3";
}
if (priority.equals(RulePriority.MINOR)) {
return "4";
}
if (priority.equals(RulePriority.INFO)) {
return "5";
}
throw new IllegalArgumentException("Level not supported: " + priority);
}

}

+ 90
- 0
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdProfileImporter.java 파일 보기

@@ -0,0 +1,90 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2009 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* Sonar is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* Sonar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.pmd;

import java.io.Reader;

import org.sonar.api.profiles.ProfileImporter;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Java;
import org.sonar.api.rules.ActiveRule;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
import org.sonar.api.rules.RuleQuery;
import org.sonar.api.utils.ValidationMessages;
import org.sonar.plugins.pmd.xml.PmdProperty;
import org.sonar.plugins.pmd.xml.PmdRule;
import org.sonar.plugins.pmd.xml.PmdRuleset;

import com.thoughtworks.xstream.XStream;

public class PmdProfileImporter extends ProfileImporter {

private final RuleFinder ruleFinder;

public PmdProfileImporter(RuleFinder ruleFinder) {
super(PmdConstants.REPOSITORY_KEY, PmdConstants.PLUGIN_NAME);
setSupportedLanguages(Java.KEY);
this.ruleFinder = ruleFinder;
}

@Override
public RulesProfile importProfile(Reader pmdConfigurationFile, ValidationMessages messages) {
PmdRuleset pmdRuleset = parsePmdRuleset(pmdConfigurationFile, messages);
RulesProfile profile = createRuleProfile(pmdRuleset, messages);
return profile;
}

protected RulesProfile createRuleProfile(PmdRuleset pmdRuleset, ValidationMessages messages) {
RulesProfile profile = RulesProfile.create();
for (PmdRule pmdRule : pmdRuleset.getPmdRules()) {
Rule rule = ruleFinder.find(RuleQuery.create().withRepositoryKey(PmdConstants.REPOSITORY_KEY).withConfigKey(pmdRule.getRef()));
if (rule != null) {
ActiveRule activeRule = profile.activateRule(rule, PmdLevelUtils.fromLevel(pmdRule.getPriority()));
if (pmdRule.getProperties() != null) {
for (PmdProperty prop : pmdRule.getProperties()) {
if (rule.getParam(prop.getName()) == null) {
messages.addWarningText("The property '" + prop.getName() + "' is not supported in the pmd rule: " + pmdRule.getRef());
continue;
}
activeRule.setParameter(prop.getName(), prop.getValue());
}
}
} else {
messages.addWarningText("Unable to import unknown PMD rule '" + pmdRule.getRef() + "'");
}
}
return profile;
}

protected PmdRuleset parsePmdRuleset(Reader pmdConfigurationFile, ValidationMessages messages) {
try {
XStream xstream = new XStream();
xstream.setClassLoader(getClass().getClassLoader());
xstream.processAnnotations(PmdRuleset.class);
xstream.processAnnotations(PmdRule.class);
xstream.processAnnotations(PmdProperty.class);
return (PmdRuleset) xstream.fromXML(pmdConfigurationFile);
} catch (RuntimeException e) {
messages.addErrorText("The PMD configuration file is not valide: " + e.getMessage());
return new PmdRuleset();
}
}
}

+ 0
- 168
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdRulesRepository.java 파일 보기

@@ -1,168 +0,0 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2009 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* Sonar is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* Sonar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.pmd;
import com.thoughtworks.xstream.XStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.CharEncoding;
import org.sonar.api.CoreProperties;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Java;
import org.sonar.api.rules.*;
import org.sonar.api.utils.SonarException;
import org.sonar.plugins.pmd.xml.Property;
import org.sonar.plugins.pmd.xml.PmdRule;
import org.sonar.plugins.pmd.xml.PmdRuleset;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class PmdRulesRepository extends AbstractImportableRulesRepository<Java, PmdRulePriorityMapper> implements ConfigurationExportable {
public PmdRulesRepository(Java language) {
super(language, new PmdRulePriorityMapper());
}
@Override
public String getRepositoryResourcesBase() {
return "org/sonar/plugins/pmd";
}
@Override
public Map<String, String> getBuiltInProfiles() {
Map<String, String> defaults = new HashMap<String, String>();
defaults.put(RulesProfile.SONAR_WAY_NAME, "profile-sonar-way.xml");
defaults.put(RulesProfile.SONAR_WAY_FINDBUGS_NAME, "profile-sonar-way.xml");
defaults.put(RulesProfile.SUN_CONVENTIONS_NAME, "profile-sun-conventions.xml");
return defaults;
}
public String exportConfiguration(RulesProfile activeProfile) {
PmdRuleset tree = buildModuleTree(activeProfile.getActiveRulesByPlugin(CoreProperties.PMD_PLUGIN), activeProfile.getName());
String xmlModules = buildXmlFromModuleTree(tree);
return addHeaderToXml(xmlModules);
}
public List<ActiveRule> importConfiguration(String configuration, List<org.sonar.api.rules.Rule> rules) {
List<ActiveRule> activeRules = new ArrayList<ActiveRule>();
PmdRuleset moduleTree = buildModuleTreeFromXml(configuration);
buildActiveRulesFromModuleTree(moduleTree, activeRules, rules);
return activeRules;
}
protected PmdRuleset buildModuleTree(List<ActiveRule> activeRules) {
return buildModuleTree(activeRules, "Sonar PMD rules");
}
protected PmdRuleset buildModuleTree(List<ActiveRule> activeRules, String profileName) {
PmdRuleset ruleset = new PmdRuleset(profileName);
for (ActiveRule activeRule : activeRules) {
if (activeRule.getRule().getPluginName().equals(CoreProperties.PMD_PLUGIN)) {
String configKey = activeRule.getRule().getConfigKey();
PmdRule rule = new PmdRule(configKey, getRulePriorityMapper().to(activeRule.getPriority()));
List<Property> properties = null;
if (activeRule.getActiveRuleParams() != null && !activeRule.getActiveRuleParams().isEmpty()) {
properties = new ArrayList<Property>();
for (ActiveRuleParam activeRuleParam : activeRule.getActiveRuleParams()) {
properties.add(new Property(activeRuleParam.getRuleParam().getKey(), activeRuleParam.getValue()));
}
}
rule.setProperties(properties);
ruleset.addRule(rule);
}
}
return ruleset;
}
protected String buildXmlFromModuleTree(PmdRuleset tree) {
XStream xstream = new XStream();
xstream.setClassLoader(getClass().getClassLoader());
xstream.processAnnotations(PmdRuleset.class);
xstream.processAnnotations(PmdRule.class);
xstream.processAnnotations(Property.class);
return xstream.toXML(tree);
}
protected String addHeaderToXml(String xmlModules) {
String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
header += ("<!-- generated by Sonar -->\n");
return header + xmlModules;
}
protected PmdRuleset buildModuleTreeFromXml(String configuration) {
InputStream inputStream = null;
try {
XStream xstream = new XStream();
xstream.setClassLoader(getClass().getClassLoader());
xstream.processAnnotations(PmdRuleset.class);
xstream.processAnnotations(org.sonar.api.rules.Rule.class);
xstream.processAnnotations(Property.class);
inputStream = IOUtils.toInputStream(configuration, CharEncoding.UTF_8);
return (PmdRuleset) xstream.fromXML(inputStream);
}
catch (IOException e) {
throw new SonarException("can't read configuration file", e);
}
finally {
IOUtils.closeQuietly(inputStream);
}
}
protected void buildActiveRulesFromModuleTree(PmdRuleset ruleset, List<ActiveRule> activeRules, List<org.sonar.api.rules.Rule> rules) {
if (ruleset.getRules() != null && !ruleset.getRules().isEmpty()) {
for (PmdRule rule : ruleset.getRules()) {
String ref = rule.getRef();
for (org.sonar.api.rules.Rule dbRule : rules) {
if (dbRule.getConfigKey().equals(ref)) {
RulePriority rulePriority = getRulePriorityMapper().from(rule.getPriority());
ActiveRule activeRule = new ActiveRule(null, dbRule, rulePriority);
activeRule.setActiveRuleParams(getActiveRuleParams(rule, dbRule, activeRule));
activeRules.add(activeRule);
break;
}
}
}
}
}
private List<ActiveRuleParam> getActiveRuleParams(PmdRule rule, org.sonar.api.rules.Rule dbRule, ActiveRule activeRule) {
List<ActiveRuleParam> activeRuleParams = new ArrayList<ActiveRuleParam>();
if (rule.getProperties() != null) {
for (Property property : rule.getProperties()) {
if (dbRule.getParams() != null) {
for (RuleParam ruleParam : dbRule.getParams()) {
if (ruleParam.getKey().equals(property.getName())) {
activeRuleParams.add(new ActiveRuleParam(activeRule, ruleParam, property.getValue()));
}
}
}
}
}
return activeRuleParams;
}
}

+ 46
- 0
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/SonarWayProfile.java 파일 보기

@@ -0,0 +1,46 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2009 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* Sonar is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* Sonar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.pmd;

import java.io.InputStreamReader;
import java.io.Reader;

import org.sonar.api.profiles.ProfileDefinition;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Java;
import org.sonar.api.utils.ValidationMessages;

public final class SonarWayProfile extends ProfileDefinition {

private final PmdProfileImporter importer;

public SonarWayProfile(PmdProfileImporter importer) {
this.importer = importer;
}

@Override
public RulesProfile createProfile(ValidationMessages messages) {
Reader pmdSonarWayProfile = new InputStreamReader(this.getClass().getResourceAsStream("/org/sonar/plugins/pmd/profile-sonar-way.xml"));
RulesProfile profile = importer.importProfile(pmdSonarWayProfile, messages);
profile.setLanguage(Java.KEY);
profile.setName(RulesProfile.SONAR_WAY_NAME);
return profile;
}
}

+ 44
- 0
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/SonarWayWithFindbugsProfile.java 파일 보기

@@ -0,0 +1,44 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2009 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* Sonar is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* Sonar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.pmd;

import org.sonar.api.profiles.ProfileDefinition;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Java;
import org.sonar.api.utils.ValidationMessages;

public class SonarWayWithFindbugsProfile extends ProfileDefinition {

private SonarWayProfile sonarWay;

public SonarWayWithFindbugsProfile(SonarWayProfile sonarWay) {
this.sonarWay = sonarWay;
}


@Override
public RulesProfile createProfile(ValidationMessages validationMessages) {
RulesProfile profile = sonarWay.createProfile(validationMessages);
profile.setName(RulesProfile.SONAR_WAY_FINDBUGS_NAME);
profile.setLanguage(Java.KEY);
return profile;
}
}


+ 47
- 0
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/SunConventionsProfile.java 파일 보기

@@ -0,0 +1,47 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2009 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* Sonar is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* Sonar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.pmd;

import java.io.InputStreamReader;
import java.io.Reader;

import org.sonar.api.profiles.ProfileDefinition;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Java;
import org.sonar.api.utils.ValidationMessages;

public final class SunConventionsProfile extends ProfileDefinition {

private final PmdProfileImporter importer;

public SunConventionsProfile(PmdProfileImporter importer) {
this.importer = importer;
}

@Override
public RulesProfile createProfile(ValidationMessages messages) {
Reader pmdSonarWayProfile = new InputStreamReader(this.getClass().getResourceAsStream(
"/org/sonar/plugins/pmd/profile-sun-conventions.xml"));
RulesProfile profile = importer.importProfile(pmdSonarWayProfile, messages);
profile.setName(RulesProfile.SUN_CONVENTIONS_NAME);
profile.setLanguage(Java.KEY);
return profile;
}
}

plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/xml/Property.java → plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/xml/PmdProperty.java 파일 보기

@@ -23,7 +23,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
@XStreamAlias("property")
public class Property {
public class PmdProperty {
@XStreamAsAttribute
private String name;
@@ -31,7 +31,7 @@ public class Property {
@XStreamAsAttribute
private String value;
public Property(String name, String value) {
public PmdProperty(String name, String value) {
this.name = name;
this.value = value;
}

+ 5
- 5
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/xml/PmdRule.java 파일 보기

@@ -34,7 +34,7 @@ public class PmdRule implements Comparable<String> {
private String priority;
private List<Property> properties;
private List<PmdProperty> properties = new ArrayList<PmdProperty>();
@XStreamOmitField
private String description; //NOSONAR unused private field
@@ -62,11 +62,11 @@ public class PmdRule implements Comparable<String> {
return ref;
}
public void setProperties(List<Property> properties) {
public void setProperties(List<PmdProperty> properties) {
this.properties = properties;
}
public List<Property> getProperties() {
public List<PmdProperty> getProperties() {
return properties;
}
@@ -82,9 +82,9 @@ public class PmdRule implements Comparable<String> {
this.priority = priority;
}
public void addProperty(Property property) {
public void addProperty(PmdProperty property) {
if (properties == null) {
properties = new ArrayList<Property>();
properties = new ArrayList<PmdProperty>();
}
properties.add(property);
}

+ 1
- 1
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/xml/PmdRuleset.java 파일 보기

@@ -49,7 +49,7 @@ public class PmdRuleset {
this.description = description;
}

public List<PmdRule> getRules() {
public List<PmdRule> getPmdRules() {
return rules;
}


+ 11
- 17
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdConfigurationTest.java 파일 보기

@@ -19,22 +19,19 @@
*/
package org.sonar.plugins.pmd;

import org.apache.commons.io.FileUtils;
import org.junit.Test;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Project;
import org.sonar.api.test.MavenTestUtils;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.internal.matchers.IsCollectionContaining.hasItem;

import java.io.File;
import java.io.IOException;
import java.util.List;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.internal.matchers.IsCollectionContaining.hasItem;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Project;
import org.sonar.api.test.MavenTestUtils;

public class PmdConfigurationTest {

@@ -42,16 +39,13 @@ public class PmdConfigurationTest {
public void writeConfigurationToWorkingDir() throws IOException {
Project project = MavenTestUtils.loadProjectFromPom(getClass(), "writeConfigurationToWorkingDir/pom.xml");

PmdRulesRepository repository = mock(PmdRulesRepository.class);
when(repository.exportConfiguration((RulesProfile)anyObject())).thenReturn("<conf/>");

PmdConfiguration configuration = new PmdConfiguration(repository, null, project);
PmdConfiguration configuration = new PmdConfiguration(new PmdProfileExporter(), RulesProfile.create(), project);
List<String> rulesets = configuration.getRulesets();

assertThat(rulesets.size(), is(1));
File xmlFile = new File(rulesets.get(0));
assertThat(xmlFile.exists(), is(true));
assertThat(FileUtils.readFileToString(xmlFile), is("<conf/>"));
assertThat(FileUtils.readFileToString(xmlFile), is("<ruleset/>"));
}

@Test
@@ -65,7 +59,7 @@ public class PmdConfigurationTest {
assertThat(rulesets, hasItem("ruleset/basic.xml"));
}

@Test(expected=RuntimeException.class)
@Test(expected = RuntimeException.class)
public void failIfConfigurationToReuseDoesNotExist() throws IOException {
Project project = MavenTestUtils.loadProjectFromPom(getClass(), "failIfConfigurationToReuseDoesNotExist/pom.xml");


+ 159
- 0
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdProfileImporterTest.java 파일 보기

@@ -0,0 +1,159 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2009 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* Sonar is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* Sonar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.pmd;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.io.Reader;
import java.io.StringReader;

import org.junit.Before;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.rules.ActiveRule;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.rules.RuleQuery;
import org.sonar.api.utils.ValidationMessages;
import org.sonar.plugins.pmd.xml.PmdRuleset;
import org.sonar.test.TestUtils;

public class PmdProfileImporterTest {

private PmdProfileImporter importer;
private ValidationMessages messages;

@Before
public void before() {
messages = ValidationMessages.create();
RuleFinder finder = createRuleFinder();
importer = new PmdProfileImporter(finder);
}

@Test
public void testBuildPmdRuleset() {
Reader reader = new StringReader(TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
PmdRuleset pmdRuleset = importer.parsePmdRuleset(reader, messages);
assertThat(pmdRuleset.getPmdRules().size(), is(3));
}

@Test
public void testImportingSimpleProfile() {
Reader reader = new StringReader(TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
RulesProfile profile = importer.importProfile(reader, messages);

assertThat(profile.getActiveRules().size(), is(3));
assertNotNull(profile.getActiveRuleByConfigKey("pmd", "rulesets/coupling.xml/ExcessiveImports"));
assertNotNull(profile.getActiveRuleByConfigKey("pmd", "rulesets/design.xml/UseNotifyAllInsteadOfNotify"));
assertThat(messages.hasErrors(), is(false));
}

@Test
public void testImportingParameters() {
Reader reader = new StringReader(TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
RulesProfile profile = importer.importProfile(reader, messages);

ActiveRule activeRule = profile.getActiveRuleByConfigKey("pmd", "rulesets/coupling.xml/ExcessiveImports");
assertThat(activeRule.getActiveRuleParams().size(), is(1));
assertThat(activeRule.getParameter("max"), is("30"));
}

@Test
public void testImportingDefaultPriority() {
Reader reader = new StringReader(TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
RulesProfile profile = importer.importProfile(reader, messages);

ActiveRule activeRule = profile.getActiveRuleByConfigKey("pmd", "rulesets/coupling.xml/ExcessiveImports");
assertThat(activeRule.getPriority(), is(RulePriority.BLOCKER)); // reuse the rule default priority
}

@Test
public void testImportingPriority() {
Reader reader = new StringReader(TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
RulesProfile profile = importer.importProfile(reader, messages);

ActiveRule activeRule = profile.getActiveRuleByConfigKey("pmd", "rulesets/design.xml/UseNotifyAllInsteadOfNotify");
assertThat(activeRule.getPriority(), is(RulePriority.MINOR));

activeRule = profile.getActiveRuleByConfigKey("pmd", "rulesets/coupling.xml/CouplingBetweenObjects");
assertThat(activeRule.getPriority(), is(RulePriority.CRITICAL));
}

@Test
public void testImportingPmdConfigurationWithUnknownNodes() {
Reader reader = new StringReader(TestUtils.getResourceContent("/org/sonar/plugins/pmd/complex-with-unknown-nodes.xml"));
RulesProfile profile = importer.importProfile(reader, messages);

assertThat(profile.getActiveRules().size(), is(3));
}

@Test
public void testUnsupportedProperty() {
Reader reader = new StringReader(TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
RulesProfile profile = importer.importProfile(reader, messages);

ActiveRule check = profile.getActiveRuleByConfigKey("pmd", "rulesets/coupling.xml/CouplingBetweenObjects");
assertThat(check.getParameter("threshold"), nullValue());
assertThat(messages.getWarnings().size(), is(1));
}

@Test
public void testUnvalidXML() {
Reader reader = new StringReader("not xml");
importer.importProfile(reader, messages);
assertThat(messages.getErrors().size(), is(1));
}

@Test
public void testImportingUnknownRules() {
Reader reader = new StringReader(TestUtils.getResourceContent("/org/sonar/plugins/pmd/simple.xml"));
importer = new PmdProfileImporter(mock(RuleFinder.class));
RulesProfile profile = importer.importProfile(reader, messages);

assertThat(profile.getActiveRules().size(), is(0));
assertThat(messages.getWarnings().size(), is(3));
}

private RuleFinder createRuleFinder() {
RuleFinder ruleFinder = mock(RuleFinder.class);
when(ruleFinder.find((RuleQuery) anyObject())).thenAnswer(new Answer<Rule>() {

public Rule answer(InvocationOnMock iom) throws Throwable {
RuleQuery query = (RuleQuery) iom.getArguments()[0];
Rule rule = Rule.create(query.getRepositoryKey(), query.getConfigKey(), "Rule name - " + query.getConfigKey())
.setConfigKey(query.getConfigKey()).setPriority(RulePriority.BLOCKER);
if (rule.getConfigKey().equals("rulesets/coupling.xml/ExcessiveImports")) {
rule.createParameter("max");
}
return rule;
}
});
return ruleFinder;
}
}

+ 0
- 396
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdRulesRepositoryTest.java 파일 보기

@@ -1,396 +0,0 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2009 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* Sonar is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* Sonar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.pmd;

import com.thoughtworks.xstream.converters.ConversionException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.CharEncoding;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.CoreProperties;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Java;
import org.sonar.api.rules.ActiveRule;
import org.sonar.api.rules.ActiveRuleParam;
import org.sonar.api.rules.RuleParam;
import org.sonar.api.rules.RulePriority;
import org.sonar.plugins.pmd.xml.Property;
import org.sonar.plugins.pmd.xml.PmdRule;
import org.sonar.plugins.pmd.xml.PmdRuleset;
import org.sonar.test.TestUtils;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.*;

public class PmdRulesRepositoryTest {

private PmdRulesRepository repository;

@Before
public void setup() {
repository = new PmdRulesRepository(new Java());
}

@Test
public void rulesAreDefinedWithTheDefaultSonarXmlFormat() {
List<org.sonar.api.rules.Rule> rules = repository.getInitialReferential();
assertTrue(rules.size() > 0);
for (org.sonar.api.rules.Rule rule : rules) {
assertNotNull(rule.getKey());
assertNotNull(rule.getDescription());
assertNotNull(rule.getConfigKey());
assertNotNull(rule.getName());
}
}

@Test
public void shouldImportconfigurationWithUtf8Character() {
RulesProfile rulesProfile = repository.loadProvidedProfile("profile", "test_xml_utf8.xml");
assertThat(rulesProfile, notNullValue());

String value = rulesProfile.getActiveRules().get(0).getActiveRuleParams().get(0).getValue();
assertThat(value, is("\u00E9"));
}

@Test
public void shouldBuildModuleWithProperties() {
org.sonar.api.rules.Rule dbRule = new org.sonar.api.rules.Rule();
dbRule.setConfigKey("rulesets/design.xml/CloseResource");
dbRule.setPluginName(CoreProperties.PMD_PLUGIN);
RuleParam ruleParam = new RuleParam(dbRule, "types", null, null);
ActiveRule activeRule = new ActiveRule(null, dbRule, RulePriority.MAJOR);
activeRule.setActiveRuleParams(Arrays.asList(new ActiveRuleParam(activeRule, ruleParam, "Connection,Statement,ResultSet")));

PmdRuleset ruleset = repository.buildModuleTree(Arrays.asList(activeRule));

assertThat(ruleset.getRules().size(), is(1));

PmdRule rule = ruleset.getRules().get(0);
assertThat(rule.getRef(), is("rulesets/design.xml/CloseResource"));
assertThat(rule.getProperties().size(), is(1));

assertThat(rule.getPriority(), is("3"));

Property property = rule.getProperties().get(0);
assertThat(property.getName(), is("types"));
assertThat(property.getValue(), is("Connection,Statement,ResultSet"));
}

@Test
public void shouldBuildManyModules() {

org.sonar.api.rules.Rule rule1 = new org.sonar.api.rules.Rule();
rule1.setPluginName(CoreProperties.PMD_PLUGIN);
rule1.setConfigKey("rulesets/design.xml/CloseResource");
ActiveRule activeRule1 = new ActiveRule(null, rule1, RulePriority.MAJOR);
org.sonar.api.rules.Rule rule2 = new org.sonar.api.rules.Rule();
rule2.setPluginName(CoreProperties.PMD_PLUGIN);
rule2.setConfigKey("rulesets/braces.xml/IfElseStmtsMustUseBraces");
ActiveRule activeRule2 = new ActiveRule(null, rule2, RulePriority.MAJOR);

PmdRuleset ruleset = repository.buildModuleTree(Arrays.asList(activeRule1, activeRule2));

assertThat(ruleset.getRules().size(), is(2));
assertThat(ruleset.getRules().get(0).getRef(), is("rulesets/design.xml/CloseResource"));
assertThat(ruleset.getRules().get(1).getRef(), is("rulesets/braces.xml/IfElseStmtsMustUseBraces"));
}

@Test
public void shouldBuilModuleTreeFromXml() throws IOException {
InputStream input = getClass().getResourceAsStream("/org/sonar/plugins/pmd/test_module_tree.xml");
PmdRuleset ruleset = repository.buildModuleTreeFromXml(IOUtils.toString(input));

assertThat(ruleset.getRules().size(), is(3));

PmdRule rule1 = ruleset.getRules().get(0);
assertThat(rule1.getRef(), is("rulesets/coupling.xml/CouplingBetweenObjects"));
assertThat(rule1.getPriority(), is("2"));
assertThat(rule1.getProperties().size(), is(1));

Property module1Property = rule1.getProperties().get(0);
assertThat(module1Property.getName(), is("threshold"));
assertThat(module1Property.getValue(), is("20"));

PmdRule rule2 = ruleset.getRules().get(1);
assertThat(rule2.getRef(), is("rulesets/coupling.xml/ExcessiveImports"));
assertThat(rule2.getPriority(), is("3"));
assertThat(rule2.getProperties().size(), is(1));

Property module2Property = rule2.getProperties().get(0);
assertThat(module2Property.getName(), is("max"));
assertThat(module2Property.getValue(), is("30"));

PmdRule rule3 = ruleset.getRules().get(2);
assertThat(rule3.getRef(), is("rulesets/design.xml/UseNotifyAllInsteadOfNotify"));
assertThat(rule3.getPriority(), is("4"));
assertNull(rule3.getProperties());
}

@Test
public void shouldBuilModuleTreeFromXmlInUtf8() throws IOException {
InputStream input = getClass().getResourceAsStream("/org/sonar/plugins/pmd/test_xml_utf8.xml");
PmdRuleset ruleset = repository.buildModuleTreeFromXml(IOUtils.toString(input, CharEncoding.UTF_8));

PmdRule rule1 = ruleset.getRules().get(0);
assertThat(rule1.getRef(), is("rulesets/coupling.xml/CouplingBetweenObjects"));
assertThat(rule1.getProperties().get(0).getValue(), is("\u00E9"));
}

@Test
public void shouldBuilXmlFromModuleTree() throws IOException, SAXException {
PmdRuleset ruleset = buildModuleTreeFixture();
String xml = repository.buildXmlFromModuleTree(ruleset);
assertXmlAreSimilar(xml, "test_module_tree.xml");
}


@Test
public void shouldImportConfiguration() throws IOException {
final List<org.sonar.api.rules.Rule> inputRules = buildRulesFixture();
List<ActiveRule> activeRulesExpected = buildActiveRulesFixture(inputRules);

InputStream input = getClass().getResourceAsStream("/org/sonar/plugins/pmd/test_module_tree.xml");
List<ActiveRule> results = repository.importConfiguration(IOUtils.toString(input), inputRules);

assertThat(results.size(), is(activeRulesExpected.size()));
assertActiveRulesAreEquals(results, activeRulesExpected);
}

@Test
public void shouldImportPmdLevelsAsSonarLevels() throws IOException {
InputStream input = getClass().getResourceAsStream("/org/sonar/plugins/pmd/PmdRulesRepositoryTest/shouldImportPmdLevelsAsSonarLevels.xml");
final List<org.sonar.api.rules.Rule> rules = buildRulesFixture();
List<ActiveRule> results = repository.importConfiguration(IOUtils.toString(input), rules);

assertThat(results.size(), is(3));
assertThat(results.get(0).getPriority(), is(RulePriority.MAJOR));
assertThat(results.get(1).getPriority(), is(RulePriority.MINOR));
assertThat(results.get(2).getPriority(), is(RulePriority.INFO));
}

@Test
public void shouldImportWithDefaultRuleLevelWhenNoExplicitPriority() throws IOException {
InputStream input = getClass().getResourceAsStream("/org/sonar/plugins/pmd/PmdRulesRepositoryTest/shouldImportWithDefaultRuleLevelWhenNoExplicitPriority.xml");
final List<org.sonar.api.rules.Rule> rules = buildRulesFixture();
List<ActiveRule> results = repository.importConfiguration(IOUtils.toString(input), rules);

assertThat(results.size(), is(1));
assertThat(results.get(0).getPriority(), is(RulePriority.MAJOR));
}

@Test
public void shouldImportConfigurationContainingDataToExcludeWithoutException() throws IOException {
shouldImportConfiguration("test_xml_with_data_to_exclude.xml");
}

// See http://jira.codehaus.org/browse/XSTR-448 for details
@Test(expected = ConversionException.class)
public void shouldFailToImportConfigurationContainingClassParamBecauseOfXStreamLimitation() throws IOException {
shouldImportConfiguration("test_xml_with_class_param.xml");
}

@Test
public void shouldBuildActiveRulesFromModuleTree() {
final List<org.sonar.api.rules.Rule> inputRules = buildRulesFixture();
List<ActiveRule> activeRulesExpected = buildActiveRulesFixture(inputRules);

List<ActiveRule> activeRules = new ArrayList<ActiveRule>();
PmdRuleset ruleset = buildModuleTreeFixture();
repository.buildActiveRulesFromModuleTree(ruleset, activeRules, inputRules);

assertThat(activeRulesExpected.size(), is(activeRules.size()));
assertActiveRulesAreEquals(activeRulesExpected, activeRules);
}

@Test
public void shouldProvideProfiles() {
List<RulesProfile> profiles = repository.getProvidedProfiles();
assertThat(profiles.size(), is(3));

RulesProfile profile1 = profiles.get(0);
assertThat(profile1.getName(), is(RulesProfile.SONAR_WAY_NAME));
assertTrue(profile1.getActiveRules().size() + "", profile1.getActiveRules().size() > 30);

RulesProfile profile2 = profiles.get(1);
assertThat(profile2.getName(), is(RulesProfile.SONAR_WAY_FINDBUGS_NAME));
assertTrue(profile2.getActiveRules().size() + "", profile2.getActiveRules().size() > 30);

RulesProfile profile3 = profiles.get(2);
assertThat(profile3.getName(), is(RulesProfile.SUN_CONVENTIONS_NAME));
assertTrue(profile3.getActiveRules().size() + "", profile3.getActiveRules().size() > 1);
}


@Test
public void shouldAddHeaderToXml() throws IOException, SAXException {
String xml = repository.addHeaderToXml("<ruleset/>");
assertXmlAreSimilar(xml, "test_header.xml");
}

@Test
public void shouldBuildOnlyOneModuleWhenNoPmdActiveRules() {
org.sonar.api.rules.Rule rule1 = new org.sonar.api.rules.Rule();
rule1.setPluginName("not-a-pmd-plugin");
ActiveRule activeRule1 = new ActiveRule(null, rule1, RulePriority.CRITICAL);
org.sonar.api.rules.Rule rule2 = new org.sonar.api.rules.Rule();
rule2.setPluginName("not-a-pmd-plugin");
ActiveRule activeRule2 = new ActiveRule(null, rule1, RulePriority.CRITICAL);

PmdRuleset tree = repository.buildModuleTree(Arrays.asList(activeRule1, activeRule2));
assertThat(tree.getRules().size(), is(0));
}

@Test
public void shouldBuildOnlyOneModuleWhenNoActiveRules() {
PmdRuleset tree = repository.buildModuleTree(Collections.<ActiveRule>emptyList());
assertThat(tree.getRules().size(), is(0));
}

@Test
public void shouldBuildTwoModulesEvenIfSameTwoRulesActivated() {
org.sonar.api.rules.Rule dbRule1 = new org.sonar.api.rules.Rule();
dbRule1.setPluginName(CoreProperties.PMD_PLUGIN);
dbRule1.setConfigKey("rulesets/coupling.xml/CouplingBetweenObjects");
ActiveRule activeRule1 = new ActiveRule(null, dbRule1, RulePriority.CRITICAL);
org.sonar.api.rules.Rule dbRule2 = new org.sonar.api.rules.Rule();
dbRule2.setPluginName(CoreProperties.PMD_PLUGIN);
dbRule2.setConfigKey("rulesets/coupling.xml/CouplingBetweenObjects");
ActiveRule activeRule2 = new ActiveRule(null, dbRule2, RulePriority.CRITICAL);

PmdRuleset tree = repository.buildModuleTree(Arrays.asList(activeRule1, activeRule2));
assertThat(tree.getRules().size(), is(2));

PmdRule rule1 = tree.getRules().get(0);
assertThat(rule1.getRef(), is("rulesets/coupling.xml/CouplingBetweenObjects"));

PmdRule rule2 = tree.getRules().get(1);
assertThat(rule2.getRef(), is("rulesets/coupling.xml/CouplingBetweenObjects"));
}

// ------------------------------------------------------------------------
// -- Private methods
// ------------------------------------------------------------------------

private void assertXmlAreSimilar(String xml, String xmlFileToFind) throws IOException, SAXException {
InputStream input = getClass().getResourceAsStream("/org/sonar/plugins/pmd/" + xmlFileToFind);
String xmlToFind = IOUtils.toString(input);
TestUtils.assertSimilarXml(xmlToFind, xml);
}

private PmdRuleset buildModuleTreeFixture() {
PmdRuleset ruleset = new PmdRuleset();
ruleset.setDescription("Sonar PMD rules");

PmdRule rule1 = new PmdRule("rulesets/coupling.xml/CouplingBetweenObjects", "2");
rule1.addProperty(new Property("threshold", "20"));
ruleset.addRule(rule1);

PmdRule rule2 = new PmdRule("rulesets/coupling.xml/ExcessiveImports", "3");
rule2.addProperty(new Property("max", "30"));
ruleset.addRule(rule2);

PmdRule rule3 = new PmdRule("rulesets/design.xml/UseNotifyAllInsteadOfNotify", "4");
ruleset.addRule(rule3);

return ruleset;
}

private List<org.sonar.api.rules.Rule> buildRulesFixture() {
final org.sonar.api.rules.Rule rule1 = new org.sonar.api.rules.Rule("Coupling Between Objects", "CouplingBetweenObjects",
"rulesets/coupling.xml/CouplingBetweenObjects", null, CoreProperties.PMD_PLUGIN, null);
RuleParam ruleParam1 = new RuleParam(rule1, "threshold", null, "i");
rule1.setParams(Arrays.asList(ruleParam1));

final org.sonar.api.rules.Rule rule2 = new org.sonar.api.rules.Rule("Excessive Imports", "ExcessiveImports",
"rulesets/coupling.xml/ExcessiveImports", null, CoreProperties.PMD_PLUGIN, null);
RuleParam ruleParam2 = new RuleParam(rule2, "max", null, "i");
rule2.setParams(Arrays.asList(ruleParam2));

final org.sonar.api.rules.Rule rule3 = new org.sonar.api.rules.Rule("Use Notify All Instead Of Notify", "UseNotifyAllInsteadOfNotify",
"rulesets/design.xml/UseNotifyAllInsteadOfNotify", null, CoreProperties.PMD_PLUGIN, null);

final org.sonar.api.rules.Rule rule4 = new org.sonar.api.rules.Rule("Class names should always begin with an upper case character.", "ClassNamingConventions",
"rulesets/naming.xml/ClassNamingConventions", null, CoreProperties.PMD_PLUGIN, null);

return Arrays.asList(rule1, rule2, rule3, rule4);
}

private List<ActiveRule> buildActiveRulesFixture(List<org.sonar.api.rules.Rule> rules) {
List<ActiveRule> activeRules = new ArrayList<ActiveRule>();

ActiveRule activeRule1 = new ActiveRule(null, rules.get(0), RulePriority.CRITICAL);
activeRule1.setActiveRuleParams(Arrays.asList(new ActiveRuleParam(activeRule1, rules.get(0).getParams().get(0), "20")));
activeRules.add(activeRule1);

ActiveRule activeRule2 = new ActiveRule(null, rules.get(1), RulePriority.MAJOR);
activeRule2.setActiveRuleParams(Arrays.asList(new ActiveRuleParam(activeRule2, rules.get(1).getParams().get(0), "30")));
activeRules.add(activeRule2);

ActiveRule activeRule3 = new ActiveRule(null, rules.get(2), RulePriority.MINOR);
activeRules.add(activeRule3);

return activeRules;

}

private void assertActiveRulesAreEquals(List<ActiveRule> activeRules1, List<ActiveRule> activeRules2) {
for (int i = 0; i < activeRules1.size(); i++) {
ActiveRule activeRule1 = activeRules1.get(i);
ActiveRule activeRule2 = activeRules2.get(i);
assertTrue(activeRule1.getRule().equals(activeRule2.getRule()));
assertTrue(activeRule1.getPriority().equals(activeRule2.getPriority()));
assertEquals(activeRule1.getActiveRuleParams().size(), (activeRule2.getActiveRuleParams().size()));

for (int j = 0; j < activeRule1.getActiveRuleParams().size(); j++) {
ActiveRuleParam activeRuleParam1 = activeRule1.getActiveRuleParams().get(j);
ActiveRuleParam activeRuleParam2 = activeRule2.getActiveRuleParams().get(j);
assertTrue(activeRuleParam1.getRuleParam().equals(activeRuleParam2.getRuleParam())
&& activeRuleParam1.getValue().equals(activeRuleParam2.getValue()));
}
}
}

public void shouldImportConfiguration(String configurationFile) throws IOException {
final List<org.sonar.api.rules.Rule> inputRules = buildRulesFixture();
List<ActiveRule> activeRulesExpected = buildActiveRulesFixture(inputRules);

InputStream input = getClass().getResourceAsStream("/org/sonar/plugins/pmd/" + configurationFile);
List<ActiveRule> results = repository.importConfiguration(IOUtils.toString(input), inputRules);

assertThat(results.size(), is(activeRulesExpected.size()));
assertActiveRulesAreEquals(results, activeRulesExpected);
}

@Test
public void shouldUseTheProfileNameWhenBuildingTheRulesSet() {
PmdRuleset tree = repository.buildModuleTree(Collections.<ActiveRule>emptyList(), "aprofile");
assertThat(tree.getDescription(), is("aprofile"));
}

}

+ 66
- 0
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SonarWayProfileTest.java 파일 보기

@@ -0,0 +1,66 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2009 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* Sonar is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* Sonar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.pmd;

import static org.hamcrest.core.Is.is;
import static org.hamcrest.number.OrderingComparisons.greaterThan;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.sonar.api.profiles.ProfileDefinition;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.rules.RuleQuery;
import org.sonar.api.utils.ValidationMessages;

public class SonarWayProfileTest {

@Test
public void create() {
ProfileDefinition sonarWay = new SonarWayProfile(createPmdProfileImporter());
ValidationMessages validation = ValidationMessages.create();
RulesProfile profile = sonarWay.createProfile(validation);
assertThat(profile.getActiveRulesByRepository(PmdConstants.REPOSITORY_KEY).size(), greaterThan(1));
assertThat(validation.hasErrors(), is(false));
}

private PmdProfileImporter createPmdProfileImporter() {

RuleFinder ruleFinder = mock(RuleFinder.class);
when(ruleFinder.find((RuleQuery) anyObject())).thenAnswer(new Answer<Rule>() {

public Rule answer(InvocationOnMock iom) throws Throwable {
RuleQuery query = (RuleQuery) iom.getArguments()[0];
Rule rule = Rule.create(query.getRepositoryKey(), query.getConfigKey(), "Rule name - " + query.getConfigKey())
.setConfigKey(query.getConfigKey()).setPriority(RulePriority.BLOCKER);
return rule;
}
});
PmdProfileImporter importer = new PmdProfileImporter(ruleFinder);
return importer;
}
}

+ 65
- 0
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SonarWayWithFindbugsProfileTest.java 파일 보기

@@ -0,0 +1,65 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2009 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* Sonar is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* Sonar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.pmd;

import static org.hamcrest.core.Is.is;
import static org.hamcrest.number.OrderingComparisons.greaterThan;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.rules.RuleQuery;
import org.sonar.api.utils.ValidationMessages;

public class SonarWayWithFindbugsProfileTest {

@Test
public void create() {
SonarWayWithFindbugsProfile sonarWayWithFindbugs = new SonarWayWithFindbugsProfile(new SonarWayProfile(createPmdProfileImporter()));
ValidationMessages validation = ValidationMessages.create();
RulesProfile profile = sonarWayWithFindbugs.createProfile(validation);
assertThat(profile.getActiveRulesByRepository(PmdConstants.REPOSITORY_KEY).size(), greaterThan(1));
assertThat(validation.hasErrors(), is(false));
}

private PmdProfileImporter createPmdProfileImporter() {

RuleFinder ruleFinder = mock(RuleFinder.class);
when(ruleFinder.find((RuleQuery) anyObject())).thenAnswer(new Answer<Rule>() {

public Rule answer(InvocationOnMock iom) throws Throwable {
RuleQuery query = (RuleQuery) iom.getArguments()[0];
Rule rule = Rule.create(query.getRepositoryKey(), query.getConfigKey(), "Rule name - " + query.getConfigKey())
.setConfigKey(query.getConfigKey()).setPriority(RulePriority.BLOCKER);
return rule;
}
});
PmdProfileImporter importer = new PmdProfileImporter(ruleFinder);
return importer;
}
}

+ 65
- 0
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SunConventionsProfileTest.java 파일 보기

@@ -0,0 +1,65 @@
/*
* Sonar, open source software quality management tool.
* Copyright (C) 2009 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* Sonar is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* Sonar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.pmd;

import static org.hamcrest.core.Is.is;
import static org.hamcrest.number.OrderingComparisons.greaterThan;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.rules.RuleQuery;
import org.sonar.api.utils.ValidationMessages;

public class SunConventionsProfileTest {
@Test
public void create() {
SunConventionsProfile sunConvention = new SunConventionsProfile(createPmdProfileImporter());
ValidationMessages validation = ValidationMessages.create();
RulesProfile profile = sunConvention.createProfile(validation);
assertThat(profile.getActiveRulesByRepository(PmdConstants.REPOSITORY_KEY).size(), greaterThan(1));
assertThat(validation.hasErrors(), is(false));
}

private PmdProfileImporter createPmdProfileImporter() {

RuleFinder ruleFinder = mock(RuleFinder.class);
when(ruleFinder.find((RuleQuery) anyObject())).thenAnswer(new Answer<Rule>() {

public Rule answer(InvocationOnMock iom) throws Throwable {
RuleQuery query = (RuleQuery) iom.getArguments()[0];
Rule rule = Rule.create(query.getRepositoryKey(), query.getConfigKey(), "Rule name - " + query.getConfigKey())
.setConfigKey(query.getConfigKey()).setPriority(RulePriority.BLOCKER);
return rule;
}
});
PmdProfileImporter importer = new PmdProfileImporter(ruleFinder);
return importer;
}

}

+ 0
- 15
plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/PmdRulesRepositoryTest/shouldImportPmdLevelsAsSonarLevels.xml 파일 보기

@@ -1,15 +0,0 @@
<ruleset>
<description>Sonar PMD rules</description>
<rule ref="rulesets/coupling.xml/ExcessiveImports">
<priority>3</priority>
<properties>
<property name="max" value="30"/>
</properties>
</rule>
<rule ref="rulesets/design.xml/UseNotifyAllInsteadOfNotify">
<priority>4</priority>
</rule>
<rule ref="rulesets/naming.xml/ClassNamingConventions">
<priority>5</priority>
</rule>
</ruleset>

+ 0
- 7
plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/PmdRulesRepositoryTest/shouldImportWithDefaultRuleLevelWhenNoExplicitPriority.xml 파일 보기

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<ruleset xmlns="http://pmd.sf.net/ruleset/1.0.0" name="pmd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd">
<description>test</description>
<rule ref="rulesets/naming.xml/ClassNamingConventions"/>
</ruleset>

plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/test_xml_with_data_to_exclude.xml → plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/complex-with-unknown-nodes.xml 파일 보기


plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/test_module_tree.xml → plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/simple.xml 파일 보기

@@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<ruleset>
<description>Sonar PMD rules</description>
<rule ref="rulesets/coupling.xml/CouplingBetweenObjects">
@@ -7,7 +8,6 @@
</properties>
</rule>
<rule ref="rulesets/coupling.xml/ExcessiveImports">
<priority>3</priority>
<properties>
<property name="max" value="30"/>
</properties>

+ 0
- 3
plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/test_header.xml 파일 보기

@@ -1,3 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Sonar PMD rules generated configuration -->
<ruleset/>

+ 0
- 11
plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/test_xml_utf8.xml 파일 보기

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Sonar PMD rules generated configuration -->
<ruleset>
<description>Sonar PMD rules</description>
<rule ref="rulesets/coupling.xml/CouplingBetweenObjects">
<priority>1</priority>
<properties>
<property name="threshold" value="é"/>
</properties>
</rule>
</ruleset>

+ 0
- 28
plugins/sonar-pmd-plugin/src/test/resources/org/sonar/plugins/pmd/test_xml_with_class_param.xml 파일 보기

@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Sonar PMD rules generated configuration -->
<ruleset language="My language" name="My name">
<description>Sonar PMD rules</description>
<exclude-pattern>to exclude</exclude-pattern>
<include-pattern>to include</include-pattern>
<rule ref="rulesets/coupling.xml/CouplingBetweenObjects" externalInfoUrl="String" typeResolution="false" dfa="true"
name="ID_1" class="NMTOKEN" message="String" since="String">
<description>rule description</description>
<priority>2</priority>
<properties>
<property name="threshold" value="20"/>
</properties>
<exclude name="NMTOKEN"/>
<example>an example</example>
</rule>
<rule ref="rulesets/coupling.xml/ExcessiveImports">
<priority>3</priority>
<properties>
<property name="max" value="30" pluginname="plugin name" description="property description"/>
</properties>
</rule>
<rule ref="rulesets/design.xml/UseNotifyAllInsteadOfNotify">
<priority>4</priority>
</rule>
</ruleset>

Loading…
취소
저장