void setParent(
      DbSession dbSession, QualityProfileKey key, @Nullable QualityProfileKey parentKey) {
    QualityProfileDto profile = db.qualityProfileDao().getNonNullByKey(dbSession, key);
    if (parentKey == null) {
      // unset if parent is defined, else nothing to do
      removeParent(dbSession, profile);

    } else if (profile.getParentKey() == null || !profile.getParentKey().equals(parentKey)) {
      QualityProfileDto parentProfile =
          db.qualityProfileDao().getNonNullByKey(dbSession, parentKey);
      if (isDescendant(dbSession, profile, parentProfile)) {
        throw new BadRequestException(
            String.format(
                "Descendant profile '%s' can not be selected as parent of '%s'", parentKey, key));
      }
      removeParent(dbSession, profile);

      // set new parent
      profile.setParent(parentKey.name());
      db.qualityProfileDao().update(dbSession, profile);
      for (ActiveRuleDto parentActiveRule :
          db.activeRuleDao().findByProfileKey(dbSession, parentKey)) {
        RuleActivation activation =
            new RuleActivation(ActiveRuleKey.of(key, parentActiveRule.getKey().ruleKey()));
        activate(dbSession, activation);
      }
    }
  }
 /**
  * Deactivate a rule on a Quality profile WITHOUT committing db session, WITHOUT checking
  * permissions, and forcing removal of inherited rules
  */
 public List<ActiveRuleChange> deactivate(DbSession dbSession, RuleDto ruleDto) {
   List<ActiveRuleChange> changes = Lists.newArrayList();
   List<ActiveRuleDto> activeRules = db.activeRuleDao().findByRule(dbSession, ruleDto);
   for (ActiveRuleDto activeRule : activeRules) {
     changes.addAll(deactivate(dbSession, activeRule.getKey(), true));
   }
   return changes;
 }
 /** Does not commit */
 private void removeParent(DbSession dbSession, QualityProfileDto profileDto) {
   if (profileDto.getParent() != null) {
     profileDto.setParent(null);
     db.qualityProfileDao().update(dbSession, profileDto);
     for (ActiveRuleDto activeRule :
         db.activeRuleDao().findByProfileKey(dbSession, profileDto.getKey())) {
       if (ActiveRuleDto.INHERITED.equals(activeRule.getInheritance())) {
         deactivate(dbSession, activeRule.getKey(), true);
       } else if (ActiveRuleDto.OVERRIDES.equals(activeRule.getInheritance())) {
         activeRule.setInheritance(null);
         db.activeRuleDao().update(dbSession, activeRule);
       }
     }
   }
 }
 boolean isSame(ActiveRuleChange change) {
   ActiveRule.Inheritance inheritance = change.getInheritance();
   if (inheritance != null && !inheritance.name().equals(activeRule.getInheritance())) {
     return false;
   }
   String severity = change.getSeverity();
   if (severity != null && !severity.equals(activeRule.getSeverityString())) {
     return false;
   }
   for (Map.Entry<String, String> changeParam : change.getParameters().entrySet()) {
     ActiveRuleParamDto param = activeRuleParams.get(changeParam.getKey());
     if (param != null && !StringUtils.equals(changeParam.getValue(), param.getValue())) {
       return false;
     }
   }
   return true;
 }
  @Test
  public void search_by_profile() throws InterruptedException {
    QualityProfileDto qualityProfileDto1 = QProfileTesting.newXooP1();
    QualityProfileDto qualityProfileDto2 = QProfileTesting.newXooP2();
    db.qualityProfileDao().insert(dbSession, qualityProfileDto1, qualityProfileDto2);

    RuleDto rule1 = RuleTesting.newXooX1();
    RuleDto rule2 = RuleTesting.newXooX2();
    RuleDto rule3 = RuleTesting.newXooX3();
    dao.insert(dbSession, rule1, rule2, rule3);

    db.activeRuleDao()
        .insert(
            dbSession,
            ActiveRuleDto.createFor(qualityProfileDto1, rule1).setSeverity("BLOCKER"),
            ActiveRuleDto.createFor(qualityProfileDto2, rule1).setSeverity("BLOCKER"),
            ActiveRuleDto.createFor(qualityProfileDto1, rule2).setSeverity("BLOCKER"));
    dbSession.commit();
    dbSession.clearCache();

    // 1. get all active rules.
    Result<Rule> result = index.search(new RuleQuery().setActivation(true), new QueryContext());
    assertThat(result.getHits()).hasSize(2);

    // 2. get all inactive rules.
    result = index.search(new RuleQuery().setActivation(false), new QueryContext());
    assertThat(result.getHits()).hasSize(1);
    assertThat(result.getHits().get(0).name()).isEqualTo(rule3.getName());

    // 3. get all rules not active on profile
    index.search(
        new RuleQuery().setActivation(false).setQProfileKey(qualityProfileDto2.getKey()),
        new QueryContext());
    // TODO
    assertThat(result.getHits()).hasSize(1);

    // 4. get all active rules on profile
    result =
        index.search(
            new RuleQuery().setActivation(true).setQProfileKey(qualityProfileDto2.getKey()),
            new QueryContext());
    assertThat(result.getHits()).hasSize(1);
    assertThat(result.getHits().get(0).name()).isEqualTo(rule1.getName());
  }
 /** True if trying to override an inherited rule but with exactly the same values */
 boolean isSameAsParent(ActiveRuleChange change) {
   if (parentActiveRule == null) {
     return false;
   }
   if (!StringUtils.equals(change.getSeverity(), parentActiveRule.getSeverityString())) {
     return false;
   }
   for (Map.Entry<String, String> entry : change.getParameters().entrySet()) {
     if (entry.getValue() != null && !entry.getValue().equals(parentParamValue(entry.getKey()))) {
       return false;
     }
   }
   return true;
 }
  private ActiveRuleDto persist(
      ActiveRuleChange change, RuleActivatorContext context, DbSession dbSession) {
    ActiveRuleDao dao = db.activeRuleDao();
    ActiveRuleDto activeRule = null;
    if (change.getType() == ActiveRuleChange.Type.ACTIVATED) {
      activeRule = ActiveRuleDto.createFor(context.profile(), context.rule());
      activeRule.setSeverity(change.getSeverity());
      if (change.getInheritance() != null) {
        activeRule.setInheritance(change.getInheritance().name());
      }
      dao.insert(dbSession, activeRule);
      for (Map.Entry<String, String> param : change.getParameters().entrySet()) {
        if (param.getValue() != null) {
          ActiveRuleParamDto paramDto =
              ActiveRuleParamDto.createFor(context.ruleParamsByKeys().get(param.getKey()));
          paramDto.setValue(param.getValue());
          dao.addParam(dbSession, activeRule, paramDto);
        }
      }

    } else if (change.getType() == ActiveRuleChange.Type.DEACTIVATED) {
      dao.deleteByKey(dbSession, change.getKey());

    } else if (change.getType() == ActiveRuleChange.Type.UPDATED) {
      activeRule = context.activeRule();
      activeRule.setSeverity(change.getSeverity());
      if (change.getInheritance() != null) {
        activeRule.setInheritance(change.getInheritance().name());
      }
      dao.update(dbSession, activeRule);

      for (Map.Entry<String, String> param : change.getParameters().entrySet()) {
        ActiveRuleParamDto activeRuleParamDto = context.activeRuleParamsAsMap().get(param.getKey());
        if (activeRuleParamDto == null) {
          // did not exist
          if (param.getValue() != null) {
            activeRuleParamDto =
                ActiveRuleParamDto.createFor(context.ruleParamsByKeys().get(param.getKey()));
            activeRuleParamDto.setValue(param.getValue());
            dao.addParam(dbSession, activeRule, activeRuleParamDto);
          }
        } else {
          if (param.getValue() != null) {
            activeRuleParamDto.setValue(param.getValue());
            dao.updateParam(dbSession, activeRule, activeRuleParamDto);
          } else {
            dao.deleteParam(dbSession, activeRule, activeRuleParamDto);
          }
        }
      }
    }

    return activeRule;
  }
 @CheckForNull
 String parentSeverity() {
   return parentActiveRule != null ? parentActiveRule.getSeverityString() : null;
 }
 @CheckForNull
 String currentSeverity() {
   return activeRule != null ? activeRule.getSeverityString() : null;
 }
  @Test
  public void search_by_profile_and_inheritance() throws InterruptedException {
    QualityProfileDto qualityProfileDto1 = QProfileTesting.newXooP1();
    QualityProfileDto qualityProfileDto2 =
        QProfileTesting.newXooP2().setParentKee(QProfileTesting.XOO_P1_KEY);
    db.qualityProfileDao().insert(dbSession, qualityProfileDto1, qualityProfileDto2);

    RuleDto rule1 = RuleTesting.newDto(RuleKey.of("xoo", "S001"));
    RuleDto rule2 = RuleTesting.newDto(RuleKey.of("xoo", "S002"));
    RuleDto rule3 = RuleTesting.newDto(RuleKey.of("xoo", "S003"));
    RuleDto rule4 = RuleTesting.newDto(RuleKey.of("xoo", "S004"));
    dao.insert(dbSession, rule1, rule2, rule3, rule4);

    db.activeRuleDao()
        .insert(
            dbSession,
            ActiveRuleDto.createFor(qualityProfileDto1, rule1).setSeverity("BLOCKER"),
            ActiveRuleDto.createFor(qualityProfileDto1, rule2).setSeverity("BLOCKER"),
            ActiveRuleDto.createFor(qualityProfileDto1, rule3).setSeverity("BLOCKER"),
            ActiveRuleDto.createFor(qualityProfileDto2, rule1)
                .setSeverity("MINOR")
                .setInheritance(ActiveRule.Inheritance.INHERITED.name()),
            ActiveRuleDto.createFor(qualityProfileDto2, rule2)
                .setSeverity("BLOCKER")
                .setInheritance(ActiveRule.Inheritance.OVERRIDES.name()),
            ActiveRuleDto.createFor(qualityProfileDto2, rule3)
                .setSeverity("BLOCKER")
                .setInheritance(ActiveRule.Inheritance.INHERITED.name()));

    dbSession.commit();

    // 0. get all rules
    Result<Rule> result = index.search(new RuleQuery(), new QueryContext());
    assertThat(result.getHits()).hasSize(4);

    // 1. get all active rules
    result = index.search(new RuleQuery().setActivation(true), new QueryContext());
    assertThat(result.getHits()).hasSize(3);

    // 2. get all inactive rules.
    result = index.search(new RuleQuery().setActivation(false), new QueryContext());
    assertThat(result.getHits()).hasSize(1);
    assertThat(result.getHits().get(0).name()).isEqualTo(rule4.getName());

    // 3. get Inherited Rules on profile1
    result =
        index.search(
            new RuleQuery()
                .setActivation(true)
                .setQProfileKey(qualityProfileDto1.getKey())
                .setInheritance(ImmutableSet.of(ActiveRule.Inheritance.INHERITED.name())),
            new QueryContext());
    assertThat(result.getHits()).hasSize(0);

    // 4. get Inherited Rules on profile2
    result =
        index.search(
            new RuleQuery()
                .setActivation(true)
                .setQProfileKey(qualityProfileDto2.getKey())
                .setInheritance(ImmutableSet.of(ActiveRule.Inheritance.INHERITED.name())),
            new QueryContext());
    assertThat(result.getHits()).hasSize(2);

    // 5. get Overridden Rules on profile1
    result =
        index.search(
            new RuleQuery()
                .setActivation(true)
                .setQProfileKey(qualityProfileDto1.getKey())
                .setInheritance(ImmutableSet.of(ActiveRule.Inheritance.OVERRIDES.name())),
            new QueryContext());
    assertThat(result.getHits()).hasSize(0);

    // 6. get Overridden Rules on profile2
    result =
        index.search(
            new RuleQuery()
                .setActivation(true)
                .setQProfileKey(qualityProfileDto2.getKey())
                .setInheritance(ImmutableSet.of(ActiveRule.Inheritance.OVERRIDES.name())),
            new QueryContext());
    assertThat(result.getHits()).hasSize(1);

    // 7. get Inherited AND Overridden Rules on profile1
    result =
        index.search(
            new RuleQuery()
                .setActivation(true)
                .setQProfileKey(qualityProfileDto1.getKey())
                .setInheritance(
                    ImmutableSet.of(
                        ActiveRule.Inheritance.INHERITED.name(),
                        ActiveRule.Inheritance.OVERRIDES.name())),
            new QueryContext());
    assertThat(result.getHits()).hasSize(0);

    // 8. get Inherited AND Overridden Rules on profile2
    result =
        index.search(
            new RuleQuery()
                .setActivation(true)
                .setQProfileKey(qualityProfileDto2.getKey())
                .setInheritance(
                    ImmutableSet.of(
                        ActiveRule.Inheritance.INHERITED.name(),
                        ActiveRule.Inheritance.OVERRIDES.name())),
            new QueryContext());
    assertThat(result.getHits()).hasSize(3);
  }
  @Override
  public ProjectReferentials load(ProjectReactor reactor, Settings settings, Languages languages) {
    ProjectReferentials ref = new ProjectReferentials();

    String defaultName = settings.getString(ModuleQProfiles.SONAR_PROFILE_PROP);

    for (Language language : languages.all()) {
      org.sonar.batch.protocol.input.QProfile profile = null;
      if (StringUtils.isNotBlank(defaultName)) {
        profile = loadDefaultQProfile(defaultName, language.getKey());
      }
      if (profile == null) {
        profile = loadQProfile(settings, language.getKey());
      }
      if (profile != null) {
        ref.addQProfile(profile);
      }
    }

    for (QProfile qProfile : ref.qProfiles()) {
      ListMultimap<Integer, ActiveRuleParamDto> paramDtosByActiveRuleId =
          ArrayListMultimap.create();
      for (ActiveRuleParamDto dto : activeRuleDao.selectParamsByProfileKey(qProfile.key())) {
        paramDtosByActiveRuleId.put(dto.getActiveRuleId(), dto);
      }

      for (ActiveRuleDto activeDto : activeRuleDao.selectByProfileKey(qProfile.key())) {
        Rule rule = ruleFinder.findById(activeDto.getRuleId());
        if (rule != null) {
          String internalKey;
          Rule template = rule.getTemplate();
          if (template != null) {
            internalKey = template.getConfigKey();
          } else {
            internalKey = rule.getConfigKey();
          }
          ActiveRule activeRule =
              new ActiveRule(
                  rule.ruleKey().repository(),
                  rule.ruleKey().rule(),
                  rule.getName(),
                  activeDto.getSeverityString(),
                  internalKey,
                  rule.getLanguage());

          // load parameter values
          for (ActiveRuleParamDto paramDto : paramDtosByActiveRuleId.get(activeDto.getId())) {
            activeRule.params().put(paramDto.getKey(), paramDto.getValue());
          }

          // load default values
          for (RuleParam param : rule.getParams()) {
            if (!activeRule.params().containsKey(param.getKey())) {
              activeRule.params().put(param.getKey(), param.getDefaultValue());
            }
          }

          ref.addActiveRule(activeRule);
        }
      }
    }

    return ref;
  }