From 9dac52b3944ba8023f8b5b2b25d694a0f8f66323 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Lievremont Date: Thu, 19 Feb 2015 10:41:36 +0100 Subject: [PATCH] SONAR-6153 Show rule tags in issue tag suggestions --- .../sonar/server/issue/index/IssueIndex.java | 44 +++++++++++++++++-- .../server/issue/IssueServiceMediumTest.java | 5 ++- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java index 5878c7a6f46..eb1a6f9b7c7 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java @@ -24,6 +24,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import org.apache.commons.lang.BooleanUtils; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.action.search.SearchResponse; @@ -32,6 +33,8 @@ import org.elasticsearch.index.query.*; import org.elasticsearch.search.aggregations.AggregationBuilder; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.global.Global; +import org.elasticsearch.search.aggregations.bucket.global.GlobalBuilder; import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogram; import org.elasticsearch.search.aggregations.bucket.missing.InternalMissing; import org.elasticsearch.search.aggregations.bucket.terms.Terms; @@ -46,6 +49,8 @@ import org.sonar.server.es.*; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.issue.IssueQuery; import org.sonar.server.issue.filter.IssueFilterParameters; +import org.sonar.server.rule.index.RuleNormalizer; +import org.sonar.server.search.IndexDefinition; import org.sonar.server.search.StickyFacetBuilder; import org.sonar.server.user.UserSession; import org.sonar.server.view.index.ViewIndexDefinition; @@ -64,6 +69,8 @@ import static com.google.common.collect.Lists.newArrayList; */ public class IssueIndex extends BaseIndex { + private static final String SUBSTRING_MATCH_REGEXP = ".*%s.*"; + public static final List SUPPORTED_FACETS = ImmutableList.of( IssueFilterParameters.SEVERITIES, IssueFilterParameters.STATUSES, @@ -542,8 +549,39 @@ public class IssueIndex extends BaseIndex { } public List listTags(IssueQuery query, @Nullable String textQuery, int maxNumberOfTags) { - Terms terms = listTermsMatching(IssueIndexDefinition.FIELD_ISSUE_TAGS, query, textQuery, Terms.Order.term(true), maxNumberOfTags); - return EsUtils.termsKeys(terms); + SearchRequestBuilder requestBuilder = getClient() + .prepareSearch(IssueIndexDefinition.INDEX, IndexDefinition.RULE.getIndexName()) + .setTypes(IssueIndexDefinition.TYPE_ISSUE, IndexDefinition.RULE.getIndexType()); + + requestBuilder.setQuery(QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(), + createBoolFilter(query))); + GlobalBuilder topAggreg = AggregationBuilders.global("tags"); + TermsBuilder issueTags = AggregationBuilders.terms("tags__issues") + .field(IssueIndexDefinition.FIELD_ISSUE_TAGS) + .size(maxNumberOfTags) + .order(Terms.Order.term(true)) + .minDocCount(1L); + if (textQuery != null) { + issueTags.include(String.format(SUBSTRING_MATCH_REGEXP, textQuery)); + } + TermsBuilder ruleTags = AggregationBuilders.terms("tags__rules") + .field(RuleNormalizer.RuleField.ALL_TAGS.field()) + .size(maxNumberOfTags) + .order(Terms.Order.term(true)) + .minDocCount(1L); + if (textQuery != null) { + ruleTags.include(String.format(SUBSTRING_MATCH_REGEXP, textQuery)); + } + + SearchResponse searchResponse = requestBuilder.addAggregation(topAggreg.subAggregation(issueTags).subAggregation(ruleTags)).get(); + Global allTags = searchResponse.getAggregations().get("tags"); + SortedSet result = Sets.newTreeSet(); + Terms issuesResult = allTags.getAggregations().get("tags__issues"); + Terms rulesResult = allTags.getAggregations().get("tags__rules"); + result.addAll(EsUtils.termsKeys(issuesResult)); + result.addAll(EsUtils.termsKeys(rulesResult)); + List resultAsList = Lists.newArrayList(result); + return resultAsList.size() > maxNumberOfTags ? resultAsList.subList(0, maxNumberOfTags) : resultAsList; } public Map countTags(IssueQuery query, int maxNumberOfTags) { @@ -572,7 +610,7 @@ public class IssueIndex extends BaseIndex { .order(termsOrder) .minDocCount(1L); if (textQuery != null) { - aggreg.include(String.format(".*%s.*", textQuery)); + aggreg.include(String.format(SUBSTRING_MATCH_REGEXP, textQuery)); } SearchResponse searchResponse = requestBuilder.addAggregation(aggreg).get(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java index 44223ac2208..3023ae60034 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java @@ -532,11 +532,12 @@ public class IssueServiceMediumTest { saveIssue(IssueTesting.newDto(rule, file, project)); saveIssue(IssueTesting.newDto(rule, file, project).setTags(ImmutableSet.of("convention"))); - assertThat(service.listTags(null, 5)).containsOnly("convention", "java8", "bug"); + assertThat(service.listTags(null, 5)).containsOnly("convention", "java8", "bug" /* from issues */, "systag1", "systag2" /* from rules */); assertThat(service.listTags(null, 2)).containsOnly("bug", "convention"); assertThat(service.listTags("vent", 5)).containsOnly("convention"); + assertThat(service.listTags("sys", 5)).containsOnly("systag1", "systag2"); assertThat(service.listTags(null, 1)).containsOnly("bug"); - assertThat(service.listTags(null, Integer.MAX_VALUE)).containsOnly("convention", "java8", "bug"); + assertThat(service.listTags(null, Integer.MAX_VALUE)).containsOnly("convention", "java8", "bug", "systag1", "systag2", "tag1", "tag2"); } @Test -- 2.39.5