import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.io.Resources;
import org.apache.commons.lang.BooleanUtils;
super.writeFacets(request, context, results, json);
}
- private void addMandatoryFacetValues(Result<?> results, String facetName, @Nullable List<String> mandatoryValues) {
- Collection<FacetValue> facetValues = results.getFacetValues(facetName);
- if (facetValues != null) {
- Map<String, Long> valuesByItem = Maps.newHashMap();
- for (FacetValue value : facetValues) {
- valuesByItem.put(value.getKey(), value.getValue());
- }
- List<String> valuesToAdd = mandatoryValues == null ? Lists.<String>newArrayList() : mandatoryValues;
- for (String item : valuesToAdd) {
- if (!valuesByItem.containsKey(item)) {
- facetValues.add(new FacetValue(item, 0));
- }
- }
- }
- }
-
private void collectFacetsData(Request request, Result<Issue> result, Set<String> projectUuids, Set<String> componentUuids, List<String> userLogins, Set<String> actionPlanKeys) {
collectFacetKeys(result, IssueFilterParameters.PROJECT_UUIDS, projectUuids);
collectParameterValues(request, IssueFilterParameters.PROJECT_UUIDS, projectUuids);
*/
package org.sonar.server.rule.index;
+import com.google.common.base.Function;
import com.google.common.base.Preconditions;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
+import org.sonar.api.rule.Severity;
import org.sonar.api.server.debt.DebtCharacteristic;
import org.sonar.core.rule.RuleDto;
import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer;
import javax.annotation.CheckForNull;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
public static final String FACET_LANGUAGES = "languages";
public static final String FACET_TAGS = "tags";
public static final String FACET_REPOSITORIES = "repositories";
+ public static final String FACET_SEVERITIES = "severities";
+ public static final String FACET_STATUSES = "statuses";
+ public static final String FACET_DEBT_CHARACTERISTICS = "debt_characteristics";
+ public static final String FACET_OLD_DEFAULT = "true";
+
+ public static final List<String> ALL_STATUSES = ImmutableList.copyOf(Collections2.transform(Arrays.asList(RuleStatus.values()), new Function<RuleStatus, String>() {
+ @Override
+ public String apply(RuleStatus input) {
+ return input.toString();
+ }
+ }));
public RuleIndex(RuleNormalizer normalizer, SearchClient client) {
super(IndexDefinition.RULE, normalizer, client);
protected Map<String, AggregationBuilder> getFacets(RuleQuery query, QueryContext options, QueryBuilder queryBuilder, Map<String, FilterBuilder> filters) {
Map<String, AggregationBuilder> aggregations = new HashMap<String, AggregationBuilder>();
-
StickyFacetBuilder stickyFacetBuilder = stickyFacetBuilder(queryBuilder, filters);
- if (options.facets().contains("languages") || options.facets().contains("true")) {
+
+ addDefaultFacets(query, options, queryBuilder, filters, aggregations, stickyFacetBuilder);
+
+ if (options.facets().contains(FACET_STATUSES)) {
+ aggregations.put(FACET_STATUSES,
+ stickyFacetBuilder.buildStickyFacet(RuleNormalizer.RuleField.STATUS.field(), FACET_STATUSES, ALL_STATUSES.toArray()));
+ }
+
+ if (options.facets().contains(FACET_SEVERITIES)) {
+ aggregations.put(FACET_SEVERITIES,
+ stickyFacetBuilder.buildStickyFacet(RuleNormalizer.RuleField.SEVERITY.field(), FACET_SEVERITIES, Severity.ALL.toArray()));
+ }
+
+ return aggregations;
+
+ }
+
+ protected void addDefaultFacets(RuleQuery query, QueryContext options, QueryBuilder queryBuilder, Map<String, FilterBuilder> filters,
+ Map<String, AggregationBuilder> aggregations, StickyFacetBuilder stickyFacetBuilder) {
+ if (options.facets().contains(FACET_LANGUAGES) || options.facets().contains(FACET_OLD_DEFAULT)) {
Collection<String> languages = query.getLanguages();
aggregations.put(FACET_LANGUAGES,
stickyFacetBuilder.buildStickyFacet(RuleNormalizer.RuleField.LANGUAGE.field(), FACET_LANGUAGES,
languages == null ? new String[0] : languages.toArray()));
}
- if (options.facets().contains("tags") || options.facets().contains("true")) {
+ if (options.facets().contains(FACET_TAGS) || options.facets().contains(FACET_OLD_DEFAULT)) {
Collection<String> tags = query.getTags();
aggregations.put(FACET_TAGS,
stickyFacetBuilder.buildStickyFacet(RuleNormalizer.RuleField.ALL_TAGS.field(), FACET_TAGS,
tags == null ? new String[0] : tags.toArray()));
}
- if (options.facets().contains("repositories") || options.facets().contains("true")) {
+ if (options.facets().contains("repositories") || options.facets().contains(FACET_OLD_DEFAULT)) {
Collection<String> repositories = query.getRepositories();
aggregations.put(FACET_REPOSITORIES,
stickyFacetBuilder.buildStickyFacet(RuleNormalizer.RuleField.REPOSITORY.field(), FACET_REPOSITORIES,
repositories == null ? new String[0] : repositories.toArray()));
}
-
-
- return aggregations;
-
}
public Result<Rule> search(RuleQuery query, QueryContext options) {
import org.sonar.server.qualityprofile.ActiveRule;
import org.sonar.server.rule.Rule;
import org.sonar.server.rule.RuleService;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleNormalizer;
import org.sonar.server.rule.index.RuleQuery;
import org.sonar.server.search.QueryContext;
@CheckForNull
protected Collection<String> possibleFacets() {
return Arrays.asList(new String[] {
- PARAM_LANGUAGES,
- PARAM_REPOSITORIES,
- "tags",
- "characteristics",
- "severities",
- "statuses",
- "true"
+ RuleIndex.FACET_LANGUAGES,
+ RuleIndex.FACET_REPOSITORIES,
+ RuleIndex.FACET_TAGS,
+ RuleIndex.FACET_DEBT_CHARACTERISTICS,
+ RuleIndex.FACET_SEVERITIES,
+ RuleIndex.FACET_STATUSES,
+ RuleIndex.FACET_OLD_DEFAULT
});
}
.setLimit(context.getLimit())
.setOffset(context.getOffset())
.setScroll(context.isScroll());
- if (context.facets().contains("true")) {
+ if (context.facets().contains(RuleIndex.FACET_OLD_DEFAULT)) {
searchQueryContext.addFacets(DEFAULT_FACETS);
} else {
searchQueryContext.addFacets(context.facets());
}
return builder.add("actives").build();
}
+
+ @Override
+ protected void writeFacets(Request request, QueryContext context, Result<?> results, JsonWriter json) {
+ addMandatoryFacetValues(results, RuleIndex.FACET_STATUSES, RuleIndex.ALL_STATUSES);
+ addMandatoryFacetValues(results, RuleIndex.FACET_SEVERITIES, Severity.ALL);
+ super.writeFacets(request, context, results, json);
+ }
}
*/
package org.sonar.server.search.ws;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.RequestHandler;
import org.sonar.server.search.Result;
import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Set;
public abstract class SearchRequestHandler<QUERY, DOMAIN> implements RequestHandler {
}
}
+ protected void addMandatoryFacetValues(Result<?> results, String facetName, @Nullable List<String> mandatoryValues) {
+ Collection<FacetValue> facetValues = results.getFacetValues(facetName);
+ if (facetValues != null) {
+ Map<String, Long> valuesByItem = Maps.newHashMap();
+ for (FacetValue value : facetValues) {
+ valuesByItem.put(value.getKey(), value.getValue());
+ }
+ List<String> valuesToAdd = mandatoryValues == null ? Lists.<String>newArrayList() : mandatoryValues;
+ for (String item : valuesToAdd) {
+ if (!valuesByItem.containsKey(item)) {
+ facetValues.add(new FacetValue(item, 0));
+ }
+ }
+ }
+ }
+
}
result.assertJson(this.getClass(), "filter_by_tags.json");
}
+ @Test
+ public void severities_facet_should_have_all_severities() throws Exception {
+ WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD);
+ request.setParam(SearchAction.PARAM_FACETS, "severities");
+ request.execute().assertJson(this.getClass(), "severities_facet.json", false);
+ }
+
+ @Test
+ public void statuses_facet_should_have_all_statuses() throws Exception {
+ WsTester.TestRequest request = tester.wsTester().newGetRequest(API_ENDPOINT, API_SEARCH_METHOD);
+ request.setParam(SearchAction.PARAM_FACETS, "statuses");
+ request.execute().assertJson(this.getClass(), "statuses_facet.json", false);
+ }
+
@Test
public void sort_by_name() throws Exception {
ruleDao.insert(session, RuleTesting.newXooX1().setName("Dodgy - Consider returning a zero length array rather than null "));
--- /dev/null
+{"total": 0, "p": 1, "ps": 100, "rules": [],
+"facets": [
+ {
+ "property": "severities",
+ "values": [
+ {
+ "val": "BLOCKER",
+ "count": 0
+ },{
+ "val": "CRITICAL",
+ "count": 0
+ },{
+ "val": "MAJOR",
+ "count": 0
+ },{
+ "val": "MINOR",
+ "count": 0
+ },
+ {
+ "val": "INFO",
+ "count": 0
+ }
+ ]
+ }
+]}
--- /dev/null
+{"total": 0, "p": 1, "ps": 100, "rules": [],
+"facets": [
+ {
+ "property": "statuses",
+ "values": [
+ {
+ "val": "BETA",
+ "count": 0
+ },{
+ "val": "DEPRECATED",
+ "count": 0
+ },{
+ "val": "READY",
+ "count": 0
+ },{
+ "val": "REMOVED",
+ "count": 0
+ }
+ ]
+ }
+]}