diff options
Diffstat (limited to 'sonar-plugin-api')
8 files changed, 240 insertions, 73 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/ActiveRule.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/ActiveRule.java index a8b3bfbef0d..10290172790 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/ActiveRule.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/ActiveRule.java @@ -71,4 +71,5 @@ public interface ActiveRule { */ @CheckForNull String templateRuleKey(); + } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/ActiveRulesBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/ActiveRulesBuilder.java index 1353b531d0d..ddabf43b7eb 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/ActiveRulesBuilder.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/ActiveRulesBuilder.java @@ -35,15 +35,12 @@ public class ActiveRulesBuilder { private final Map<RuleKey, NewActiveRule> map = new LinkedHashMap<>(); - public NewActiveRule create(RuleKey ruleKey) { - return new NewActiveRule(this, ruleKey); - } - - void activate(NewActiveRule newActiveRule) { + public ActiveRulesBuilder addRule(NewActiveRule newActiveRule) { if (map.containsKey(newActiveRule.ruleKey)) { throw new IllegalStateException(String.format("Rule '%s' is already activated", newActiveRule.ruleKey)); } map.put(newActiveRule.ruleKey, newActiveRule); + return this; } public ActiveRules build() { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultActiveRule.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultActiveRule.java index 36539d4a9de..9133b24e8e7 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultActiveRule.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/DefaultActiveRule.java @@ -35,6 +35,7 @@ public class DefaultActiveRule implements ActiveRule { private final String templateRuleKey; private final Map<String, String> params; private final long createdAt; + private final long updatedAt; DefaultActiveRule(NewActiveRule newActiveRule) { this.severity = newActiveRule.severity; @@ -44,6 +45,7 @@ public class DefaultActiveRule implements ActiveRule { this.params = Collections.unmodifiableMap(new HashMap<>(newActiveRule.params)); this.language = newActiveRule.language; this.createdAt = newActiveRule.createdAt; + this.updatedAt = newActiveRule.updatedAt; } @Override @@ -85,4 +87,8 @@ public class DefaultActiveRule implements ActiveRule { public long createdAt() { return createdAt; } + + public long updatedAt() { + return updatedAt; + } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/NewActiveRule.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/NewActiveRule.java index 851953c70a0..ab6add0e14b 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/NewActiveRule.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/rule/internal/NewActiveRule.java @@ -22,6 +22,7 @@ package org.sonar.api.batch.rule.internal; import java.util.HashMap; import java.util.Map; import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; import org.apache.commons.lang.StringUtils; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.Severity; @@ -29,71 +30,93 @@ import org.sonar.api.rule.Severity; /** * @since 4.2 */ +@Immutable public class NewActiveRule { final RuleKey ruleKey; - String name; - String severity = Severity.defaultSeverity(); - Map<String, String> params = new HashMap<>(); - long createdAt; - String internalKey; - String language; - String templateRuleKey; - private final ActiveRulesBuilder builder; + final String name; + final String severity; + final Map<String, String> params; + final long createdAt; + final long updatedAt; + final String internalKey; + final String language; + final String templateRuleKey; - NewActiveRule(ActiveRulesBuilder builder, RuleKey ruleKey) { - this.builder = builder; - this.ruleKey = ruleKey; + NewActiveRule(Builder builder) { + this.ruleKey = builder.ruleKey; + this.name = builder.name; + this.severity = builder.severity; + this.params = builder.params; + this.createdAt = builder.createdAt; + this.updatedAt = builder.updatedAt; + this.internalKey = builder.internalKey; + this.language = builder.language; + this.templateRuleKey = builder.templateRuleKey; } - public NewActiveRule setName(String name) { - this.name = name; - return this; - } + public static class Builder { + private RuleKey ruleKey; + private String name; + private String severity = Severity.defaultSeverity(); + private Map<String, String> params = new HashMap<>(); + private long createdAt; + private long updatedAt; + private String internalKey; + private String language; + private String templateRuleKey; - public NewActiveRule setSeverity(@Nullable String severity) { - this.severity = StringUtils.defaultIfBlank(severity, Severity.defaultSeverity()); - return this; - } + public Builder setRuleKey(RuleKey ruleKey) { + this.ruleKey = ruleKey; + return this; + } - public NewActiveRule setInternalKey(@Nullable String internalKey) { - this.internalKey = internalKey; - return this; - } + public Builder setName(String name) { + this.name = name; + return this; + } - public NewActiveRule setTemplateRuleKey(@Nullable String templateRuleKey) { - this.templateRuleKey = templateRuleKey; - return this; - } + public Builder setSeverity(@Nullable String severity) { + this.severity = StringUtils.defaultIfBlank(severity, Severity.defaultSeverity()); + return this; + } - public NewActiveRule setLanguage(@Nullable String language) { - this.language = language; - return this; - } + public Builder setParam(String key, @Nullable String value) { + // possible improvement : check that the param key exists in rule definition + if (value == null) { + params.remove(key); + } else { + params.put(key, value); + } + return this; + } - public NewActiveRule setParam(String key, @Nullable String value) { - // possible improvement : check that the param key exists in rule definition - if (value == null) { - params.remove(key); - } else { - params.put(key, value); + public Builder setCreatedAt(long createdAt) { + this.createdAt = createdAt; + return this; } - return this; - } - public Map<String, String> params() { - return params; - } + public Builder setUpdatedAt(long updatedAt) { + this.updatedAt = updatedAt; + return this; + } - public long getCreatedAt() { - return createdAt; - } + public Builder setInternalKey(@Nullable String internalKey) { + this.internalKey = internalKey; + return this; + } - public void setCreatedAt(long createdAt) { - this.createdAt = createdAt; - } + public Builder setLanguage(@Nullable String language) { + this.language = language; + return this; + } + + public Builder setTemplateRuleKey(@Nullable String templateRuleKey) { + this.templateRuleKey = templateRuleKey; + return this; + } - public ActiveRulesBuilder activate() { - builder.activate(this); - return builder; + public NewActiveRule build() { + return new NewActiveRule(this); + } } } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckFactoryTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckFactoryTest.java index ab1b7a1ac8b..a67603a568e 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckFactoryTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/CheckFactoryTest.java @@ -22,6 +22,7 @@ package org.sonar.api.batch.rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; +import org.sonar.api.batch.rule.internal.NewActiveRule; import org.sonar.api.rule.RuleKey; import org.sonar.api.utils.SonarException; @@ -46,7 +47,10 @@ public class CheckFactoryTest { @Test public void class_name_as_check_key() { RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithoutProperties"); - builder.create(ruleKey).activate(); + NewActiveRule rule = new NewActiveRule.Builder() + .setRuleKey(ruleKey) + .build(); + builder.addRule(rule); CheckFactory checkFactory = new CheckFactory(builder.build()); Checks checks = checkFactory.create("squid").addAnnotatedChecks(CheckWithoutProperties.class); @@ -60,7 +64,11 @@ public class CheckFactoryTest { @Test public void param_as_string_field() { RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithStringProperty"); - builder.create(ruleKey).setParam("pattern", "foo").activate(); + NewActiveRule rule = new NewActiveRule.Builder() + .setRuleKey(ruleKey) + .setParam("pattern", "foo") + .build(); + builder.addRule(rule); CheckFactory checkFactory = new CheckFactory(builder.build()); Checks checks = checkFactory.create("squid").addAnnotatedChecks(CheckWithStringProperty.class); @@ -77,7 +85,11 @@ public class CheckFactoryTest { thrown.expectMessage("The field 'unknown' does not exist or is not annotated with @RuleProperty in the class org.sonar.api.batch.rule.CheckWithStringProperty"); RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithStringProperty"); - builder.create(ruleKey).setParam("unknown", "foo").activate(); + NewActiveRule rule = new NewActiveRule.Builder() + .setRuleKey(ruleKey) + .setParam("unknown", "foo") + .build(); + builder.addRule(rule); CheckFactory checkFactory = new CheckFactory(builder.build()); checkFactory.create("squid").addAnnotatedChecks(CheckWithStringProperty.class); @@ -86,7 +98,12 @@ public class CheckFactoryTest { @Test public void param_as_primitive_fields() { RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithPrimitiveProperties"); - builder.create(ruleKey).setParam("max", "300").setParam("ignore", "true").activate(); + NewActiveRule rule = new NewActiveRule.Builder() + .setRuleKey(ruleKey) + .setParam("max", "300") + .setParam("ignore", "true") + .build(); + builder.addRule(rule); CheckFactory checkFactory = new CheckFactory(builder.build()); Checks checks = checkFactory.create("squid").addAnnotatedChecks(CheckWithPrimitiveProperties.class); @@ -103,7 +120,11 @@ public class CheckFactoryTest { @Test public void param_as_inherited_field() { RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithPrimitiveProperties"); - builder.create(ruleKey).setParam("max", "300").activate(); + NewActiveRule rule = new NewActiveRule.Builder() + .setRuleKey(ruleKey) + .setParam("max", "300") + .build(); + builder.addRule(rule); CheckFactory checkFactory = new CheckFactory(builder.build()); Checks checks = checkFactory.create("squid").addAnnotatedChecks(CheckWithPrimitiveProperties.class); @@ -116,7 +137,11 @@ public class CheckFactoryTest { @Test public void use_template_rule_key() { RuleKey ruleKey = RuleKey.of("squid", "S0001_123"); - builder.create(ruleKey).setTemplateRuleKey("S0001").activate(); + NewActiveRule rule = new NewActiveRule.Builder() + .setRuleKey(ruleKey) + .setTemplateRuleKey("S0001") + .build(); + builder.addRule(rule); CheckFactory checkFactory = new CheckFactory(builder.build()); Checks checks = checkFactory.create("squid").addAnnotatedChecks(CheckWithKey.class); @@ -133,7 +158,11 @@ public class CheckFactoryTest { thrown.expect(SonarException.class); RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithUnsupportedPropertyType"); - builder.create(ruleKey).setParam("max", "300").activate(); + NewActiveRule rule = new NewActiveRule.Builder() + .setRuleKey(ruleKey) + .setParam("max", "300") + .build(); + builder.addRule(rule); CheckFactory checkFactory = new CheckFactory(builder.build()); checkFactory.create("squid").addAnnotatedChecks(CheckWithUnsupportedPropertyType.class); @@ -142,7 +171,11 @@ public class CheckFactoryTest { @Test public void override_field_key() { RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithOverriddenPropertyKey"); - builder.create(ruleKey).setParam("maximum", "300").activate(); + NewActiveRule rule = new NewActiveRule.Builder() + .setRuleKey(ruleKey) + .setParam("maximum", "300") + .build(); + builder.addRule(rule); CheckFactory checkFactory = new CheckFactory(builder.build()); Checks checks = checkFactory.create("squid").addAnnotatedChecks(CheckWithOverriddenPropertyKey.class); @@ -158,7 +191,11 @@ public class CheckFactoryTest { @Test public void checks_as_objects() { RuleKey ruleKey = RuleKey.of("squid", "org.sonar.api.batch.rule.CheckWithStringProperty"); - builder.create(ruleKey).setParam("pattern", "foo").activate(); + NewActiveRule rule = new NewActiveRule.Builder() + .setRuleKey(ruleKey) + .setParam("pattern", "foo") + .build(); + builder.addRule(rule); CheckFactory checkFactory = new CheckFactory(builder.build()); CheckWithStringProperty check = new CheckWithStringProperty(); diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ActiveRulesBuilderTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ActiveRulesBuilderTest.java index 29eca75ed17..3591f59f3af 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ActiveRulesBuilderTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/ActiveRulesBuilderTest.java @@ -42,16 +42,24 @@ public class ActiveRulesBuilderTest { @Test public void build_rules() { - ActiveRules activeRules = new ActiveRulesBuilder() - .create(RuleKey.of("squid", "S0001")) + NewActiveRule activeRule = new NewActiveRule.Builder() + .setRuleKey(RuleKey.of("squid", "S0001")) .setName("My Rule") .setSeverity(Severity.CRITICAL) .setInternalKey("__S0001__") .setParam("min", "20") - .activate() + .build(); + + ActiveRules activeRules = new ActiveRulesBuilder() + .addRule(activeRule) // most simple rule - .create(RuleKey.of("squid", "S0002")).activate() - .create(RuleKey.of("findbugs", "NPE")).setInternalKey(null).setSeverity(null).setParam("foo", null).activate() + .addRule(new NewActiveRule.Builder().setRuleKey(RuleKey.of("squid", "S0002")).build()) + .addRule(new NewActiveRule.Builder() + .setRuleKey(RuleKey.of("findbugs", "NPE")) + .setInternalKey(null) + .setSeverity(null) + .setParam("foo", null) + .build()) .build(); assertThat(activeRules.findAll()).hasSize(3); @@ -83,11 +91,14 @@ public class ActiveRulesBuilderTest { @Test public void fail_to_add_twice_the_same_rule() { ActiveRulesBuilder builder = new ActiveRulesBuilder(); - builder.create(RuleKey.of("squid", "S0001")).activate(); + NewActiveRule rule = new NewActiveRule.Builder() + .setRuleKey(RuleKey.of("squid", "S0001")) + .build(); + builder.addRule(rule); thrown.expect(IllegalStateException.class); thrown.expectMessage("Rule 'squid:S0001' is already activated"); - builder.create(RuleKey.of("squid", "S0001")).activate(); + builder.addRule(rule); } } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/NewActiveRuleTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/NewActiveRuleTest.java new file mode 100644 index 00000000000..4ecbd6e6917 --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/rule/internal/NewActiveRuleTest.java @@ -0,0 +1,85 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program 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. + * + * This program 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 this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.api.batch.rule.internal; + +import com.google.common.collect.ImmutableMap; +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.rule.Severity; + +import static org.assertj.core.api.Assertions.assertThat; + +public class NewActiveRuleTest { + + private NewActiveRule.Builder builder; + + @Before + public void setBuilder() { + builder = new NewActiveRule.Builder(); + } + + @Test + public void builder_should_set_every_param() { + NewActiveRule rule = builder + .setRuleKey(RuleKey.of("foo", "bar")) + .setName("name") + .setSeverity(Severity.CRITICAL) + .setParam("key", "value") + .setCreatedAt(1_000L) + .setUpdatedAt(1_000L) + .setInternalKey("internal_key") + .setLanguage("language") + .setTemplateRuleKey("templateRuleKey") + .build(); + + assertThat(rule.ruleKey).isEqualTo(RuleKey.of("foo", "bar")); + assertThat(rule.name).isEqualTo("name"); + assertThat(rule.severity).isEqualTo(Severity.CRITICAL); + assertThat(rule.params).isEqualTo(ImmutableMap.of("key", "value")); + assertThat(rule.createdAt).isEqualTo(1_000L); + assertThat(rule.updatedAt).isEqualTo(1_000L); + assertThat(rule.internalKey).isEqualTo("internal_key"); + assertThat(rule.language).isEqualTo("language"); + assertThat(rule.templateRuleKey).isEqualTo("templateRuleKey"); + } + + @Test + public void severity_should_have_default_value() { + NewActiveRule rule = builder.build(); + assertThat(rule.severity).isEqualTo(Severity.defaultSeverity()); + } + + @Test + public void params_should_be_empty_map_if_no_params() { + NewActiveRule rule = builder.build(); + assertThat(rule.params).isEqualTo(ImmutableMap.of()); + } + + @Test + public void set_param_remove_param_if_value_is_null() { + NewActiveRule rule = builder + .setParam("foo", "bar") + .setParam("removed", "value") + .setParam("removed", null) + .build(); + assertThat(rule.params).isEqualTo(ImmutableMap.of("foo", "bar")); + } +} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java index a4d659e29f0..3a3aca0fbc7 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java @@ -26,6 +26,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; +import org.mockito.Mockito; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultFileSystem; @@ -36,6 +37,7 @@ import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.rule.Severity; import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; +import org.sonar.api.batch.rule.internal.NewActiveRule; import org.sonar.api.batch.sensor.error.AnalysisError; import org.sonar.api.batch.sensor.error.NewAnalysisError; import org.sonar.api.batch.sensor.highlighting.TypeOfText; @@ -51,6 +53,8 @@ import org.sonar.api.rules.RuleType; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; import static org.assertj.core.data.MapEntry.entry; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class SensorContextTesterTest { @@ -79,7 +83,10 @@ public class SensorContextTesterTest { @Test public void testActiveRules() { - ActiveRules activeRules = new ActiveRulesBuilder().create(RuleKey.of("repo", "rule")).activate().build(); + NewActiveRule activeRule = new NewActiveRule.Builder() + .setRuleKey(RuleKey.of("foo", "bar")) + .build(); + ActiveRules activeRules = new ActiveRulesBuilder().addRule(activeRule).build(); tester.setActiveRules(activeRules); assertThat(tester.activeRules().findAll()).hasSize(1); } |