diff options
author | Simon Brandhof <simon.brandhof@gmail.com> | 2014-03-24 18:01:30 +0100 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@gmail.com> | 2014-03-24 18:48:48 +0100 |
commit | d1c26036280d4513835de01dca1893f652d51413 (patch) | |
tree | 2b8a275baee492b5dcaf523aa42a552f771712f7 /sonar-plugin-api/src | |
parent | de01dbe251f7691a55b0a8720b7260a0e691dcfe (diff) | |
download | sonarqube-d1c26036280d4513835de01dca1893f652d51413.tar.gz sonarqube-d1c26036280d4513835de01dca1893f652d51413.zip |
SONAR-4908 extract RulesDefinitionXmlLoader
Diffstat (limited to 'sonar-plugin-api/src')
7 files changed, 104 insertions, 77 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java index 45650ecf6c0..2bab880020a 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java @@ -20,7 +20,13 @@ package org.sonar.api.server.rule; import com.google.common.base.Strings; -import com.google.common.collect.*; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSortedSet; +import com.google.common.collect.ListMultimap; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.LoggerFactory; @@ -31,10 +37,9 @@ import org.sonar.api.rule.Severity; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; - import java.io.IOException; -import java.io.InputStream; import java.net.URL; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; @@ -107,48 +112,6 @@ public interface RulesDefinition extends ServerExtension { */ NewExtendedRepository loadAnnotatedClasses(Class... classes); - /** - * Reads definitions of rules from a XML file. Format is : - * <pre> - * <rules> - * <rule> - * <!-- required fields --> - * <key>the-rule-key</key> - * <name>The purpose of the rule</name> - * <description> - * <![CDATA[The description]]> - * </description> - * - * <!-- optional fields --> - * <internalKey>Checker/TreeWalker/LocalVariableName</internalKey> - * <severity>BLOCKER</severity> - * <cardinality>MULTIPLE</cardinality> - * <status>BETA</status> - * <param> - * <key>the-param-key</key> - * <tag>style</tag> - * <tag>security</tag> - * <description> - * <![CDATA[ - * the param-description - * ]]> - * </description> - * <defaultValue>42</defaultValue> - * </param> - * <param> - * <key>another-param</key> - * </param> - * - * <!-- deprecated fields --> - * <configKey>Checker/TreeWalker/LocalVariableName</configKey> - * <priority>BLOCKER</priority> - * </rule> - * </rules> - * - * </pre> - */ - NewExtendedRepository loadXml(InputStream xmlInput, String encoding); - void done(); } @@ -157,6 +120,10 @@ public interface RulesDefinition extends ServerExtension { @CheckForNull NewRule rule(String ruleKey); + + Collection<NewRule> rules(); + + String key(); } class NewRepositoryImpl implements NewRepository { @@ -175,6 +142,11 @@ public interface RulesDefinition extends ServerExtension { } @Override + public String key() { + return key; + } + + @Override public NewRepositoryImpl setName(@Nullable String s) { if (StringUtils.isNotEmpty(s)) { this.name = s; @@ -202,6 +174,11 @@ public interface RulesDefinition extends ServerExtension { } @Override + public Collection<NewRule> rules() { + return newRules.values(); + } + + @Override public NewRepositoryImpl loadAnnotatedClasses(Class... classes) { new RuleDefinitionsFromAnnotations().loadRules(this, classes); return this; @@ -213,12 +190,6 @@ public interface RulesDefinition extends ServerExtension { } @Override - public NewRepositoryImpl loadXml(InputStream xmlInput, String encoding) { - new RuleDefinitionsFromXml().loadRules(this, xmlInput, encoding); - return this; - } - - @Override public void done() { // note that some validations can be done here, for example for // verifying that at least one rule is declared @@ -409,6 +380,10 @@ public interface RulesDefinition extends ServerExtension { return paramsByKey.get(paramKey); } + public Collection<NewParam> params() { + return paramsByKey.values(); + } + /** * @see RuleTagFormat */ @@ -589,6 +564,10 @@ public interface RulesDefinition extends ServerExtension { this.key = this.name = key; } + public String key() { + return key; + } + public NewParam setName(@Nullable String s) { // name must never be null. this.name = StringUtils.defaultIfBlank(s, key); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitionsFromXml.java b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinitionXmlLoader.java index 80b9bec7e06..240420d1ee2 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RuleDefinitionsFromXml.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinitionXmlLoader.java @@ -24,13 +24,13 @@ import org.apache.commons.lang.StringUtils; 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.rule.RuleStatus; import org.sonar.api.rule.Severity; import org.sonar.check.Cardinality; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; - import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -39,15 +39,53 @@ import java.util.ArrayList; import java.util.List; /** - * @since 4.2 + * Loads definitions of rules from a XML file. + * + * <h3>XML Format</h3> + * <pre> + * <rules> + * <rule> + * <!-- required fields --> + * <key>the-rule-key</key> + * <name>The purpose of the rule</name> + * + * <!-- optional fields --> + * <description> + * <![CDATA[The description]]> + * </description> + * <internalKey>Checker/TreeWalker/LocalVariableName</internalKey> + * <severity>BLOCKER</severity> + * <cardinality>MULTIPLE</cardinality> + * <status>BETA</status> + * <param> + * <key>the-param-key</key> + * <tag>style</tag> + * <tag>security</tag> + * <description> + * <![CDATA[the param-description]]> + * </description> + * <defaultValue>42</defaultValue> + * </param> + * <param> + * <key>another-param</key> + * </param> + * + * <!-- deprecated fields --> + * <configKey>Checker/TreeWalker/LocalVariableName</configKey> + * <priority>BLOCKER</priority> + * </rule> + * </rules> + * </pre> + * + * @since 4.3 */ -class RuleDefinitionsFromXml { +public class RulesDefinitionXmlLoader implements ServerComponent { - void loadRules(RulesDefinition.NewRepository repo, InputStream input, String encoding) { + public void load(RulesDefinition.NewRepository repo, InputStream input, String encoding) { Reader reader = null; try { reader = new InputStreamReader(input, encoding); - loadRules(repo, reader); + load(repo, reader); } catch (IOException e) { throw new IllegalStateException("Fail to load XML file", e); @@ -57,7 +95,7 @@ class RuleDefinitionsFromXml { } } - void loadRules(RulesDefinition.NewRepository repo, Reader reader) { + public void load(RulesDefinition.NewRepository repo, Reader reader) { XMLInputFactory xmlFactory = XMLInputFactory.newInstance(); xmlFactory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE); xmlFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.FALSE); diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionFromXmlTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest.java index 8be35912749..df6ff3bdc85 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionFromXmlTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest.java @@ -20,35 +20,34 @@ package org.sonar.api.server.rule; import com.google.common.base.Charsets; +import org.apache.commons.io.IOUtils; import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; +import java.io.InputStream; import java.io.UnsupportedEncodingException; import static org.fest.assertions.Assertions.assertThat; -public class RulesDefinitionFromXmlTest { +public class RulesDefinitionXmlLoaderTest { @org.junit.Rule public final ExpectedException thrown = ExpectedException.none(); - private RulesDefinition.Repository load(Reader reader) { + private RulesDefinition.Repository load(InputStream input, String encoding) { RulesDefinition.Context context = new RulesDefinition.Context(); RulesDefinition.NewRepository newRepository = context.createRepository("squid", "java"); - new RuleDefinitionsFromXml().loadRules(newRepository, reader); + new RulesDefinitionXmlLoader().load(newRepository, input, encoding); newRepository.done(); return context.repository("squid"); } @Test - public void should_parse_xml() throws Exception { - InputStreamReader reader = new InputStreamReader(getClass().getResourceAsStream("/org/sonar/api/server/rule/RuleDefinitionsFromXmlTest/rules.xml"), Charsets.UTF_8.name()); - RulesDefinition.Repository repository = load(reader); + public void parse_xml() throws Exception { + InputStream input = getClass().getResourceAsStream("/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest/rules.xml"); + RulesDefinition.Repository repository = load(input, Charsets.UTF_8.name()); assertThat(repository.rules()).hasSize(2); RulesDefinition.Rule rule = repository.rule("complete"); @@ -77,27 +76,36 @@ public class RulesDefinitionFromXmlTest { } @Test - public void should_fail_if_missing_rule_key() { + public void fail_if_missing_rule_key() { thrown.expect(IllegalStateException.class); - load(new StringReader("<rules><rule><name>Foo</name></rule></rules>")); + load(IOUtils.toInputStream("<rules><rule><name>Foo</name></rule></rules>"), Charsets.UTF_8.name()); } @Test - public void should_fail_if_missing_property_key() { + public void fail_if_missing_property_key() { thrown.expect(IllegalStateException.class); - load(new StringReader("<rules><rule><key>foo</key><name>Foo</name><param></param></rule></rules>")); + load(IOUtils.toInputStream("<rules><rule><key>foo</key><name>Foo</name><param></param></rule></rules>"), Charsets.UTF_8.name()); } @Test - public void should_fail_on_invalid_rule_parameter_type() { + public void fail_on_invalid_rule_parameter_type() { thrown.expect(IllegalStateException.class); - load(new StringReader("<rules><rule><key>foo</key><name>Foo</name><param><key>key</key><type>INVALID</type></param></rule></rules>")); + load(IOUtils.toInputStream("<rules><rule><key>foo</key><name>Foo</name><param><key>key</key><type>INVALID</type></param></rule></rules>"), Charsets.UTF_8.name()); + } + + @Test + public void fail_if_invalid_xml() throws UnsupportedEncodingException { + thrown.expect(IllegalStateException.class); + thrown.expectMessage("XML is not valid"); + + InputStream input = getClass().getResourceAsStream("/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest/invalid.xml"); + load(input, Charsets.UTF_8.name()); } @Test public void test_utf8_encoding() throws UnsupportedEncodingException { - InputStreamReader reader = new InputStreamReader(getClass().getResourceAsStream("/org/sonar/api/server/rule/RuleDefinitionsFromXmlTest/utf8.xml"), Charsets.UTF_8.name()); - RulesDefinition.Repository repository = load(reader); + InputStream input = getClass().getResourceAsStream("/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest/utf8.xml"); + RulesDefinition.Repository repository = load(input, Charsets.UTF_8.name()); assertThat(repository.rules()).hasSize(1); RulesDefinition.Rule rule = repository.rules().get(0); @@ -109,10 +117,10 @@ public class RulesDefinitionFromXmlTest { } @Test - public void should_support_deprecated_format() throws UnsupportedEncodingException { + public void support_deprecated_format() throws UnsupportedEncodingException { // the deprecated format uses some attributes instead of nodes - InputStreamReader reader = new InputStreamReader(getClass().getResourceAsStream("/org/sonar/api/server/rule/RuleDefinitionsFromXmlTest/deprecated.xml"), Charsets.UTF_8.name()); - RulesDefinition.Repository repository = load(reader); + InputStream input = getClass().getResourceAsStream("/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest/deprecated.xml"); + RulesDefinition.Repository repository = load(input, Charsets.UTF_8.name()); assertThat(repository.rules()).hasSize(1); RulesDefinition.Rule rule = repository.rules().get(0); diff --git a/sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RuleDefinitionsFromXmlTest/deprecated.xml b/sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest/deprecated.xml index 2938ea70377..2938ea70377 100644 --- a/sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RuleDefinitionsFromXmlTest/deprecated.xml +++ b/sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest/deprecated.xml diff --git a/sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest/invalid.xml b/sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest/invalid.xml new file mode 100644 index 00000000000..de3d00c00aa --- /dev/null +++ b/sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest/invalid.xml @@ -0,0 +1,2 @@ +<rules> + <rule> diff --git a/sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RuleDefinitionsFromXmlTest/rules.xml b/sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest/rules.xml index 28ea7019c6e..28ea7019c6e 100644 --- a/sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RuleDefinitionsFromXmlTest/rules.xml +++ b/sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest/rules.xml diff --git a/sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RuleDefinitionsFromXmlTest/utf8.xml b/sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest/utf8.xml index 6197e030057..6197e030057 100644 --- a/sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RuleDefinitionsFromXmlTest/utf8.xml +++ b/sonar-plugin-api/src/test/resources/org/sonar/api/server/rule/RulesDefinitionXmlLoaderTest/utf8.xml |