import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
-
import java.io.IOException;
import java.net.URL;
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
/**
* Defines a web service. Note that contrary to the deprecated {@link org.sonar.api.web.Webservice}
/**
* @since 4.4
*/
- public NewParam setExampleValue(@Nullable String s) {
- this.exampleValue = s;
+ public NewParam setExampleValue(@Nullable Object s) {
+ this.exampleValue = (s != null ? s.toString() : null);
return this;
}
/**
* @since 4.4
*/
- public NewParam setDefaultValue(@Nullable String s) {
- this.defaultValue = s;
+ public NewParam setDefaultValue(@Nullable Object o) {
+ this.defaultValue = (o != null ? o.toString() : null);
return this;
}
import org.apache.commons.lang.StringUtils;
import org.junit.Test;
+import org.sonar.api.rule.RuleStatus;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.Collection;
import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.Fail.fail;
assertThat(action.param("severity").possibleValues()).containsOnly("INFO", "MAJOR", "BLOCKER");
}
+ @Test
+ public void param_metadata_as_objects() {
+ new WebService() {
+ @Override
+ public void define(Context context) {
+ NewController newController = context.createController("api/rule");
+ NewAction create = newController.createAction("create").setHandler(mock(RequestHandler.class));
+ create.createParam("status")
+ .setDefaultValue(RuleStatus.BETA)
+ .setPossibleValues(RuleStatus.BETA, RuleStatus.READY)
+ .setExampleValue(RuleStatus.BETA);
+ create.createParam("max")
+ .setDefaultValue(11)
+ .setPossibleValues(11, 13, 17)
+ .setExampleValue(17);
+ newController.done();
+ }
+ }.define(context);
+
+ WebService.Action action = context.controller("api/rule").action("create");
+ assertThat(action.param("status").defaultValue()).isEqualTo("BETA");
+ assertThat(action.param("status").possibleValues()).containsOnly("BETA", "READY");
+ assertThat(action.param("status").exampleValue()).isEqualTo("BETA");
+ assertThat(action.param("max").defaultValue()).isEqualTo("11");
+ assertThat(action.param("max").possibleValues()).containsOnly("11", "13", "17");
+ assertThat(action.param("max").exampleValue()).isEqualTo("17");
+ }
+
+ @Test
+ public void param_null_metadata() {
+ new WebService() {
+ @Override
+ public void define(Context context) {
+ NewController newController = context.createController("api/rule");
+ NewAction create = newController.createAction("create").setHandler(mock(RequestHandler.class));
+ create.createParam("status")
+ .setDefaultValue(null)
+ .setPossibleValues((Collection) null)
+ .setExampleValue(null);
+ create.createParam("max")
+ .setPossibleValues((String[]) null);
+ newController.done();
+ }
+ }.define(context);
+
+ WebService.Action action = context.controller("api/rule").action("create");
+ assertThat(action.param("status").defaultValue()).isNull();
+ assertThat(action.param("status").possibleValues()).isNull();
+ assertThat(action.param("status").exampleValue()).isNull();
+ assertThat(action.param("max").possibleValues()).isNull();
+ }
+
@Test
public void fail_if_duplicated_action_parameters() {
try {
pico.addSingleton(SetTagsAction.class);
pico.addSingleton(SetNoteAction.class);
pico.addSingleton(RuleMapping.class);
+ pico.addSingleton(ActiveRuleCompleter.class);
pico.addSingleton(org.sonar.server.rule2.ws.AppAction.class);
// measure
import org.sonar.core.qualityprofile.db.ActiveRuleDto;
import org.sonar.core.qualityprofile.db.ActiveRuleKey;
import org.sonar.core.qualityprofile.db.ActiveRuleParamDto;
+import org.sonar.core.qualityprofile.db.QualityProfileKey;
import org.sonar.core.rule.RuleParamDto;
import org.sonar.server.db.DbClient;
import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
import org.sonar.server.user.UserSession;
import org.sonar.server.util.TypeValidations;
+import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
this.previewCache = previewCache;
}
+ @CheckForNull
+ public ActiveRule getByKey(ActiveRuleKey key) {
+ return index.get(ActiveRuleIndex.class).getByKey(key);
+ }
+
+ public List<ActiveRule> findByRuleKey(RuleKey key){
+ return index.get(ActiveRuleIndex.class).findByRule(key);
+ }
+
/**
* Activate a rule on a Quality profile. Update configuration (severity/parameters) if the rule is already
* activated.
}
}
}
-
- public List<ActiveRule> findByRuleKey(RuleKey ruleKey){
- return index.get(ActiveRuleIndex.class).findByRule(ruleKey);
- }
}
import org.sonar.server.qualityprofile.ActiveRule;
import org.sonar.server.rule2.index.RuleIndexDefinition;
import org.sonar.server.search.BaseIndex;
-import org.sonar.server.search.QueryOptions;
import java.io.IOException;
import java.util.ArrayList;
}
@Override
- public ActiveRule toDoc(Map<String,Object> fields, QueryOptions options) {
+ public ActiveRule toDoc(Map<String, Object> fields) {
return new ActiveRuleDoc(fields);
}
List<ActiveRule> activeRules = new ArrayList<ActiveRule>();
for (SearchHit hit : response.getHits()) {
- activeRules.add(toDoc(hit.getSource(), QueryOptions.DEFAULT));
+ activeRules.add(toDoc(hit.getSource()));
}
return activeRules;
.setType(this.getIndexType())
.setIndex(this.getIndexName())
.setId(ActiveRuleKey.of(qualityProfileKey, ruleKey).toString())
- .get().getSource(), QueryOptions.DEFAULT);
+ .get().getSource());
}
}
import org.sonar.core.qualityprofile.db.ActiveRuleDto;
import org.sonar.core.qualityprofile.db.ActiveRuleKey;
import org.sonar.core.qualityprofile.db.ActiveRuleParamDto;
-import org.sonar.core.qualityprofile.db.QualityProfileDao;
import org.sonar.core.qualityprofile.db.QualityProfileDto;
import org.sonar.server.db.DbClient;
import org.sonar.server.search.BaseNormalizer;
import org.sonar.api.rule.RuleKey;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.persistence.DbSession;
-import org.sonar.core.qualityprofile.db.QualityProfileKey;
import org.sonar.core.rule.RuleDto;
import org.sonar.server.db.DbClient;
-import org.sonar.server.qualityprofile.ActiveRule;
-import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
import org.sonar.server.rule2.index.RuleIndex;
import org.sonar.server.rule2.index.RuleNormalizer;
import org.sonar.server.rule2.index.RuleQuery;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import java.util.Date;
-import java.util.List;
import java.util.Set;
/**
public class RuleService implements ServerComponent {
private final RuleIndex index;
- private final ActiveRuleIndex activeRuleIndex;
private final DbClient db;
- public RuleService(ActiveRuleIndex activeRuleIndex, RuleIndex index, DbClient db) {
+ public RuleService(RuleIndex index, DbClient db) {
this.index = index;
- this.activeRuleIndex = activeRuleIndex;
this.db = db;
}
}
public RuleResult search(RuleQuery query, QueryOptions options) {
- RuleResult result = index.search(query, options);
-
- /** Check for activation */
- if (query.getActivation() != null && !query.getActivation().isEmpty()) {
- if (query.getActivation().equalsIgnoreCase("true")) {
- for (Rule rule : result.getHits()) {
- if(query.getQProfileKey() == null){
- throw new IllegalStateException("\"activation=true\" requires a profile key!");
- }
- QualityProfileKey qualityProfileKey = QualityProfileKey.parse(query.getQProfileKey());
- result.getActiveRules().put(rule.key().toString(),
- activeRuleIndex.getByRuleKeyAndProfileKey(rule.key(),qualityProfileKey));
- }
- } else if (query.getActivation().equalsIgnoreCase("all")) {
- for (Rule rule : result.getHits()) {
- List<ActiveRule> activeRules = activeRuleIndex.findByRule(rule.key());
- for (ActiveRule activeRule : activeRules) {
- result.getActiveRules().put(rule.key().toString(), activeRule);
- }
- }
- }
- }
-
- return result;
+ return index.search(query, options);
}
/**
/**
* Set tags for rule.
*
- * @param ruleKey the required key
- * @param tags Set of tags. <code>null</code> to remove all tags.
+ * @param ruleKey the required key
+ * @param tags Set of tags. <code>null</code> to remove all tags.
*/
public void setTags(RuleKey ruleKey, Set<String> tags) {
-
checkAdminPermission(UserSession.get());
DbSession dbSession = db.openSession(false);
addMatchField(mapping, RuleNormalizer.RuleField.REPOSITORY.key(), "string");
addMatchField(mapping, RuleNormalizer.RuleField.SEVERITY.key(), "string");
- addMatchField(mapping, RuleNormalizer.RuleField.STATUS.key(), "string");;
+ addMatchField(mapping, RuleNormalizer.RuleField.STATUS.key(), "string");
+ ;
addMatchField(mapping, RuleNormalizer.RuleField.LANGUAGE.key(), "string");
mapping.startObject(RuleNormalizer.RuleField.CHARACTERISTIC.key())
}
/** Implementation of activation query */
- if (query.getActivation() != null && !query.getActivation().isEmpty()) {
- if (query.getActivation().equals("false")) {
- /** these are inactive rules */
- fb.mustNot(FilterBuilders.hasChildFilter(new ActiveRuleIndexDefinition().getIndexType(),
- QueryBuilders.matchAllQuery()));
- } else if (query.getActivation().equals("all")) {
- /** these are active rules */
+ if (query.getActivation() == Boolean.TRUE) {
+ if (query.getQProfileKey() == null) {
+ // the rules that are activated at least once
fb.must(FilterBuilders.hasChildFilter(new ActiveRuleIndexDefinition().getIndexType(),
QueryBuilders.matchAllQuery()));
- } else if (query.getActivation().equals("true")) {
- /** these are active rules for a given profile*/
- if (query.getQProfileKey() == null || query.getQProfileKey().isEmpty()) {
- throw new IllegalStateException("qProfile is required when \"activation=true\"");
- }
+ } else {
+ // the rules that are activated on this profile
fb.must(FilterBuilders.hasChildFilter(new ActiveRuleIndexDefinition().getIndexType(),
QueryBuilders.termQuery(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY.key(),
query.getQProfileKey())
));
}
- }
+ } else if (query.getActivation() == Boolean.FALSE) {
+ if (query.getQProfileKey() == null) {
+ // the rules that are never activated, on any profile
+ fb.mustNot(FilterBuilders.hasChildFilter(new ActiveRuleIndexDefinition().getIndexType(),
+ QueryBuilders.matchAllQuery()));
+ } else {
+ // the rules that are not activated on this profile
+ fb.mustNot(FilterBuilders.hasChildFilter(new ActiveRuleIndexDefinition().getIndexType(),
+ QueryBuilders.termQuery(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY.key(),
+ query.getQProfileKey())
+ ));
+ }
+ }
if ((query.getLanguages() != null && !query.getLanguages().isEmpty()) ||
(query.getRepositories() != null && !query.getRepositories().isEmpty()) ||
(query.getStatuses() != null && !query.getStatuses().isEmpty()) ||
(query.getKey() != null && !query.getKey().isEmpty()) ||
(query.getDebtCharacteristics() != null && !query.getDebtCharacteristics().isEmpty()) ||
- (query.getActivation() != null && !query.getActivation().isEmpty())) {
+ (query.getActivation() != null)) {
return fb;
} else {
return FilterBuilders.matchAllFilter();
protected void setFacets(SearchRequestBuilder query) {
- /* the Lang facet */
+ /* the Lang facet */
query.addAggregation(AggregationBuilders
.terms("Languages")
.field(RuleNormalizer.RuleField.LANGUAGE.key())
@Override
- protected Rule toDoc(Map<String, Object> fields, QueryOptions options) {
+ protected Rule toDoc(Map<String, Object> fields) {
Preconditions.checkArgument(fields != null, "Cannot construct Rule with null response!!!");
return new RuleDoc(fields);
}
SearchResponse esResponse = request.get();
- Terms aggregation = (Terms) esResponse.getAggregations().get(key);
+ Terms aggregation = esResponse.getAggregations().get(key);
- for (Terms.Bucket value : aggregation.getBuckets()){
+ for (Terms.Bucket value : aggregation.getBuckets()) {
tags.add(value.getKey());
}
return tags;
private Collection<String> severities;
private Collection<RuleStatus> statuses;
private Collection<String> tags;
+ private Collection<String> allOfTags;
private Collection<String> debtCharacteristics;
private Boolean hasDebtCharacteristic;
private SortField sortField;
private boolean ascendingSort = true;
- private String activation;
+ private Boolean activation;
private String qProfileKey;
/**
* TODO should not be public
+ *
* @see org.sonar.server.rule2.RuleService#newRuleQuery()
*/
public RuleQuery() {
return this;
}
- public RuleQuery setActivation(String activation) {
+ public RuleQuery setActivation(@Nullable Boolean activation) {
this.activation = activation;
return this;
}
@CheckForNull
- public String getActivation(){
+ public Boolean getActivation() {
return this.activation;
}
return this;
}
+ @CheckForNull
+ public Collection<String> getAllOfTags() {
+ return allOfTags;
+ }
+
+ public RuleQuery setAllOfTags(@Nullable Collection<String> tags) {
+ this.allOfTags = tags;
+ return this;
+ }
+
@CheckForNull
public Collection<String> getDebtCharacteristics() {
return debtCharacteristics;
return hasDebtCharacteristic;
}
- public RuleQuery setHasDebtCharacteristic(@Nullable Boolean hasDebtCharacteristic) {
- this.hasDebtCharacteristic = hasDebtCharacteristic;
+ public RuleQuery setHasDebtCharacteristic(@Nullable Boolean b) {
+ this.hasDebtCharacteristic = b;
return this;
}
*/
package org.sonar.server.rule2.index;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Multimap;
import org.elasticsearch.action.search.SearchResponse;
-import org.sonar.server.qualityprofile.ActiveRule;
import org.sonar.server.rule2.Rule;
import org.sonar.server.search.Result;
public class RuleResult extends Result<Rule> {
- private Multimap<String,ActiveRule> activeRules;
-
public RuleResult(SearchResponse response) {
super(response);
- activeRules = ArrayListMultimap.create();
}
@Override
public Collection<Rule> getRules() {
return super.getHits();
}
-
- public Multimap<String,ActiveRule> getActiveRules() {
- return this.activeRules;
- }
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.rule2.ws;
+
+import org.sonar.api.ServerComponent;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.core.qualityprofile.db.ActiveRuleKey;
+import org.sonar.core.qualityprofile.db.QualityProfileKey;
+import org.sonar.server.qualityprofile.ActiveRule;
+import org.sonar.server.qualityprofile.ActiveRuleService;
+import org.sonar.server.rule2.Rule;
+import org.sonar.server.rule2.index.RuleQuery;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Add details about active rules to api/rules/search and api/rules/show
+ * web services.
+ */
+public class ActiveRuleCompleter implements ServerComponent {
+ private final ActiveRuleService service;
+
+ public ActiveRuleCompleter(ActiveRuleService service) {
+ this.service = service;
+ }
+
+ void completeSearch(RuleQuery query, Collection<Rule> rules, JsonWriter json) {
+ json.name("actives").beginObject();
+
+ if (query.getQProfileKey() != null) {
+ // Load details of active rules on the selected profile
+ QualityProfileKey profileKey = QualityProfileKey.parse(query.getQProfileKey());
+ for (Rule rule : rules) {
+ ActiveRule activeRule = service.getByKey(ActiveRuleKey.of(profileKey, rule.key()));
+ if (activeRule != null) {
+ writeActiveRules(rule.key(), Arrays.asList(activeRule), json);
+ }
+ }
+ } else {
+ // Load details of all active rules
+ for (Rule rule : rules) {
+ writeActiveRules(rule.key(), service.findByRuleKey(rule.key()), json);
+ }
+ }
+ json.endObject();
+ }
+
+ void completeShow(Rule rule, JsonWriter json) {
+ json.name("actives").beginArray();
+ for (ActiveRule activeRule : service.findByRuleKey(rule.key())) {
+ writeActiveRule(activeRule, json);
+ }
+ json.endArray();
+ }
+
+ private void writeActiveRules(RuleKey ruleKey, Collection<ActiveRule> activeRules, JsonWriter json) {
+ if (!activeRules.isEmpty()) {
+ json.name(ruleKey.toString());
+ json.beginArray();
+ for (ActiveRule activeRule : activeRules) {
+ writeActiveRule(activeRule, json);
+ }
+ json.endArray();
+ }
+ }
+
+ private void writeActiveRule(ActiveRule activeRule, JsonWriter json) {
+ json
+ .beginObject()
+ .prop("qProfile", activeRule.key().qProfile().toString())
+ .prop("inherit", activeRule.inheritance().toString())
+ .prop("severity", activeRule.severity());
+ if (activeRule.parentKey() != null) {
+ json.prop("parent", activeRule.parentKey().toString());
+ }
+ json.name("params").beginArray();
+ for (Map.Entry<String, String> param : activeRule.params().entrySet()) {
+ json
+ .beginObject()
+ .prop("key", param.getKey())
+ .prop("value", param.getValue())
+ .endObject();
+ }
+ json.endArray().endObject();
+ }
+}
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.text.JsonWriter;
-import org.sonar.server.qualityprofile.ActiveRule;
import org.sonar.server.rule2.Rule;
import org.sonar.server.rule2.RuleService;
import org.sonar.server.rule2.index.RuleDoc;
*/
public class SearchAction implements RequestHandler {
- private static final String PARAM_REPOSITORIES = "repositories";
- private static final String PARAM_ACTIVATION = "activation";
- private static final String PARAM_QPROFILE = "qprofile";
- private static final String PARAM_SEVERITIES = "severities";
- private static final String PARAM_STATUSES = "statuses";
- private static final String PARAM_LANGUAGES = "languages";
- private static final String PARAM_DEBT_CHARACTERISTICS = "debt_characteristics";
- private static final String PARAM_HAS_DEBT_CHARACTERISTIC = "has_debt_characteristic";
- private static final String PARAM_TAGS = "tags";
- private static final String PARAM_ALL_OF_TAGS = "all_of_tags";
- private static final String PARAM_FACETS = "facets";
-
- private final RuleService service;
+ public static final String PARAM_REPOSITORIES = "repositories";
+ public static final String PARAM_ACTIVATION = "activation";
+ public static final String PARAM_QPROFILE = "qprofile";
+ public static final String PARAM_SEVERITIES = "severities";
+ public static final String PARAM_STATUSES = "statuses";
+ public static final String PARAM_LANGUAGES = "languages";
+ public static final String PARAM_DEBT_CHARACTERISTICS = "debt_characteristics";
+ public static final String PARAM_HAS_DEBT_CHARACTERISTIC = "has_debt_characteristic";
+ public static final String PARAM_TAGS = "tags";
+ public static final String PARAM_ALL_OF_TAGS = "all_of_tags";
+ public static final String PARAM_FACETS = "facets";
+
+ private final RuleService ruleService;
+ private final ActiveRuleCompleter activeRuleCompleter;
private final RuleMapping mapping;
- public SearchAction(RuleService service, RuleMapping mapping) {
- this.service = service;
+ public SearchAction(RuleService service, ActiveRuleCompleter activeRuleCompleter, RuleMapping mapping) {
+ this.ruleService = service;
+ this.activeRuleCompleter = activeRuleCompleter;
this.mapping = mapping;
}
action
.createParam(SearchOptions.PARAM_TEXT_QUERY)
.setDescription("UTF-8 search query")
- .setExampleValue("null pointer");
+ .setExampleValue("xpath");
action
.createParam(PARAM_REPOSITORIES)
.createParam(PARAM_STATUSES)
.setDescription("Comma-separated list of status codes")
.setPossibleValues(RuleStatus.values())
- .setExampleValue(RuleStatus.READY.toString());
+ .setExampleValue(RuleStatus.READY);
action
.createParam(PARAM_DEBT_CHARACTERISTICS)
.setExampleValue("security,java8");
action
- .createParam(PARAM_QPROFILE)
- .setDescription("Key of Quality profile")
- .setExampleValue("java:Sonar way");
+ .createParam(PARAM_ACTIVATION)
+ .setDescription("TODO")
+ .setBooleanPossibleValues();
action
- .createParam(PARAM_ACTIVATION)
- .setDescription("Used only if 'qprofile' is set")
- .setExampleValue("java:Sonar way")
- .setPossibleValues("false", "true", "all");
+ .createParam(PARAM_QPROFILE)
+ .setDescription("Key of Quality profile to filter on. Used only if the parameter '" +
+ PARAM_ACTIVATION + "' is set.")
+ .setExampleValue("java:Sonar way");
// TODO limit the fields to sort on + document possible values + default value ?
action
.createParam(SearchOptions.PARAM_ASCENDING)
.setDescription("Ascending sort")
.setBooleanPossibleValues()
- .setDefaultValue("true");
+ .setDefaultValue(true);
}
@Override
QueryOptions queryOptions = mapping.newQueryOptions(searchOptions);
queryOptions.setFacet(request.mandatoryParamAsBoolean(PARAM_FACETS));
- RuleResult results = service.search(query, queryOptions);
+ RuleResult results = ruleService.search(query, queryOptions);
JsonWriter json = response.newJsonWriter().beginObject();
searchOptions.writeStatistics(json, results);
writeRules(results, json, searchOptions);
if (searchOptions.hasField("actives")) {
- writeActiveRules(results, json);
+ activeRuleCompleter.completeSearch(query, results.getRules(), json);
}
if (queryOptions.isFacet()) {
-
writeFacets(results, json);
}
json.endObject().close();
}
private RuleQuery createRuleQuery(Request request) {
- RuleQuery query = service.newRuleQuery();
+ RuleQuery query = ruleService.newRuleQuery();
query.setQueryText(request.param(SearchOptions.PARAM_TEXT_QUERY));
query.setSeverities(request.paramAsStrings(PARAM_SEVERITIES));
query.setRepositories(request.paramAsStrings(PARAM_REPOSITORIES));
query.setLanguages(request.paramAsStrings(PARAM_LANGUAGES));
query.setDebtCharacteristics(request.paramAsStrings(PARAM_DEBT_CHARACTERISTICS));
query.setHasDebtCharacteristic(request.paramAsBoolean(PARAM_HAS_DEBT_CHARACTERISTIC));
- query.setActivation(request.param(PARAM_ACTIVATION));
+ query.setActivation(request.paramAsBoolean(PARAM_ACTIVATION));
query.setQProfileKey(request.param(PARAM_QPROFILE));
query.setSortField(RuleQuery.SortField.valueOfOrNull(request.param(SearchOptions.PARAM_SORT)));
query.setAscendingSort(request.mandatoryParamAsBoolean(SearchOptions.PARAM_ASCENDING));
query.setTags(request.paramAsStrings(PARAM_TAGS));
+ query.setAllOfTags(request.paramAsStrings(PARAM_ALL_OF_TAGS));
return query;
}
json.endArray();
}
- private void writeActiveRules(RuleResult result, JsonWriter json) {
- json.name("actives").beginObject();
- for (Map.Entry<String, Collection<ActiveRule>> entry : result.getActiveRules().asMap().entrySet()) {
- // rule key
- json.name(entry.getKey());
- json.beginArray();
- for (ActiveRule activeRule : entry.getValue()) {
- writeActiveRule(json, activeRule);
- }
- json.endArray();
- }
- json.endObject();
- }
-
- /**
- * This method is static and package protected because it's used by {@link org.sonar.server.rule2.ws.ShowAction}
- */
- static void writeActiveRule(JsonWriter json, ActiveRule activeRule) {
- json
- .beginObject()
- .prop("qProfile", activeRule.key().qProfile().toString())
- .prop("inherit", activeRule.inheritance().toString())
- .prop("severity", activeRule.severity());
- if (activeRule.parentKey() != null) {
- json.prop("parent", activeRule.parentKey().toString());
- }
- json.name("params").beginArray();
- for (Map.Entry<String, String> param : activeRule.params().entrySet()) {
- json
- .beginObject()
- .prop("key", param.getKey())
- .prop("value", param.getValue())
- .endObject();
- }
- json.endArray().endObject();
- }
-
private void writeFacets(RuleResult results, JsonWriter json) {
json.name("facets").beginArray();
for (Map.Entry<String, Collection<FacetValue>> facet : results.getFacets().entrySet()) {
- System.out.println("facet = " + facet);
json.beginObject();
json.prop("name", facet.getKey());
json.name("values").beginArray();
for (FacetValue facetValue : facet.getValue()) {
json.beginObject();
json.prop("val", facetValue.getKey());
- json.prop("count", (Integer) facetValue.getValue());
+ json.prop("count", facetValue.getValue());
json.endObject();
}
- json.endArray();
- json.endObject();
+ json.endArray().endObject();
}
json.endArray();
}
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.qualityprofile.ActiveRule;
-import org.sonar.server.qualityprofile.ActiveRuleService;
import org.sonar.server.rule2.Rule;
import org.sonar.server.rule2.RuleService;
import org.sonar.server.search.BaseDoc;
-import java.util.List;
-
/**
* @since 4.4
*/
public class ShowAction implements RequestHandler {
- private static final String PARAM_KEY = "key";
- private static final String PARAM_ACTIVATION = "activation";
+ public static final String PARAM_KEY = "key";
+ public static final String PARAM_ACTIVES = "actives";
private final RuleService service;
private final RuleMapping mapping;
- private final ActiveRuleService activeRuleService;
+ private final ActiveRuleCompleter activeRuleCompleter;
- public ShowAction(RuleService service, ActiveRuleService activeRuleService, RuleMapping mapping) {
+ public ShowAction(RuleService service, ActiveRuleCompleter activeRuleCompleter, RuleMapping mapping) {
this.service = service;
this.mapping = mapping;
- this.activeRuleService = activeRuleService;
+ this.activeRuleCompleter = activeRuleCompleter;
}
void define(WebService.NewController controller) {
.setExampleValue("javascript:EmptyBlock");
action
- .createParam(PARAM_ACTIVATION)
- .setDescription("Show rule's activations for all profiles (ActiveRules)")
- .setDefaultValue("true")
- .setBooleanPossibleValues();
+ .createParam(PARAM_ACTIVES)
+ .setDescription("Show rule's activations for all profiles (\"active rules\")")
+ .setBooleanPossibleValues()
+ .setDefaultValue(false);
}
@Override
JsonWriter json = response.newJsonWriter().beginObject().name("rule");
mapping.write((BaseDoc) rule, json);
- if (request.mandatoryParamAsBoolean(PARAM_ACTIVATION)) {
- writeActiveRules(activeRuleService.findByRuleKey(key), json);
+ if (request.mandatoryParamAsBoolean(PARAM_ACTIVES)) {
+ activeRuleCompleter.completeShow(rule, json);
}
json.endObject().close();
}
-
- void writeActiveRules(List<ActiveRule> activeRules, JsonWriter json) {
- json.name("actives").beginArray();
- for (ActiveRule activeRule : activeRules) {
- SearchAction.writeActiveRule(json, activeRule);
- }
- json.endArray();
-
- }
}
/* Base CRUD methods */
- protected abstract D toDoc(Map<String,Object> fields, QueryOptions options);
+ protected abstract D toDoc(Map<String,Object> fields);
public D getByKey(K key) {
GetResponse response = getClient().prepareGet()
.setRouting(this.getKeyValue(key))
.get();
if (response.isExists()) {
- return toDoc(response.getSource(), QueryOptions.DEFAULT);
+ return toDoc(response.getSource());
}
return null;
}
import org.sonar.server.qualityprofile.persistence.ActiveRuleDao;
import org.sonar.server.rule2.index.RuleIndex;
import org.sonar.server.rule2.index.RuleNormalizer;
-import org.sonar.server.rule2.index.RuleQuery;
-import org.sonar.server.rule2.index.RuleResult;
import org.sonar.server.rule2.persistence.RuleDao;
-import org.sonar.server.search.QueryOptions;
import org.sonar.server.tester.ServerTester;
import org.sonar.server.user.MockUserSession;
dao.insert(newRuleDto(rule1)
.setTags(Sets.newHashSet("security"))
.setSystemTags(Collections.<String>emptySet()),
- dbSession);
+ dbSession
+ );
RuleKey rule2 = RuleKey.of("java", "S001");
dao.insert(newRuleDto(rule2)
RuleKey rule1 = RuleKey.of("javascript", "S001");
dao.insert(newRuleDto(rule1)
.setTags(Sets.newHashSet("security"))
- .setSystemTags(Sets.newHashSet("java-coding","stephane.gamard@sonarsource.com")),
- dbSession);
+ .setSystemTags(Sets.newHashSet("java-coding", "stephane.gamard@sonarsource.com")),
+ dbSession
+ );
RuleKey rule2 = RuleKey.of("java", "S001");
dao.insert(newRuleDto(rule2)
dbSession.commit();
-
Set<String> tags = index.terms(RuleNormalizer.RuleField._TAGS.key());
- assertThat(tags).containsOnly("java-coding","security",
- "stephane.gamard@sonarsource.com","mytag");
+ assertThat(tags).containsOnly("java-coding", "security",
+ "stephane.gamard@sonarsource.com", "mytag");
tags = index.terms(RuleNormalizer.RuleField.SYSTEM_TAGS.key());
assertThat(tags).containsOnly("java-coding",
public void test_search_activation_on_rules() throws InterruptedException {
// 1. Create in DB
- QualityProfileDto qprofile1 = QualityProfileDto.createFor("profile1","java");
- QualityProfileDto qprofile2 = QualityProfileDto.createFor("profile2","java");
+ QualityProfileDto qprofile1 = QualityProfileDto.createFor("profile1", "java");
+ QualityProfileDto qprofile2 = QualityProfileDto.createFor("profile2", "java");
tester.get(QualityProfileDao.class).insert(qprofile1, dbSession);
tester.get(QualityProfileDao.class).insert(qprofile2, dbSession);
dbSession.commit();
-
// 2. test in DB
assertThat(tester.get(RuleDao.class).findAll(dbSession)).hasSize(2);
assertThat(tester.get(ActiveRuleDao.class).findByRule(rule1, dbSession)).hasSize(1);
// 3. Test for ALL activations
- RuleQuery query = new RuleQuery()
- .setActivation("all");
- RuleResult result = service.search(query, new QueryOptions());
- assertThat(result.getActiveRules().values()).hasSize(3);
-
- // 4. Test for NO active rules
- query = new RuleQuery()
- .setActivation("false");
- result = service.search(query, new QueryOptions());
- assertThat(result.getActiveRules().values()).hasSize(0);
-
- // 4. Test for active rules of QProfile
- query = new RuleQuery()
- .setActivation("true")
- .setQProfileKey(qprofile1.getKey().toString());
- result = service.search(query, new QueryOptions());
- assertThat(result.getActiveRules().values()).hasSize(2);
+ // TODO
+// RuleQuery query = new RuleQuery()
+// .setActivation("all");
+// RuleResult result = service.search(query, new QueryOptions());
+// assertThat(result.getActiveRules().values()).hasSize(3);
+//
+// // 4. Test for NO active rules
+// query = new RuleQuery()
+// .setActivation("false");
+// result = service.search(query, new QueryOptions());
+// assertThat(result.getActiveRules().values()).hasSize(0);
+//
+// // 4. Test for active rules of QProfile
+// query = new RuleQuery()
+// .setActivation("true")
+// .setQProfileKey(qprofile1.getKey().toString());
+// result = service.search(query, new QueryOptions());
+// assertThat(result.getActiveRules().values()).hasSize(2);
}
private RuleDto newRuleDto(RuleKey ruleKey) {
RuleResult result;
// 1. get all active rules.
- result = index.search(new RuleQuery().setActivation("all"),
+ result = index.search(new RuleQuery().setActivation(true),
new QueryOptions());
assertThat(result.getHits()).hasSize(2);
// 2. get all inactive rules.
- result = index.search(new RuleQuery().setActivation("false"),
+ result = index.search(new RuleQuery().setActivation(false),
new QueryOptions());
assertThat(result.getHits()).hasSize(1);
assertThat(result.getHits().get(0).name()).isEqualTo(rule3.getName());
- // 3. get all active rules missing profile.
- try {
- index.search(new RuleQuery().setActivation("true"),
+ // 3. get all rules not active on profile
+ index.search(new RuleQuery().setActivation(false).setQProfileKey(qualityProfileDto2.getKey().toString()),
new QueryOptions());
- fail();
- } catch (IllegalStateException e) {
- assertThat(e).hasMessage("qProfile is required when \"activation=true\"");
- }
+ // TODO
+ assertThat(result.getRules()).hasSize(1);
- // 4. get all active rules. for qualityProfileDto2
- result = index.search(new RuleQuery().setActivation("true")
+ // 4. get all active rules on profile
+ result = index.search(new RuleQuery().setActivation(true)
.setQProfileKey(qualityProfileDto2.getKey().toString()),
new QueryOptions()
);