@@ -33,19 +33,21 @@ public final class CheckstyleRuleRepository extends RuleRepository { | |||
// for user extensions | |||
private ServerFileSystem fileSystem; | |||
private XMLRuleParser xmlRuleParser; | |||
public CheckstyleRuleRepository(ServerFileSystem fileSystem) { | |||
public CheckstyleRuleRepository(ServerFileSystem fileSystem, XMLRuleParser xmlRuleParser) { | |||
super(CheckstyleConstants.REPOSITORY_KEY, Java.KEY); | |||
setName(CheckstyleConstants.REPOSITORY_NAME); | |||
this.fileSystem = fileSystem; | |||
this.xmlRuleParser = xmlRuleParser; | |||
} | |||
@Override | |||
public List<Rule> createRules() { | |||
List<Rule> rules = new ArrayList<Rule>(); | |||
rules.addAll(XMLRuleParser.parseXML(getClass().getResourceAsStream("/org/sonar/plugins/checkstyle/rules.xml"))); | |||
rules.addAll(xmlRuleParser.parse(getClass().getResourceAsStream("/org/sonar/plugins/checkstyle/rules.xml"))); | |||
for (File userExtensionXml : fileSystem.getExtensions(CheckstyleConstants.REPOSITORY_KEY, "xml")) { | |||
rules.addAll(XMLRuleParser.parseXML(userExtensionXml)); | |||
rules.addAll(xmlRuleParser.parse(userExtensionXml)); | |||
} | |||
return rules; | |||
} |
@@ -22,6 +22,7 @@ package org.sonar.plugins.checkstyle; | |||
import org.junit.Test; | |||
import org.sonar.api.platform.ServerFileSystem; | |||
import org.sonar.api.rules.Rule; | |||
import org.sonar.api.rules.XMLRuleParser; | |||
import java.util.List; | |||
@@ -34,7 +35,7 @@ public class CheckstyleRuleRepositoryTest { | |||
@Test | |||
public void loadRepositoryFromXml() { | |||
ServerFileSystem fileSystem = mock(ServerFileSystem.class); | |||
CheckstyleRuleRepository repository = new CheckstyleRuleRepository(fileSystem); | |||
CheckstyleRuleRepository repository = new CheckstyleRuleRepository(fileSystem, new XMLRuleParser()); | |||
List<Rule> rules = repository.createRules(); | |||
assertThat(rules.size(), greaterThan(100)); | |||
} |
@@ -28,13 +28,16 @@ import java.util.List; | |||
public final class FindbugsRuleRepository extends RuleRepository { | |||
public FindbugsRuleRepository() { | |||
private XMLRuleParser xmlRuleParser; | |||
public FindbugsRuleRepository(XMLRuleParser xmlRuleParser) { | |||
super(FindbugsConstants.REPOSITORY_KEY, Java.KEY); | |||
setName(FindbugsConstants.REPOSITORY_NAME); | |||
this.xmlRuleParser = xmlRuleParser; | |||
} | |||
@Override | |||
public List<Rule> createRules() { | |||
return XMLRuleParser.parseXML(getClass().getResourceAsStream("/org/sonar/plugins/findbugs/rules.xml")); | |||
return xmlRuleParser.parse(getClass().getResourceAsStream("/org/sonar/plugins/findbugs/rules.xml")); | |||
} | |||
} |
@@ -25,13 +25,14 @@ import java.util.List; | |||
import org.sonar.api.rules.Rule; | |||
import org.sonar.api.rules.RuleFinder; | |||
import org.sonar.api.rules.RuleQuery; | |||
import org.sonar.api.rules.XMLRuleParser; | |||
public class FindbugsRuleFinder implements RuleFinder { | |||
private final List<Rule> findbugsRules; | |||
public FindbugsRuleFinder() { | |||
FindbugsRuleRepository repo = new FindbugsRuleRepository(); | |||
FindbugsRuleRepository repo = new FindbugsRuleRepository(new XMLRuleParser()); | |||
findbugsRules = repo.createRules(); | |||
for(Rule rule : findbugsRules){ | |||
rule.setRepositoryKey(FindbugsConstants.REPOSITORY_KEY); |
@@ -27,12 +27,13 @@ import java.util.List; | |||
import org.junit.Test; | |||
import org.sonar.api.rules.Rule; | |||
import org.sonar.api.rules.XMLRuleParser; | |||
public class FindbugsRuleRepositoryTest { | |||
@Test | |||
public void testLoadRepositoryFromXml() { | |||
FindbugsRuleRepository repository = new FindbugsRuleRepository(); | |||
FindbugsRuleRepository repository = new FindbugsRuleRepository(new XMLRuleParser()); | |||
List<Rule> rules = repository.createRules(); | |||
assertThat(rules.size(), greaterThan(300)); | |||
for (Rule rule : rules) { |
@@ -35,11 +35,7 @@ import org.mockito.stubbing.Answer; | |||
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.Rule; | |||
import org.sonar.api.rules.RulePriority; | |||
import org.sonar.api.rules.RuleQuery; | |||
import org.sonar.api.rules.RulesManager; | |||
import org.sonar.api.rules.*; | |||
import org.sonar.test.TestUtils; | |||
import org.xml.sax.SAXException; | |||
@@ -93,7 +89,7 @@ public abstract class FindbugsTests { | |||
RulesProfile profile = RulesProfile.create(); | |||
profile.setName(RulesProfile.SONAR_WAY_FINDBUGS_NAME); | |||
profile.setLanguage(Java.KEY); | |||
for (Rule rule : new FindbugsRuleRepository().createRules()) { | |||
for (Rule rule : new FindbugsRuleRepository(new XMLRuleParser()).createRules()) { | |||
rule.setRepositoryKey(FindbugsConstants.REPOSITORY_KEY); | |||
profile.activateRule(rule, null); | |||
} |
@@ -19,6 +19,7 @@ | |||
*/ | |||
package org.sonar.plugins.pmd; | |||
import com.google.common.collect.Lists; | |||
import org.sonar.api.platform.ServerFileSystem; | |||
import org.sonar.api.resources.Java; | |||
import org.sonar.api.rules.Rule; | |||
@@ -26,26 +27,27 @@ import org.sonar.api.rules.RuleRepository; | |||
import org.sonar.api.rules.XMLRuleParser; | |||
import java.io.File; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
public final class PmdRuleRepository extends RuleRepository { | |||
// for user extensions | |||
private ServerFileSystem fileSystem; | |||
private XMLRuleParser xmlRuleParser; | |||
public PmdRuleRepository(ServerFileSystem fileSystem) { | |||
public PmdRuleRepository(ServerFileSystem fileSystem, XMLRuleParser xmlRuleParser) { | |||
super(PmdConstants.REPOSITORY_KEY, Java.KEY); | |||
setName(PmdConstants.REPOSITORY_NAME); | |||
this.fileSystem = fileSystem; | |||
this.xmlRuleParser = xmlRuleParser; | |||
} | |||
@Override | |||
public List<Rule> createRules() { | |||
List<Rule> rules = new ArrayList<Rule>(); | |||
rules.addAll(XMLRuleParser.parseXML(getClass().getResourceAsStream("/org/sonar/plugins/pmd/rules.xml"))); | |||
List<Rule> rules = Lists.newArrayList(); | |||
rules.addAll(xmlRuleParser.parse(getClass().getResourceAsStream("/org/sonar/plugins/pmd/rules.xml"))); | |||
for (File userExtensionXml : fileSystem.getExtensions(PmdConstants.REPOSITORY_KEY, "xml")) { | |||
rules.addAll(XMLRuleParser.parseXML(userExtensionXml)); | |||
rules.addAll(xmlRuleParser.parse(userExtensionXml)); | |||
} | |||
return rules; | |||
} |
@@ -17,10 +17,7 @@ import org.apache.commons.lang.StringUtils; | |||
import org.junit.Test; | |||
import org.sonar.api.platform.ServerFileSystem; | |||
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.RuleQuery; | |||
import org.sonar.api.rules.*; | |||
import org.sonar.api.utils.ValidationMessages; | |||
import org.sonar.plugins.pmd.xml.PmdProperty; | |||
import org.sonar.plugins.pmd.xml.PmdRule; | |||
@@ -34,7 +31,7 @@ public class PmdProfileExporterTest { | |||
@Test | |||
public void testExportProfile() throws IOException, SAXException { | |||
ServerFileSystem fileSystem = mock(ServerFileSystem.class); | |||
PmdRuleRepository repository = new PmdRuleRepository(fileSystem); | |||
PmdRuleRepository repository = new PmdRuleRepository(fileSystem, new XMLRuleParser()); | |||
List<Rule> rules = repository.createRules(); | |||
RuleFinder ruleFinder = new PmdRuleFinder(rules); |
@@ -28,13 +28,14 @@ import java.util.List; | |||
import org.junit.Test; | |||
import org.sonar.api.platform.ServerFileSystem; | |||
import org.sonar.api.rules.Rule; | |||
import org.sonar.api.rules.XMLRuleParser; | |||
public class PmdRuleRepositoryTest { | |||
@Test | |||
public void testLoadRepositoryFromXml() { | |||
ServerFileSystem fileSystem = mock(ServerFileSystem.class); | |||
PmdRuleRepository repository = new PmdRuleRepository(fileSystem); | |||
PmdRuleRepository repository = new PmdRuleRepository(fileSystem, new XMLRuleParser()); | |||
List<Rule> rules = repository.createRules(); | |||
assertThat(rules.size(), greaterThan(100)); | |||
} |
@@ -23,6 +23,7 @@ import com.google.common.collect.Lists; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.api.ServerComponent; | |||
import org.sonar.api.utils.AnnotationUtils; | |||
import org.sonar.check.Check; | |||
@@ -33,50 +34,34 @@ import java.util.List; | |||
/** | |||
* @since 2.3 | |||
*/ | |||
public final class AnnotationRuleRepository extends RuleRepository { | |||
public final class AnnotationRuleParser implements ServerComponent { | |||
private static final Logger LOG = LoggerFactory.getLogger(AnnotationRuleRepository.class); | |||
private static final Logger LOG = LoggerFactory.getLogger(AnnotationRuleParser.class); | |||
private Collection<Class> annotatedClasses; | |||
/** | |||
* Use the factory method create() | |||
*/ | |||
private AnnotationRuleRepository(String key, String language, String name, Collection<Class> annotatedClasses) { | |||
super(key, language); | |||
setName(name); | |||
this.annotatedClasses = annotatedClasses; | |||
} | |||
public static AnnotationRuleRepository create(String key, String language, String name, Collection<Class> annotatedClasses) { | |||
return new AnnotationRuleRepository(key, language, name, annotatedClasses); | |||
} | |||
@Override | |||
public List<Rule> createRules() { | |||
public List<Rule> parse(String repositoryKey, Collection<Class> annotatedClasses) { | |||
List<Rule> rules = Lists.newArrayList(); | |||
for (Class annotatedClass : annotatedClasses) { | |||
rules.add(create(annotatedClass)); | |||
rules.add(create(repositoryKey, annotatedClass)); | |||
} | |||
return rules; | |||
} | |||
private Rule create(Class annotatedClass) { | |||
private Rule create(String repositoryKey, Class annotatedClass) { | |||
org.sonar.check.Rule ruleAnnotation = AnnotationUtils.getClassAnnotation(annotatedClass, org.sonar.check.Rule.class); | |||
if (ruleAnnotation != null) { | |||
return toRule(annotatedClass, ruleAnnotation); | |||
return toRule(repositoryKey, annotatedClass, ruleAnnotation); | |||
} | |||
Check checkAnnotation = AnnotationUtils.getClassAnnotation(annotatedClass, Check.class); | |||
if (checkAnnotation != null) { | |||
return toRule(annotatedClass, checkAnnotation); | |||
return toRule(repositoryKey, annotatedClass, checkAnnotation); | |||
} | |||
LOG.warn("The class " + annotatedClass.getCanonicalName() + " is not a check template. It should be annotated with " + Rule.class); | |||
LOG.warn("The class " + annotatedClass.getCanonicalName() + " should be annotated with " + Rule.class); | |||
return null; | |||
} | |||
private Rule toRule(Class clazz, org.sonar.check.Rule ruleAnnotation) { | |||
String key = StringUtils.defaultIfEmpty(ruleAnnotation.key(), clazz.getCanonicalName()); | |||
Rule rule = Rule.create(getKey(), key, ruleAnnotation.name()); | |||
private Rule toRule(String repositoryKey, Class clazz, org.sonar.check.Rule ruleAnnotation) { | |||
String ruleKey = StringUtils.defaultIfEmpty(ruleAnnotation.key(), clazz.getCanonicalName()); | |||
Rule rule = Rule.create(repositoryKey, ruleKey, ruleAnnotation.name()); | |||
rule.setDescription(ruleAnnotation.description()); | |||
rule.setRulesCategory(RulesCategory.fromIsoCategory(ruleAnnotation.isoCategory())); | |||
rule.setPriority(RulePriority.fromCheckPriority(ruleAnnotation.priority())); | |||
@@ -91,9 +76,9 @@ public final class AnnotationRuleRepository extends RuleRepository { | |||
return rule; | |||
} | |||
private Rule toRule(Class clazz, Check checkAnnotation) { | |||
String key = StringUtils.defaultIfEmpty(checkAnnotation.key(), clazz.getCanonicalName()); | |||
Rule rule = Rule.create(getKey(), key, checkAnnotation.title()); | |||
private Rule toRule(String repositoryKey, Class clazz, Check checkAnnotation) { | |||
String ruleKey = StringUtils.defaultIfEmpty(checkAnnotation.key(), clazz.getCanonicalName()); | |||
Rule rule = Rule.create(repositoryKey, ruleKey, checkAnnotation.title()); | |||
rule.setDescription(checkAnnotation.description()); | |||
rule.setRulesCategory(RulesCategory.fromIsoCategory(checkAnnotation.isoCategory())); | |||
rule.setPriority(RulePriority.fromCheckPriority(checkAnnotation.priority())); |
@@ -27,6 +27,7 @@ import org.codehaus.stax2.XMLInputFactory2; | |||
import org.codehaus.staxmate.SMInputFactory; | |||
import org.codehaus.staxmate.in.SMHierarchicCursor; | |||
import org.codehaus.staxmate.in.SMInputCursor; | |||
import org.sonar.api.ServerComponent; | |||
import org.sonar.api.utils.SonarException; | |||
import javax.xml.stream.XMLInputFactory; | |||
@@ -38,17 +39,13 @@ import java.util.List; | |||
/** | |||
* @since 2.3 | |||
*/ | |||
public final class XMLRuleParser { | |||
public final class XMLRuleParser implements ServerComponent { | |||
private XMLRuleParser() { | |||
// only static methods | |||
} | |||
public static List<Rule> parseXML(File file) { | |||
public List<Rule> parse(File file) { | |||
Reader reader = null; | |||
try { | |||
reader = new InputStreamReader(FileUtils.openInputStream(file), CharEncoding.UTF_8); | |||
return parseXML(reader); | |||
return parse(reader); | |||
} catch (IOException e) { | |||
throw new SonarException("Fail to load the file: " + file, e); | |||
@@ -61,11 +58,11 @@ public final class XMLRuleParser { | |||
/** | |||
* Warning : the input stream is closed in this method | |||
*/ | |||
public static List<Rule> parseXML(InputStream input) { | |||
public List<Rule> parse(InputStream input) { | |||
Reader reader = null; | |||
try { | |||
reader = new InputStreamReader(input, CharEncoding.UTF_8); | |||
return parseXML(reader); | |||
return parse(reader); | |||
} catch (IOException e) { | |||
throw new SonarException("Fail to load the xml stream", e); | |||
@@ -75,7 +72,7 @@ public final class XMLRuleParser { | |||
} | |||
} | |||
public static List<Rule> parseXML(Reader reader) { | |||
public List<Rule> parse(Reader reader) { | |||
XMLInputFactory xmlFactory = XMLInputFactory2.newInstance(); | |||
xmlFactory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE); | |||
xmlFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.FALSE); |
@@ -35,7 +35,7 @@ public class XMLRuleParserTest { | |||
@Test | |||
public void parseXml() { | |||
List<Rule> rules = XMLRuleParser.parseXML(getClass().getResourceAsStream("/org/sonar/api/rules/XMLRuleParserTest/rules.xml")); | |||
List<Rule> rules = new XMLRuleParser().parse(getClass().getResourceAsStream("/org/sonar/api/rules/XMLRuleParserTest/rules.xml")); | |||
assertThat(rules.size(), is(2)); | |||
Rule rule = rules.get(0); | |||
@@ -59,17 +59,17 @@ public class XMLRuleParserTest { | |||
@Test(expected = SonarException.class) | |||
public void failIfMissingRuleKey() { | |||
XMLRuleParser.parseXML(new StringReader("<rules><rule><name>Foo</name></rule></rules>")); | |||
new XMLRuleParser().parse(new StringReader("<rules><rule><name>Foo</name></rule></rules>")); | |||
} | |||
@Test(expected = SonarException.class) | |||
public void failIfMissingPropertyKey() { | |||
XMLRuleParser.parseXML(new StringReader("<rules><rule><key>foo</key><name>Foo</name><param></param></rule></rules>")); | |||
new XMLRuleParser().parse(new StringReader("<rules><rule><key>foo</key><name>Foo</name><param></param></rule></rules>")); | |||
} | |||
@Test | |||
public void utf8Encoding() { | |||
List<Rule> rules = XMLRuleParser.parseXML(getClass().getResourceAsStream("/org/sonar/api/rules/XMLRuleParserTest/utf8.xml")); | |||
List<Rule> rules = new XMLRuleParser().parse(getClass().getResourceAsStream("/org/sonar/api/rules/XMLRuleParserTest/utf8.xml")); | |||
assertThat(rules.size(), is(1)); | |||
Rule rule = rules.get(0); | |||
assertThat(rule.getKey(), is("com.puppycrawl.tools.checkstyle.checks.naming.LocalVariableNameCheck")); | |||
@@ -82,7 +82,7 @@ public class XMLRuleParserTest { | |||
@Test | |||
public void supportDeprecatedFormat() { | |||
// the deprecated format uses some attributes instead of nodes | |||
List<Rule> rules = XMLRuleParser.parseXML(getClass().getResourceAsStream("/org/sonar/api/rules/XMLRuleParserTest/deprecated.xml")); | |||
List<Rule> rules = new XMLRuleParser().parse(getClass().getResourceAsStream("/org/sonar/api/rules/XMLRuleParserTest/deprecated.xml")); | |||
assertThat(rules.size(), is(1)); | |||
Rule rule = rules.get(0); | |||
assertThat(rule.getPriority(), Is.is(RulePriority.CRITICAL)); |
@@ -33,6 +33,7 @@ import org.sonar.api.profiles.XMLProfileParser; | |||
import org.sonar.api.profiles.XMLProfileSerializer; | |||
import org.sonar.api.resources.Languages; | |||
import org.sonar.api.rules.DefaultRulesManager; | |||
import org.sonar.api.rules.XMLRuleParser; | |||
import org.sonar.api.utils.HttpDownloader; | |||
import org.sonar.api.utils.IocContainer; | |||
import org.sonar.api.utils.TimeProfiler; | |||
@@ -175,6 +176,7 @@ public final class Platform { | |||
servicesContainer.as(Characteristics.CACHE).addComponent(AnnotationProfileParser.class); | |||
servicesContainer.as(Characteristics.CACHE).addComponent(XMLProfileParser.class); | |||
servicesContainer.as(Characteristics.CACHE).addComponent(XMLProfileSerializer.class); | |||
servicesContainer.as(Characteristics.CACHE).addComponent(XMLRuleParser.class); | |||
servicesContainer.as(Characteristics.CACHE).addComponent(DefaultRuleFinder.class); | |||
servicesContainer.as(Characteristics.CACHE).addComponent(DeprecatedRuleRepositories.class); | |||
servicesContainer.as(Characteristics.CACHE).addComponent(DeprecatedProfiles.class); |