]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10357 add ruleId to BuiltInQProfile#activeRules
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Tue, 30 Jan 2018 17:27:47 +0000 (18:27 +0100)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Thu, 8 Feb 2018 12:41:00 +0000 (13:41 +0100)
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQProfile.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQProfileInsertImpl.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQProfileRepositoryImpl.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/BuiltInQProfileUpdateImpl.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQProfileInsertImplTest.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQProfileRepositoryImplTest.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQProfileRepositoryRule.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/BuiltInQProfileUpdateImplTest.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RegisterQualityProfilesNotificationTest.java

index a60ca1a261cb40d28bcdca932dc8b99d63921607..265971231885e1086180e6b5ea1f9304187af890 100644 (file)
@@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableList;
 import java.util.ArrayList;
 import java.util.List;
 import javax.annotation.concurrent.Immutable;
+import org.sonar.api.rule.RuleKey;
 import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;
 
 /**
@@ -32,7 +33,7 @@ import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;
 public final class BuiltInQProfile {
   private final QProfileName qProfileName;
   private final boolean isDefault;
-  private final List<BuiltInQualityProfilesDefinition.BuiltInActiveRule> activeRules;
+  private final List<ActiveRule> activeRules;
 
   private BuiltInQProfile(Builder builder) {
     this.qProfileName = new QProfileName(builder.language, builder.name);
@@ -56,16 +57,38 @@ public final class BuiltInQProfile {
     return isDefault;
   }
 
-  public List<BuiltInQualityProfilesDefinition.BuiltInActiveRule> getActiveRules() {
+  public List<ActiveRule> getActiveRules() {
     return activeRules;
   }
 
+  static final class ActiveRule {
+    private final int ruleId;
+    private final BuiltInQualityProfilesDefinition.BuiltInActiveRule builtIn;
+
+    ActiveRule(int ruleId, BuiltInQualityProfilesDefinition.BuiltInActiveRule builtIn) {
+      this.ruleId = ruleId;
+      this.builtIn = builtIn;
+    }
+
+    public int getRuleId() {
+      return ruleId;
+    }
+
+    public RuleKey getRuleKey() {
+      return RuleKey.of(builtIn.repoKey(), builtIn.ruleKey());
+    }
+
+    public BuiltInQualityProfilesDefinition.BuiltInActiveRule getBuiltIn() {
+      return builtIn;
+    }
+  }
+
   static final class Builder {
     private String language;
     private String name;
     private boolean declaredDefault;
     private boolean computedDefault;
-    private final List<BuiltInQualityProfilesDefinition.BuiltInActiveRule> activeRules = new ArrayList<>();
+    private final List<ActiveRule> activeRules = new ArrayList<>();
 
     public Builder setLanguage(String language) {
       this.language = language;
@@ -95,8 +118,13 @@ public final class BuiltInQProfile {
       return this;
     }
 
-    Builder addRules(List<BuiltInQualityProfilesDefinition.BuiltInActiveRule> rules) {
-      this.activeRules.addAll(rules);
+    Builder addRule(BuiltInQualityProfilesDefinition.BuiltInActiveRule rule, int ruleId) {
+      this.activeRules.add(new ActiveRule(ruleId, rule));
+      return this;
+    }
+
+    Builder addRule(ActiveRule activeRule) {
+      this.activeRules.add(activeRule);
       return this;
     }
 
index 0ffe5e2b7d8469a15ebf887d72be72e6154e2d93..741e254f3645482c8f71386407c9db6310946005 100644 (file)
@@ -139,8 +139,8 @@ public class BuiltInQProfileInsertImpl implements BuiltInQProfileInsert {
     return dto;
   }
 
-  private ActiveRuleChange insertActiveRule(DbSession dbSession, RulesProfileDto rulesProfileDto, BuiltInQualityProfilesDefinition.BuiltInActiveRule activeRule, long now) {
-    RuleKey ruleKey = RuleKey.of(activeRule.repoKey(), activeRule.ruleKey());
+  private ActiveRuleChange insertActiveRule(DbSession dbSession, RulesProfileDto rulesProfileDto, BuiltInQProfile.ActiveRule activeRule, long now) {
+    RuleKey ruleKey = activeRule.getRuleKey();
     RuleDefinitionDto ruleDefinitionDto = ruleRepository.getDefinition(ruleKey)
       .orElseThrow(() -> new IllegalStateException("RuleDefinition not found for key " + ruleKey));
 
@@ -148,12 +148,12 @@ public class BuiltInQProfileInsertImpl implements BuiltInQProfileInsert {
     dto.setProfileId(rulesProfileDto.getId());
     dto.setRuleId(ruleDefinitionDto.getId());
     dto.setKey(ActiveRuleKey.of(rulesProfileDto, ruleDefinitionDto.getKey()));
-    dto.setSeverity(firstNonNull(activeRule.overriddenSeverity(), ruleDefinitionDto.getSeverityString()));
+    dto.setSeverity(firstNonNull(activeRule.getBuiltIn().overriddenSeverity(), ruleDefinitionDto.getSeverityString()));
     dto.setUpdatedAt(now);
     dto.setCreatedAt(now);
     dbClient.activeRuleDao().insert(dbSession, dto);
 
-    List<ActiveRuleParamDto> paramDtos = insertActiveRuleParams(dbSession, activeRule, ruleKey, dto);
+    List<ActiveRuleParamDto> paramDtos = insertActiveRuleParams(dbSession, activeRule, dto);
 
     ActiveRuleChange change = new ActiveRuleChange(ActiveRuleChange.Type.ACTIVATED, dto, ruleDefinitionDto);
     change.setSeverity(dto.getSeverityString());
@@ -161,12 +161,12 @@ public class BuiltInQProfileInsertImpl implements BuiltInQProfileInsert {
     return change;
   }
 
-  private List<ActiveRuleParamDto> insertActiveRuleParams(DbSession session, BuiltInQualityProfilesDefinition.BuiltInActiveRule activeRule, RuleKey ruleKey,
+  private List<ActiveRuleParamDto> insertActiveRuleParams(DbSession session, BuiltInQProfile.ActiveRule activeRule,
     ActiveRuleDto activeRuleDto) {
-    Map<String, String> valuesByParamKey = activeRule.overriddenParams()
+    Map<String, String> valuesByParamKey = activeRule.getBuiltIn().overriddenParams()
       .stream()
       .collect(MoreCollectors.uniqueIndex(BuiltInQualityProfilesDefinition.OverriddenParam::key, BuiltInQualityProfilesDefinition.OverriddenParam::overriddenValue));
-    return ruleRepository.getRuleParams(ruleKey)
+    return ruleRepository.getRuleParams(activeRule.getRuleKey())
       .stream()
       .map(param -> {
         String activeRuleValue = valuesByParamKey.get(param.getName());
index 07406726ef095e3542b5b145f7a84bb64e963ea5..bb8f4d2ac6ce7744db46cf78ff31ba83cac23d32 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.server.qualityprofile;
 
 import com.google.common.collect.ImmutableList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -29,12 +30,16 @@ import java.util.Set;
 import javax.annotation.Nullable;
 import org.sonar.api.profiles.RulesProfile;
 import org.sonar.api.resources.Languages;
+import org.sonar.api.rule.RuleKey;
 import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;
 import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.BuiltInQualityProfile;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
 import org.sonar.api.utils.log.Profiler;
 import org.sonar.core.util.stream.MoreCollectors;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.rule.RuleDefinitionDto;
 
 import static com.google.common.base.Preconditions.checkState;
 
@@ -42,6 +47,7 @@ public class BuiltInQProfileRepositoryImpl implements BuiltInQProfileRepository
   private static final Logger LOGGER = Loggers.get(BuiltInQProfileRepositoryImpl.class);
   private static final String DEFAULT_PROFILE_NAME = "Sonar way";
 
+  private final DbClient dbClient;
   private final Languages languages;
   private final List<BuiltInQualityProfilesDefinition> definitions;
   private List<BuiltInQProfile> qProfiles;
@@ -49,11 +55,12 @@ public class BuiltInQProfileRepositoryImpl implements BuiltInQProfileRepository
   /**
    * Requires for pico container when no {@link BuiltInQualityProfilesDefinition} is defined at all
    */
