import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
-import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import org.sonar.api.rules.RuleType;
import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Arrays.asList;
import static java.util.Collections.emptySet;
import static java.util.Optional.ofNullable;
import static org.sonar.db.rule.RuleDescriptionSectionDto.DEFAULT_KEY;
private String ruleKey = null;
private final Set<RuleDescriptionSectionDto> ruleDescriptionSectionDtos = new HashSet<>();
+ private String genericConceptsField = null;
/**
* Description format can be null on external rule, otherwise it should never be null
return Objects.equals(contextKey, otherContextKey);
}
+ public Set<String> getGenericConcepts() {
+ return deserializeStringSet(genericConceptsField);
+ }
+
+ public RuleDto setGenericConcepts(Set<String> genericConcepts){
+ this.genericConceptsField = serializeStringSet(genericConcepts);
+ return this;
+ }
+
@CheckForNull
public Format getDescriptionFormat() {
return descriptionFormat;
}
public Set<String> getTags() {
- return tags == null ? new HashSet<>() : new TreeSet<>(Arrays.asList(StringUtils.split(tags, ',')));
+ return tags == null ? new HashSet<>() : new TreeSet<>(asList(StringUtils.split(tags, ',')));
}
String getTagsAsString() {
r.ad_hoc_name as "adHocName",
r.ad_hoc_description as "adHocDescription",
r.ad_hoc_severity as "adHocSeverity",
- r.ad_hoc_type as "adHocType"
+ r.ad_hoc_type as "adHocType",
+ r.generic_concepts as "genericConceptsField"
</sql>
<sql id="leftOuterJoinRulesDescriptionSections">
ad_hoc_description,
ad_hoc_severity,
ad_hoc_type,
+ generic_concepts,
created_at,
updated_at
)
#{adHocDescription,jdbcType=CLOB},
#{adHocSeverity,jdbcType=VARCHAR},
#{adHocType,jdbcType=TINYINT},
+ #{genericConceptsField,jdbcType=VARCHAR},
#{createdAt,jdbcType=BIGINT},
#{updatedAt,jdbcType=BIGINT}
)
ad_hoc_description=#{adHocDescription,jdbcType=CLOB},
ad_hoc_severity=#{adHocSeverity,jdbcType=VARCHAR},
ad_hoc_type=#{adHocType,jdbcType=TINYINT},
+ generic_concepts=#{genericConceptsField,jdbcType=VARCHAR},
updated_at=#{updatedAt,jdbcType=BIGINT}
where
uuid=#{uuid,jdbcType=VARCHAR}
assertThat(actual.getAdHocType()).isEqualTo(expected.getAdHocType());
assertThat(actual.getRuleDescriptionSectionDtos()).usingRecursiveFieldByFieldElementComparator()
.containsExactlyInAnyOrderElementsOf(expected.getRuleDescriptionSectionDtos());
+ assertThat(actual.getGenericConcepts()).isEqualTo(expected.getGenericConcepts());
}
@Test
.setAdHocType(RuleType.values()[nextInt(RuleType.values().length - 1)])
.setCreatedAt(currentTimeMillis)
.setUpdatedAt(currentTimeMillis + 5)
- .setScope(Scope.MAIN);
+ .setScope(Scope.MAIN)
+ .setGenericConcepts(Set.of(randomAlphanumeric(5), randomAlphanumeric(5)));
}
public static RuleParamDto newRuleParam(RuleDto rule) {
import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_DESCRIPTION_SECTIONS;
import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_EFFORT_TO_FIX_DESCRIPTION;
import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_GAP_DESCRIPTION;
+import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_GENERIC_CONCEPTS;
import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_HTML_DESCRIPTION;
import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_INTERNAL_KEY;
import static org.sonar.server.rule.ws.RulesWsParameters.FIELD_IS_EXTERNAL;
setAdHocSeverity(ruleResponse, ruleDto, fieldsToReturn);
setAdHocType(ruleResponse, ruleDto);
}
+ setGenericConcepts(ruleResponse, ruleDto, fieldsToReturn);
return ruleResponse;
}
}
}
+ private static void setGenericConcepts(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn) {
+ if (shouldReturnField(fieldsToReturn, FIELD_GENERIC_CONCEPTS)) {
+ ruleResponse.getGenericConceptsBuilder().addAllGenericConcepts((ruleDto.getGenericConcepts()));
+ }
+ }
+
private static void setDeprecatedKeys(Rules.Rule.Builder ruleResponse, RuleDto ruleDto, Set<String> fieldsToReturn,
Map<String, List<DeprecatedRuleKeyDto>> deprecatedRuleKeysByRuleUuid) {
if (shouldReturnField(fieldsToReturn, FIELD_DEPRECATED_KEYS)) {
public static final String FIELD_MARKDOWN_DESCRIPTION = "mdDesc";
public static final String FIELD_DESCRIPTION_SECTIONS = "descriptionSections";
+ public static final String FIELD_GENERIC_CONCEPTS = "genericConcepts";
public static final String FIELD_NOTE_LOGIN = "noteLogin";
public static final String FIELD_MARKDOWN_NOTE = "mdNote";
public static final String FIELD_HTML_NOTE = "htmlNote";
FIELD_MARKDOWN_DESCRIPTION, FIELD_DESCRIPTION_SECTIONS, FIELD_NOTE_LOGIN, FIELD_MARKDOWN_NOTE, FIELD_HTML_NOTE,
FIELD_DEFAULT_DEBT_REM_FUNCTION, FIELD_EFFORT_TO_FIX_DESCRIPTION, FIELD_DEBT_OVERLOADED, FIELD_DEBT_REM_FUNCTION,
FIELD_DEFAULT_REM_FUNCTION, FIELD_GAP_DESCRIPTION, FIELD_REM_FUNCTION_OVERLOADED, FIELD_REM_FUNCTION,
- FIELD_PARAMS, FIELD_ACTIVES, FIELD_SCOPE, FIELD_DEPRECATED_KEYS);
+ FIELD_PARAMS, FIELD_ACTIVES, FIELD_SCOPE, FIELD_DEPRECATED_KEYS, FIELD_GENERIC_CONCEPTS);
private RulesWsParameters() {
// prevent instantiation
new Change("9.5", "The field 'htmlDesc' has been deprecated use 'descriptionSections' instead"),
new Change("9.5", "The field 'descriptionSections' has been added to the payload"),
new Change("9.5", "The field 'descriptionSections' has been added to the 'f' parameter"),
- new Change("9.6", "'descriptionSections' can optionally embed a context field")
+ new Change("9.6", "'descriptionSections' can optionally embed a context field"),
+ new Change("9.6", "The field 'genericConcepts' has been added to the 'f' parameter")
);
action.createParam(FACETS)
new Change("9.5", "The field 'htmlDesc' has been deprecated use 'descriptionSections' instead"),
new Change("9.5", "The field 'descriptionSections' has been added to the payload"),
new Change("9.5", "The field 'descriptionSections' has been added to the 'f' parameter"),
- new Change("9.6", "'descriptionSections' can optionally embed a context field")
+ new Change("9.6", "'descriptionSections' can optionally embed a context field"),
+ new Change("9.6", "'genericConcepts' has been added")
);
action
indexRules();
Rules.SearchResponse response = ws.newRequest()
- .setParam(WebService.Param.FIELDS, "createdAt,langName")
+ .setParam(WebService.Param.FIELDS, "createdAt,langName,genericConcepts")
.executeProtobuf(Rules.SearchResponse.class);
Rules.Rule result = response.getRules(0);
// selected fields
assertThat(result.getCreatedAt()).isNotEmpty();
assertThat(result.getLangName()).isNotEmpty();
+ assertThat(result.getGenericConcepts().getGenericConceptsList()).containsExactlyElementsOf(rule.getGenericConcepts());
// not returned fields
assertThat(result.hasEffortToFixDescription()).isFalse();
assertThat(resultRule.getParams().getParamsList())
.extracting(Rule.Param::getKey, Rule.Param::getHtmlDesc, Rule.Param::getDefaultValue)
.containsExactlyInAnyOrder(tuple(ruleParam.getName(), ruleParam.getDescription(), ruleParam.getDefaultValue()));
+ assertThat(resultRule.getGenericConcepts().getGenericConceptsList()).containsExactlyElementsOf(rule.getGenericConcepts());
}
@Test
optional bool isExternal = 47;
optional DeprecatedKeys deprecatedKeys = 48;
optional DescriptionSections descriptionSections = 49;
+ optional GenericConcepts genericConcepts = 50;
message DescriptionSections {
repeated DescriptionSection descriptionSections = 1;
repeated string tags = 1;
}
+message GenericConcepts {
+ repeated string genericConcepts = 1;
+}
+
message Actives {
map<string, ActiveList> actives = 1;
}