/** 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;
 }
  @Test
  public void search_qprofile_activity_with_rule_not_found() throws InterruptedException {
    MockUserSession.set()
        .setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN)
        .setLogin("me");

    RuleKey ruleKey = RuleKey.of("xoo", "deleted_rule");

    tester
        .get(ActivityService.class)
        .write(
            dbSession,
            Activity.Type.QPROFILE,
            ActiveRuleChange.createFor(
                    ActiveRuleChange.Type.ACTIVATED, ActiveRuleKey.of(XOO_P1_KEY, ruleKey))
                .setSeverity(Severity.MAJOR)
                .setParameter("max", "10"));
    dbSession.commit();

    Result<QProfileActivity> activities =
        service.searchActivities(new QProfileActivityQuery(), new QueryContext());
    assertThat(activities.getHits()).hasSize(1);

    QProfileActivity activity = activities.getHits().get(0);
    assertThat(activity.ruleKey()).isEqualTo(ruleKey);
    assertThat(activity.ruleName()).isNull();
  }
  private List<ActiveRuleChange> cascadeDeactivation(
      ActiveRuleKey key, DbSession dbSession, boolean isCascade, boolean force) {
    List<ActiveRuleChange> changes = Lists.newArrayList();
    RuleActivatorContext context = contextFactory.create(key, dbSession);
    ActiveRuleChange change;
    if (context.activeRule() == null) {
      return changes;
    }
    if (!force && !isCascade && context.activeRule().getInheritance() != null) {
      throw new IllegalStateException("Cannot deactivate inherited rule '" + key.ruleKey() + "'");
    }
    change = ActiveRuleChange.createFor(ActiveRuleChange.Type.DEACTIVATED, key);
    changes.add(change);
    persist(change, context, dbSession);

    // get all inherited profiles
    List<QualityProfileDto> profiles =
        db.qualityProfileDao().findByParentKey(dbSession, key.qProfile());

    for (QualityProfileDto profile : profiles) {
      ActiveRuleKey activeRuleKey = ActiveRuleKey.of(profile.getKey(), key.ruleKey());
      changes.addAll(cascadeDeactivation(activeRuleKey, dbSession, true, force));
    }

    if (!changes.isEmpty()) {
      log.write(dbSession, Activity.Type.ACTIVE_RULE, changes);
      previewCache.reportGlobalModification();
    }

    return changes;
  }
  @Test
  public void search_qprofile_activity_with_user_not_found() throws InterruptedException {
    MockUserSession.set()
        .setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN)
        .setLogin("david");

    // We need an actual rule in DB to test RuleName in Activity
    db.ruleDao().getByKey(dbSession, RuleTesting.XOO_X1);

    tester
        .get(ActivityService.class)
        .write(
            dbSession,
            Activity.Type.QPROFILE,
            ActiveRuleChange.createFor(
                    ActiveRuleChange.Type.ACTIVATED,
                    ActiveRuleKey.of(XOO_P1_KEY, RuleTesting.XOO_X1))
                .setSeverity(Severity.MAJOR)
                .setParameter("max", "10"));
    dbSession.commit();

    Result<QProfileActivity> activities =
        service.searchActivities(new QProfileActivityQuery(), new QueryContext());
    assertThat(activities.getHits()).hasSize(1);

    QProfileActivity activity = activities.getHits().get(0);
    assertThat(activity.login()).isEqualTo("david");
    assertThat(activity.authorName()).isNull();
  }
 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;
 }
 /**
  * Severity and parameter values are : 1. defined by end-user 2. else inherited from parent
  * profile 3. else defined by rule defaults
  *
  * <p>On custom rules, it's always rule parameters that are used
  */
 private void applySeverityAndParamToChange(
     RuleActivation activation, RuleActivatorContext context, ActiveRuleChange change) {
   change.setSeverity(
       StringUtils.defaultIfEmpty(activation.getSeverity(), context.defaultSeverity()));
   for (RuleParamDto ruleParamDto : context.ruleParams()) {
     String value = null;
     if (context.rule().getTemplateId() == null) {
       value =
           StringUtils.defaultIfEmpty(
               activation.getParameters().get(ruleParamDto.getName()),
               context.defaultParam(ruleParamDto.getName()));
       verifyParam(ruleParamDto, value);
     }
     change.setParameter(
         ruleParamDto.getName(),
         StringUtils.defaultIfEmpty(value, ruleParamDto.getDefaultValue()));
   }
 }
  public List<ActiveRuleChange> activate(DbSession dbSession, RuleActivation activation) {
    RuleActivatorContext context = contextFactory.create(activation.getKey(), dbSession);
    context.verifyForActivation();
    List<ActiveRuleChange> changes = Lists.newArrayList();
    ActiveRuleChange change;
    boolean stopPropagation = false;

    if (context.activeRule() == null) {
      // new activation
      change = ActiveRuleChange.createFor(ActiveRuleChange.Type.ACTIVATED, activation.getKey());
      if (activation.isCascade() || context.isSameAsParent(activation)) {
        change.setInheritance(ActiveRule.Inheritance.INHERITED);
      }
      applySeverityAndParamToChange(activation, context, change);

    } else {
      // already activated

      if (activation.isCascade() && context.activeRule().doesOverride()) {
        // propagating to descendants, but child profile already overrides rule -> stop propagation
        return changes;
      }
      change = ActiveRuleChange.createFor(ActiveRuleChange.Type.UPDATED, activation.getKey());
      if (activation.isCascade() && context.activeRule().getInheritance() == null) {
        // activate on child, then on parent -> mark child as overriding parent
        change.setInheritance(ActiveRule.Inheritance.OVERRIDES);
        change.setSeverity(context.activeRule().getSeverityString());
        change.setParameters(context.activeRuleParamsAsStringMap());
        stopPropagation = true;
      } else {
        applySeverityAndParamToChange(activation, context, change);
        if (!activation.isCascade() && context.parentProfile() != null) {
          // override rule which is already declared on parents
          change.setInheritance(
              context.isSameAsParent(activation)
                  ? ActiveRule.Inheritance.INHERITED
                  : ActiveRule.Inheritance.OVERRIDES);
        }
      }
    }

    changes.add(change);
    persist(change, context, dbSession);

    if (!stopPropagation) {
      changes.addAll(cascadeActivation(dbSession, activation));
    }

    if (!changes.isEmpty()) {
      log.write(dbSession, Activity.Type.ACTIVE_RULE, changes);
      previewCache.reportGlobalModification();
    }
    return changes;
  }
  @Test
  public void search_activity_by_qprofile_having_dashes_in_keys() throws InterruptedException {
    tester
        .get(ActivityService.class)
        .write(
            dbSession,
            Activity.Type.QPROFILE,
            ActiveRuleChange.createFor(
                ActiveRuleChange.Type.ACTIVATED,
                ActiveRuleKey.of("java-default", RuleTesting.XOO_X1)));
    tester
        .get(ActivityService.class)
        .write(
            dbSession,
            Activity.Type.QPROFILE,
            ActiveRuleChange.createFor(
                ActiveRuleChange.Type.ACTIVATED,
                ActiveRuleKey.of("java-toto", RuleTesting.XOO_X1)));
    dbSession.commit();

    // 0. Base case verify 2 activities in index
    assertThat(service.searchActivities(new QProfileActivityQuery(), new QueryContext()).getHits())
        .hasSize(2);

    // 1. filter by QProfile
    List<QProfileActivity> result =
        service
            .searchActivities(
                new QProfileActivityQuery().setQprofileKeys(ImmutableSet.of("java-default")),
                new QueryContext())
            .getHits();
    assertThat(result).hasSize(1);

    // 1. filter by QProfiles
    assertThat(
            service
                .searchActivities(
                    new QProfileActivityQuery()
                        .setQprofileKeys(ImmutableSet.of("java-default", "java-toto")),
                    new QueryContext())
                .getHits())
        .hasSize(2);
  }
  @Test
  public void search_qprofile_activity() throws InterruptedException {
    MockUserSession.set()
        .setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN)
        .setLogin("david");

    UserDto user =
        new UserDto()
            .setLogin("david")
            .setName("David")
            .setEmail("*****@*****.**")
            .setCreatedAt(new Date())
            .setUpdatedAt(new Date());
    db.userDao().insert(dbSession, user);

    // We need an actual rule in DB to test RuleName in Activity
    RuleDto rule = db.ruleDao().getByKey(dbSession, RuleTesting.XOO_X1);

    tester
        .get(ActivityService.class)
        .write(
            dbSession,
            Activity.Type.QPROFILE,
            ActiveRuleChange.createFor(
                    ActiveRuleChange.Type.ACTIVATED,
                    ActiveRuleKey.of(XOO_P1_KEY, RuleTesting.XOO_X1))
                .setSeverity(Severity.MAJOR)
                .setParameter("max", "10"));
    dbSession.commit();

    Result<QProfileActivity> activities =
        service.searchActivities(new QProfileActivityQuery(), new QueryContext());
    assertThat(activities.getHits()).hasSize(1);

    QProfileActivity activity = activities.getHits().get(0);
    assertThat(activity.type()).isEqualTo(Activity.Type.QPROFILE);
    assertThat(activity.action()).isEqualTo(ActiveRuleChange.Type.ACTIVATED.name());
    assertThat(activity.ruleKey()).isEqualTo(RuleTesting.XOO_X1);
    assertThat(activity.profileKey()).isEqualTo(XOO_P1_KEY);
    assertThat(activity.severity()).isEqualTo(Severity.MAJOR);
    assertThat(activity.ruleName()).isEqualTo(rule.getName());
    assertThat(activity.login()).isEqualTo("david");
    assertThat(activity.authorName()).isEqualTo("David");

    assertThat(activity.parameters()).hasSize(1);
    assertThat(activity.parameters().get("max")).isEqualTo("10");
  }
 @Override
 public ActiveRuleKey apply(@Nonnull ActiveRuleChange input) {
   return input.getKey();
 }
 @Override
 public boolean apply(@Nonnull ActiveRuleChange input) {
   return input.getType().equals(ActiveRuleChange.Type.DEACTIVATED);
 }
  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;
  }