-  public BuiltInQProfileRepositoryImpl(Languages languages) {
-    this(languages, new BuiltInQualityProfilesDefinition[0]);
+  public BuiltInQProfileRepositoryImpl(DbClient dbClient, Languages languages) {
+    this(dbClient, languages, new BuiltInQualityProfilesDefinition[0]);
   }
 
-  public BuiltInQProfileRepositoryImpl(Languages languages, BuiltInQualityProfilesDefinition... definitions) {
+  public BuiltInQProfileRepositoryImpl(DbClient dbClient, Languages languages, BuiltInQualityProfilesDefinition... definitions) {
+    this.dbClient = dbClient;
     this.languages = languages;
     this.definitions = ImmutableList.copyOf(definitions);
   }
@@ -98,18 +105,29 @@ public class BuiltInQProfileRepositoryImpl implements BuiltInQProfileRepository
     return profilesByLanguageAndName;
   }
 
-  private static List<BuiltInQProfile> toFlatList(Map<String, Map<String, BuiltInQualityProfile>> rulesProfilesByLanguage) {
-    Map<String, List<BuiltInQProfile.Builder>> buildersByLanguage = rulesProfilesByLanguage
-      .entrySet()
-      .stream()
-      .collect(MoreCollectors.uniqueIndex(Map.Entry::getKey, BuiltInQProfileRepositoryImpl::toQualityProfileBuilders));
-    return buildersByLanguage
-      .entrySet()
-      .stream()
-      .filter(BuiltInQProfileRepositoryImpl::ensureAtMostOneDeclaredDefault)
-      .map(entry -> toQualityProfiles(entry.getValue()))
-      .flatMap(Collection::stream)
-      .collect(MoreCollectors.toList());
+  private List<BuiltInQProfile> toFlatList(Map<String, Map<String, BuiltInQualityProfile>> rulesProfilesByLanguage) {
+    if (rulesProfilesByLanguage.isEmpty()) {
+      return Collections.emptyList();
+    }
+
+    try (DbSession dbSession = dbClient.openSession(false)) {
+      Map<RuleKey, RuleDefinitionDto> rulesByRuleKey = dbClient.ruleDao().selectAllDefinitions(dbSession)
+        .stream()
+        .collect(MoreCollectors.uniqueIndex(RuleDefinitionDto::getKey));
+      Map<String, List<BuiltInQProfile.Builder>> buildersByLanguage = rulesProfilesByLanguage
+        .entrySet()
+        .stream()
+        .collect(MoreCollectors.uniqueIndex(
+          Map.Entry::getKey,
+          rulesProfilesByLanguageAndName -> toQualityProfileBuilders(rulesProfilesByLanguageAndName, rulesByRuleKey)));
+      return buildersByLanguage
+        .entrySet()
+        .stream()
+        .filter(BuiltInQProfileRepositoryImpl::ensureAtMostOneDeclaredDefault)
+        .map(entry -> toQualityProfiles(entry.getValue()))
+        .flatMap(Collection::stream)
+        .collect(MoreCollectors.toList());
+    }
   }
 
   /**
@@ -124,14 +142,15 @@ public class BuiltInQProfileRepositoryImpl implements BuiltInQProfileRepository
    *       RulesProfile with a given name</li>
    * </ul>
    */
-  private static List<BuiltInQProfile.Builder> toQualityProfileBuilders(Map.Entry<String, Map<String, BuiltInQualityProfile>> rulesProfilesByLanguageAndName) {
+  private static List<BuiltInQProfile.Builder> toQualityProfileBuilders(Map.Entry<String, Map<String, BuiltInQualityProfile>> rulesProfilesByLanguageAndName,
+    Map<RuleKey, RuleDefinitionDto> rulesByRuleKey) {
     String language = rulesProfilesByLanguageAndName.getKey();
     // use a LinkedHashMap to keep order of insertion of RulesProfiles
     Map<String, BuiltInQProfile.Builder> qualityProfileBuildersByName = new LinkedHashMap<>();
     for (BuiltInQualityProfile builtInProfile : rulesProfilesByLanguageAndName.getValue().values()) {
       qualityProfileBuildersByName.compute(
         builtInProfile.name(),
-        (name, existingBuilder) -> updateOrCreateBuilder(language, existingBuilder, builtInProfile));
+        (name, existingBuilder) -> updateOrCreateBuilder(language, existingBuilder, builtInProfile, rulesByRuleKey));
     }
     return ImmutableList.copyOf(qualityProfileBuildersByName.values());
   }
@@ -148,16 +167,26 @@ public class BuiltInQProfileRepositoryImpl implements BuiltInQProfileRepository
     return true;
   }
 
-  private static BuiltInQProfile.Builder updateOrCreateBuilder(String language, @Nullable BuiltInQProfile.Builder existingBuilder, BuiltInQualityProfile builtInProfile) {
-    BuiltInQProfile.Builder builder = existingBuilder;
-    if (builder == null) {
-      builder = new BuiltInQProfile.Builder()
+  private static BuiltInQProfile.Builder updateOrCreateBuilder(String language, @Nullable BuiltInQProfile.Builder existingBuilder, BuiltInQualityProfile builtInProfile,
+    Map<RuleKey, RuleDefinitionDto> rulesByRuleKey) {
+    BuiltInQProfile.Builder builder = createOrReuseBuilder(existingBuilder, language, builtInProfile);
+    builder.setDeclaredDefault(builtInProfile.isDefault());
+    builtInProfile.rules().forEach(builtInActiveRule -> {
+      RuleKey ruleKey = RuleKey.of(builtInActiveRule.repoKey(), builtInActiveRule.ruleKey());
+      RuleDefinitionDto ruleDefinition = rulesByRuleKey.get(ruleKey);
+      checkState(ruleDefinition != null, "Rule with key '%s' not found", ruleKey);
+      builder.addRule(builtInActiveRule, ruleDefinition.getId());
+    });
+    return builder;
+  }
+
+  private static BuiltInQProfile.Builder createOrReuseBuilder(@Nullable BuiltInQProfile.Builder existingBuilder, String language, BuiltInQualityProfile builtInProfile) {
+    if (existingBuilder == null) {
+      return new BuiltInQProfile.Builder()
         .setLanguage(language)
         .setName(builtInProfile.name());
     }
-    return builder
-      .setDeclaredDefault(builtInProfile.isDefault())
-      .addRules(builtInProfile.rules());
+    return existingBuilder;
   }
 
   private static List<BuiltInQProfile> toQualityProfiles(List<BuiltInQProfile.Builder> builders) {
index 9e77286eaab92db5b63e2039c5fd1f319d70051a..044ace3cc9ba0f28cd114f37e48079aa1a6ec25f 100644 (file)
@@ -27,13 +27,11 @@ import java.util.Set;
 import java.util.stream.Stream;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;
-import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.BuiltInActiveRule;
 import org.sonar.core.util.stream.MoreCollectors;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.qualityprofile.ActiveRuleDto;
 import org.sonar.db.qualityprofile.RulesProfileDto;
-import org.sonar.db.rule.RuleDefinitionDto;
 import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
 
 import static org.sonar.core.util.stream.MoreCollectors.toSet;
@@ -59,13 +57,13 @@ public class BuiltInQProfileUpdateImpl implements BuiltInQProfileUpdate {
 
     Set<RuleKey> ruleKeys = Stream.concat(
       deactivatedKeys.stream(),
-      builtIn.getActiveRules().stream().map(ar -> RuleKey.of(ar.repoKey(), ar.ruleKey())))
+      builtIn.getActiveRules().stream().map(BuiltInQProfile.ActiveRule::getRuleKey))
       .collect(toSet());
     RuleActivationContext context = ruleActivator.createContextForBuiltInProfile(dbSession, rulesProfile, ruleKeys);
 
     Collection<RuleActivation> activations = new ArrayList<>();
-    for (BuiltInActiveRule ar : builtIn.getActiveRules()) {
-      RuleActivation activation = convert(ar, context);
+    for (BuiltInQProfile.ActiveRule ar : builtIn.getActiveRules()) {
+      RuleActivation activation = convert(ar);
       activations.add(activation);
       deactivatedKeys.remove(activation.getRuleKey());
     }
@@ -82,13 +80,10 @@ public class BuiltInQProfileUpdateImpl implements BuiltInQProfileUpdate {
     return changes;
   }
 
-  private static RuleActivation convert(BuiltInActiveRule ar, RuleActivationContext context) {
-    RuleKey ruleKey = RuleKey.of(ar.repoKey(), ar.ruleKey());
-    context.reset(ruleKey);
-    RuleDefinitionDto ruleDefinition = context.getRule().get();
-    Map<String, String> params = ar.overriddenParams().stream()
+  private static RuleActivation convert(BuiltInQProfile.ActiveRule ar) {
+    Map<String, String> params = ar.getBuiltIn().overriddenParams().stream()
       .collect(MoreCollectors.uniqueIndex(BuiltInQualityProfilesDefinition.OverriddenParam::key, BuiltInQualityProfilesDefinition.OverriddenParam::overriddenValue));
-    return RuleActivation.create(ruleDefinition.getId(), ruleKey, ar.overriddenSeverity(), params);
+    return RuleActivation.create(ar.getRuleId(), ar.getRuleKey(), ar.getBuiltIn().overriddenSeverity(), params);
   }
 
 }
index f818a5c56682776c38d1260c1d8d8c80ac3c2508..f2a2081b53f9771816c2a88bced78850e5a8eafd 100644 (file)
@@ -108,7 +108,7 @@ public class BuiltInQProfileInsertImplTest {
     newQp.activateRule(rule2.getRepositoryKey(), rule2.getRuleKey()).overrideSeverity(Severity.MAJOR);
     newQp.done();
 
-    BuiltInQProfile builtIn = builtInQProfileRepository.create(context.profile("xoo", "the name"));
+    BuiltInQProfile builtIn = builtInQProfileRepository.create(context.profile("xoo", "the name"), rule1, rule2);
     call(builtIn);
 
     verifyTableSize("rules_profiles", 1);
index 8e731f1debf87ca0e3ce7ef6cc99bb3cddbc7e28..0d1a96835f9e67d1f962848e4a0d482dd352862e 100644 (file)
@@ -28,11 +28,15 @@ import org.junit.rules.ExpectedException;
 import org.sonar.api.resources.Language;
 import org.sonar.api.resources.Languages;
 import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbTester;
 import org.sonar.server.language.LanguageTesting;
 
 import static java.util.Arrays.asList;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.groups.Tuple.tuple;
+import static org.mockito.Mockito.mock;
 
 public class BuiltInQProfileRepositoryImplTest {
   private static final Language FOO_LANGUAGE = LanguageTesting.newLanguage("foo", "foo", "foo");
@@ -40,10 +44,14 @@ public class BuiltInQProfileRepositoryImplTest {
 
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
+  @Rule
+  public DbTester dbTester = DbTester.create(System2.INSTANCE);
+
+  private DbClient dbClient = dbTester.getDbClient();
 
   @Test
   public void get_throws_ISE_if_called_before_initialize() {
-    BuiltInQProfileRepositoryImpl underTest = new BuiltInQProfileRepositoryImpl(new Languages());
+    BuiltInQProfileRepositoryImpl underTest = new BuiltInQProfileRepositoryImpl(mock(DbClient.class), new Languages());
 
     expectedException.expect(IllegalStateException.class);
     expectedException.expectMessage("initialize must be called first");
@@ -53,7 +61,7 @@ public class BuiltInQProfileRepositoryImplTest {
 
   @Test
   public void initialize_throws_ISE_if_called_twice() {
-    BuiltInQProfileRepositoryImpl underTest = new BuiltInQProfileRepositoryImpl(new Languages());
+    BuiltInQProfileRepositoryImpl underTest = new BuiltInQProfileRepositoryImpl(mock(DbClient.class), new Languages());
     underTest.initialize();
 
     expectedException.expect(IllegalStateException.class);
@@ -64,7 +72,7 @@ public class BuiltInQProfileRepositoryImplTest {
 
   @Test
   public void initialize_creates_no_BuiltInQProfile_when_there_is_no_definition() {
-    BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(new Languages(FOO_LANGUAGE));
+    BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(mock(DbClient.class), new Languages(FOO_LANGUAGE));
 
     underTest.initialize();
 
@@ -73,7 +81,7 @@ public class BuiltInQProfileRepositoryImplTest {
 
   @Test
   public void initialize_creates_no_BuiltInQProfile_when_all_definitions_apply_to_non_defined_languages() {
-    BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(new Languages(), new DummyProfileDefinition("foo", "P1", false));
+    BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(mock(DbClient.class), new Languages(), new DummyProfileDefinition("foo", "P1", false));
 
     underTest.initialize();
 
@@ -82,7 +90,7 @@ public class BuiltInQProfileRepositoryImplTest {
 
   @Test
   public void initialize_makes_single_profile_of_a_language_default_even_if_not_flagged_as_so() {
-    BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(new Languages(FOO_LANGUAGE), new DummyProfileDefinition("foo", "foo1", false));
+    BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(dbClient, new Languages(FOO_LANGUAGE), new DummyProfileDefinition("foo", "foo1", false));
 
     underTest.initialize();
 
@@ -93,7 +101,7 @@ public class BuiltInQProfileRepositoryImplTest {
 
   @Test
   public void initialize_makes_single_profile_of_a_language_default_even_if_flagged_as_so() {
-    BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(new Languages(FOO_LANGUAGE), new DummyProfileDefinition("foo", "foo1", true));
+    BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(dbClient, new Languages(FOO_LANGUAGE), new DummyProfileDefinition("foo", "foo1", true));
 
     underTest.initialize();
 
@@ -109,7 +117,7 @@ public class BuiltInQProfileRepositoryImplTest {
     Collections.shuffle(definitions);
     String firstName = definitions.get(0).getName();
     String secondName = definitions.get(1).getName();
-    BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(new Languages(FOO_LANGUAGE), definitions.toArray(new BuiltInQualityProfilesDefinition[0]));
+    BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(dbClient, new Languages(FOO_LANGUAGE), definitions.toArray(new BuiltInQualityProfilesDefinition[0]));
 
     underTest.initialize();
 
@@ -120,7 +128,7 @@ public class BuiltInQProfileRepositoryImplTest {
 
   @Test
   public void initialize_fails_with_ISE_when_two_profiles_with_different_name_are_default_for_the_same_language() {
-    BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(new Languages(FOO_LANGUAGE),
+    BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(dbClient, new Languages(FOO_LANGUAGE),
       new DummyProfileDefinition("foo", "foo1", true), new DummyProfileDefinition("foo", "foo2", true));
 
     expectedException.expect(IllegalStateException.class);
@@ -132,7 +140,7 @@ public class BuiltInQProfileRepositoryImplTest {
   @Test
   public void initialize_creates_profile_Sonar_Way_as_default_if_none_other_is_defined_default_for_a_given_language() {
     BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(
-      new Languages(FOO_LANGUAGE),
+      dbClient, new Languages(FOO_LANGUAGE),
       new DummyProfileDefinition("foo", "doh", false), new DummyProfileDefinition("foo", "boo", false),
       new DummyProfileDefinition("foo", SONAR_WAY_QP_NAME, false), new DummyProfileDefinition("foo", "goo", false));
 
@@ -148,7 +156,7 @@ public class BuiltInQProfileRepositoryImplTest {
   @Test
   public void initialize_does_not_create_Sonar_Way_as_default_if_other_profile_is_defined_as_default() {
     BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(
-      new Languages(FOO_LANGUAGE),
+      dbClient, new Languages(FOO_LANGUAGE),
       new DummyProfileDefinition("foo", SONAR_WAY_QP_NAME, false), new DummyProfileDefinition("foo", "goo", true));
 
     underTest.initialize();
@@ -164,7 +172,7 @@ public class BuiltInQProfileRepositoryImplTest {
   public void initialize_matches_Sonar_Way_default_with_case_sensitivity() {
     String sonarWayInOtherCase = SONAR_WAY_QP_NAME.toUpperCase();
     BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(
-      new Languages(FOO_LANGUAGE),
+      dbClient, new Languages(FOO_LANGUAGE),
       new DummyProfileDefinition("foo", "goo", false), new DummyProfileDefinition("foo", sonarWayInOtherCase, false));
 
     underTest.initialize();
index 34474b42adf160ae207be808c3828352286ee839..2f4a3661533d7c7ec9576640c6044e5b5c544302 100644 (file)
  */
 package org.sonar.server.qualityprofile;
 
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 import org.junit.rules.ExternalResource;
 import org.sonar.api.resources.Language;
+import org.sonar.api.rule.RuleKey;
 import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;
+import org.sonar.core.util.stream.MoreCollectors;
+import org.sonar.db.rule.RuleDefinitionDto;
 
 import static com.google.common.base.Preconditions.checkState;
 
@@ -60,27 +65,39 @@ public class BuiltInQProfileRepositoryRule extends ExternalResource implements B
     return add(language, profileName, false);
   }
 
-  public BuiltInQProfile add(Language language, String profileName, boolean isDefault, BuiltInQualityProfilesDefinition.BuiltInActiveRule... rules) {
+  public BuiltInQProfile add(Language language, String profileName, boolean isDefault) {
+    return add(language, profileName, isDefault, new BuiltInQProfile.ActiveRule[0]);
+  }
+
+  public BuiltInQProfile add(Language language, String profileName, boolean isDefault, BuiltInQProfile.ActiveRule... rules) {
     BuiltInQProfile builtIn = create(language, profileName, isDefault, rules);
     profiles.add(builtIn);
     return builtIn;
   }
 
-  public BuiltInQProfile create(Language language, String profileName, boolean isDefault, BuiltInQualityProfilesDefinition.BuiltInActiveRule... rules) {
-    return new BuiltInQProfile.Builder()
+  public BuiltInQProfile create(Language language, String profileName, boolean isDefault, BuiltInQProfile.ActiveRule... rules) {
+    BuiltInQProfile.Builder builder = new BuiltInQProfile.Builder()
       .setLanguage(language.getKey())
       .setName(profileName)
-      .setDeclaredDefault(isDefault)
-      .addRules(Arrays.asList(rules))
-      .build();
+      .setDeclaredDefault(isDefault);
+    Arrays.stream(rules).forEach(builder::addRule);
+    return builder.build();
   }
 
-  public BuiltInQProfile create(BuiltInQualityProfilesDefinition.BuiltInQualityProfile api) {
-    return new BuiltInQProfile.Builder()
+  public BuiltInQProfile create(BuiltInQualityProfilesDefinition.BuiltInQualityProfile api, RuleDefinitionDto... rules) {
+    BuiltInQProfile.Builder builder = new BuiltInQProfile.Builder()
       .setLanguage(api.language())
       .setName(api.name())
-      .setDeclaredDefault(api.isDefault())
-      .addRules(new ArrayList<>(api.rules()))
+      .setDeclaredDefault(api.isDefault());
+    Map<RuleKey, RuleDefinitionDto> rulesByRuleKey = Arrays.stream(rules)
+      .collect(MoreCollectors.uniqueIndex(RuleDefinitionDto::getKey));
+    api.rules().forEach(rule -> {
+      RuleKey ruleKey = RuleKey.of(rule.repoKey(), rule.ruleKey());
+      RuleDefinitionDto ruleDefinition = rulesByRuleKey.get(ruleKey);
+      Preconditions.checkState(ruleDefinition != null, "Rule '%s' not found", ruleKey);
+      builder.addRule(rule, ruleDefinition.getId());
+    });
+    return builder
       .build();
   }
 }
index b966d46665ad477d281838cb93675a33b25fda61..81c9a6717b3f12bdbe85a67a44ecc0d08101f9fd 100644 (file)
@@ -87,7 +87,7 @@ public class BuiltInQProfileUpdateImplTest {
     newQp.activateRule(rule1.getRepositoryKey(), rule1.getRuleKey()).overrideSeverity(Severity.CRITICAL);
     newQp.activateRule(rule2.getRepositoryKey(), rule2.getRuleKey()).overrideSeverity(Severity.MAJOR);
     newQp.done();
-    BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile("xoo", "Sonar way"));
+    BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile("xoo", "Sonar way"), rule1, rule2);
 
     underTest.update(db.getSession(), builtIn, persistedProfile);
 
@@ -105,7 +105,7 @@ public class BuiltInQProfileUpdateImplTest {
     NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile("Sonar way", "xoo");
     newQp.activateRule(rule.getRepositoryKey(), rule.getRuleKey()).overrideSeverity(Severity.CRITICAL);
     newQp.done();
-    BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile("xoo", "Sonar way"));
+    BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile("xoo", "Sonar way"), rule);
 
     activateRuleInDb(persistedProfile, rule, BLOCKER);
 
@@ -124,7 +124,7 @@ public class BuiltInQProfileUpdateImplTest {
     NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile("Sonar way", "xoo");
     newQp.activateRule(rule.getRepositoryKey(), rule.getRuleKey()).overrideSeverity(Severity.CRITICAL);
     newQp.done();
-    BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile("xoo", "Sonar way"));
+    BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile("xoo", "Sonar way"), rule);
 
     activateRuleInDb(persistedProfile, rule, CRITICAL);
 
@@ -144,7 +144,7 @@ public class BuiltInQProfileUpdateImplTest {
     NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile("Sonar way", "xoo");
     newQp.activateRule(rule2.getRepositoryKey(), rule2.getRuleKey()).overrideSeverity(Severity.MAJOR);
     newQp.done();
-    BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile("xoo", "Sonar way"));
+    BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile("xoo", "Sonar way"), rule1, rule2);
 
     // built-in definition contains only rule2
     // so rule1 must be deactivated
@@ -169,7 +169,7 @@ public class BuiltInQProfileUpdateImplTest {
     newQp.activateRule(rule1.getRepositoryKey(), rule1.getRuleKey()).overrideSeverity(Severity.CRITICAL);
     newQp.activateRule(rule2.getRepositoryKey(), rule2.getRuleKey()).overrideSeverity(Severity.MAJOR);
     newQp.done();
-    BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile("xoo", "Sonar way"));
+    BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile("xoo", "Sonar way"), rule1, rule2);
 
     // rule1 must be updated (blocker to critical)
     // rule2 must be activated
index cc2983410bfbc72a8f705ba74aac00ca0820c840..b67057e584fbbca1b08a048ff61132113a4faf8d 100644 (file)
@@ -22,12 +22,15 @@ package org.sonar.server.qualityprofile;
 import com.google.common.collect.Multimap;
 import java.security.SecureRandom;
 import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
 import java.util.Random;
 import java.util.function.Consumer;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.mockito.ArgumentCaptor;
+import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.rules.RulePriority;
 import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;
@@ -36,6 +39,7 @@ import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.NewBuiltInQ
 import org.sonar.api.utils.System2;
 import org.sonar.api.utils.log.LogTester;
 import org.sonar.core.util.UuidFactoryFast;
+import org.sonar.core.util.stream.MoreCollectors;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbTester;
 import org.sonar.db.organization.OrganizationDto;
@@ -48,6 +52,7 @@ import org.sonar.server.rule.index.RuleIndex;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.util.TypeValidations;
 
+import static com.google.common.base.Preconditions.checkState;
 import static java.util.Collections.singleton;
 import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
 import static org.apache.commons.lang.math.RandomUtils.nextLong;
@@ -303,8 +308,21 @@ public class RegisterQualityProfilesNotificationTest {
 
     Arrays.stream(dbRules).forEach(dbRule -> newQp.activateRule(dbRule.getRepositoryKey(), dbRule.getRuleKey()).overrideSeverity(Severity.MAJOR));
     newQp.done();
-    builtInQProfileRepositoryRule.add(newLanguage(dbProfile.getLanguage()), dbProfile.getName(), false,
-      context.profile(dbProfile.getLanguage(), dbProfile.getName()).rules().toArray(new BuiltInActiveRule[0]));
+    List<BuiltInActiveRule> rules = context.profile(dbProfile.getLanguage(), dbProfile.getName()).rules();
+    BuiltInQProfile.ActiveRule[] activeRules = toActiveRules(rules, dbRules);
+    builtInQProfileRepositoryRule.add(newLanguage(dbProfile.getLanguage()), dbProfile.getName(), false, activeRules);
+  }
+
+  private static BuiltInQProfile.ActiveRule[] toActiveRules(List<BuiltInActiveRule> rules, RuleDefinitionDto[] dbRules) {
+    Map<RuleKey, RuleDefinitionDto> dbRulesByRuleKey = Arrays.stream(dbRules)
+      .collect(MoreCollectors.uniqueIndex(RuleDefinitionDto::getKey));
+    return rules.stream()
+      .map(r -> {
+        RuleKey ruleKey = RuleKey.of(r.repoKey(), r.ruleKey());
+        RuleDefinitionDto ruleDefinitionDto = dbRulesByRuleKey.get(ruleKey);
+        checkState(ruleDefinitionDto != null, "Rule '%s' not found", ruleKey);
+        return new BuiltInQProfile.ActiveRule(ruleDefinitionDto.getId(), r);
+      }).toArray(BuiltInQProfile.ActiveRule[]::new);
   }
 
   private void addPluginProfile(QProfileDto profile, RuleDefinitionDto... dbRules) {
@@ -313,8 +331,8 @@ public class RegisterQualityProfilesNotificationTest {
 
     Arrays.stream(dbRules).forEach(dbRule -> newQp.activateRule(dbRule.getRepositoryKey(), dbRule.getRuleKey()).overrideSeverity(Severity.MAJOR));
     newQp.done();
-    builtInQProfileRepositoryRule.add(newLanguage(profile.getLanguage()), profile.getName(), false,
-      context.profile(profile.getLanguage(), profile.getName()).rules().toArray(new BuiltInActiveRule[0]));
+    BuiltInQProfile.ActiveRule[] activeRules = toActiveRules(context.profile(profile.getLanguage(), profile.getName()).rules(), dbRules);
+    builtInQProfileRepositoryRule.add(newLanguage(profile.getLanguage()), profile.getName(), false, activeRules);
   }
 
   private RulesProfileDto insertBuiltInProfile(String language) {