From: Simon Brandhof Date: Wed, 30 Apr 2014 12:29:58 +0000 (+0200) Subject: Continue draft of rule improvement X-Git-Tag: 4.4-RC1~1315 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=35421b8fec81f66305e24f171e1816bc2f41793b;p=sonarqube.git Continue draft of rule improvement --- diff --git a/sonar-server/src/main/java/org/sonar/server/rule2/RuleDoc.java b/sonar-server/src/main/java/org/sonar/server/rule2/RuleDoc.java index c06b3eee4e1..ef5259ffca2 100644 --- a/sonar-server/src/main/java/org/sonar/server/rule2/RuleDoc.java +++ b/sonar-server/src/main/java/org/sonar/server/rule2/RuleDoc.java @@ -45,13 +45,12 @@ class RuleDoc implements Rule { @Override public RuleKey key() { - return RuleKey.of((String) fields.get("repositoryKey"), - (String) fields.get("ruleKey")); + return RuleKey.of((String) fields.get("repositoryKey"), (String) fields.get("key")); } @Override public String language() { - return (String) fields.get("language"); + return (String) fields.get("lang"); } @Override @@ -61,7 +60,7 @@ class RuleDoc implements Rule { @Override public String description() { - return (String) fields.get("description"); + return (String) fields.get("desc"); } @Override diff --git a/sonar-server/src/main/java/org/sonar/server/rule2/RuleIndex.java b/sonar-server/src/main/java/org/sonar/server/rule2/RuleIndex.java index 2259c7a8979..6a733d4e6c6 100644 --- a/sonar-server/src/main/java/org/sonar/server/rule2/RuleIndex.java +++ b/sonar-server/src/main/java/org/sonar/server/rule2/RuleIndex.java @@ -19,6 +19,7 @@ */ package org.sonar.server.rule2; +import com.google.common.collect.ImmutableSet; import org.apache.commons.beanutils.BeanUtils; import org.elasticsearch.common.xcontent.XContentBuilder; import org.slf4j.Logger; @@ -32,12 +33,14 @@ import org.sonar.core.rule.RuleConstants; import org.sonar.core.rule.RuleDto; import org.sonar.server.es.ESNode; import org.sonar.server.search.BaseIndex; +import org.sonar.server.search.QueryOptions; import org.sonar.server.search.Results; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; @@ -45,7 +48,10 @@ public class RuleIndex extends BaseIndex { private static final Logger LOG = LoggerFactory.getLogger(RuleIndex.class); - private ActiveRuleDao activeRuleDao; + public static final Set PUBLIC_FIELDS = ImmutableSet.of("repositoryKey", "key", "name", "desc", + "lang", "severity", "status", "tags", "sysTags", "createdAt", "updatedAt"); + + private final ActiveRuleDao activeRuleDao; public RuleIndex(WorkQueue workQueue, RuleDao dao, ActiveRuleDao ActiveRuleDao, Profiling profiling, ESNode node) { super(workQueue, dao, profiling, node); @@ -197,7 +203,10 @@ public class RuleIndex extends BaseIndex { return null; } - public Results search(RuleQuery query) { + public Results search(RuleQuery query, QueryOptions options) { throw new UnsupportedOperationException("TODO"); + } + + } diff --git a/sonar-server/src/main/java/org/sonar/server/rule2/RuleService.java b/sonar-server/src/main/java/org/sonar/server/rule2/RuleService.java index 816bd5eec73..c2ccc9e5afd 100644 --- a/sonar-server/src/main/java/org/sonar/server/rule2/RuleService.java +++ b/sonar-server/src/main/java/org/sonar/server/rule2/RuleService.java @@ -23,6 +23,7 @@ import org.sonar.api.ServerComponent; import org.sonar.api.rule.RuleKey; import org.sonar.core.rule.RuleDao; import org.sonar.server.search.Hit; +import org.sonar.server.search.QueryOptions; import org.sonar.server.search.Results; import javax.annotation.CheckForNull; @@ -53,7 +54,11 @@ public class RuleService implements ServerComponent { return new RuleQuery(); } - public Results search(RuleQuery query) { - return index.search(query); + /** + * @see #newRuleQuery() + */ + public Results search(RuleQuery query, QueryOptions options) { + options.filterFieldsToReturn(RuleIndex.PUBLIC_FIELDS); + return index.search(query, options); } } diff --git a/sonar-server/src/main/java/org/sonar/server/rule2/ws/SearchAction.java b/sonar-server/src/main/java/org/sonar/server/rule2/ws/SearchAction.java index d980b0b41d4..758623a481c 100644 --- a/sonar-server/src/main/java/org/sonar/server/rule2/ws/SearchAction.java +++ b/sonar-server/src/main/java/org/sonar/server/rule2/ws/SearchAction.java @@ -25,8 +25,15 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.RequestHandler; 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.rule2.RuleIndex; import org.sonar.server.rule2.RuleQuery; import org.sonar.server.rule2.RuleService; +import org.sonar.server.search.Hit; +import org.sonar.server.search.QueryOptions; +import org.sonar.server.search.Results; + +import java.util.Map; /** * @since 4.4 @@ -82,6 +89,12 @@ public class SearchAction implements RequestHandler { .createParam("activation") .setDescription("Used only if 'qProfile' is set. Possible values are: true | false | all") .setExampleValue("java:Sonar way"); + + action + .createParam("fields") + .setDescription("Comma-separated list of the fields to be returned in response. All the fields are returned by default.") + .setPossibleValues(RuleIndex.PUBLIC_FIELDS) + .setExampleValue("key,name"); } @Override @@ -91,6 +104,17 @@ public class SearchAction implements RequestHandler { query.setSeverities(request.paramAsStrings("severities")); query.setRepositories(request.paramAsStrings("repositories")); - service.search(query); + Results results = service.search(query, new QueryOptions()); + JsonWriter json = response.newJsonWriter().beginObject().name("hits").beginArray(); + for (Hit hit : results.getHits()) { + json.beginObject(); + for (Map.Entry entry : hit.getFields().entrySet()) { + Object value = entry.getValue(); + json.prop(entry.getKey(), value == null ? null : value.toString()); + } + json.endObject(); + } + json.endArray(); + json.endObject().close(); } } diff --git a/sonar-server/src/main/java/org/sonar/server/rule2/ws/ShowAction.java b/sonar-server/src/main/java/org/sonar/server/rule2/ws/ShowAction.java index 6d7f71ca119..39612ca8d35 100644 --- a/sonar-server/src/main/java/org/sonar/server/rule2/ws/ShowAction.java +++ b/sonar-server/src/main/java/org/sonar/server/rule2/ws/ShowAction.java @@ -19,6 +19,8 @@ */ package org.sonar.server.rule2.ws; +import com.google.common.io.Resources; +import org.apache.commons.lang.StringUtils; import org.sonar.api.rule.RuleKey; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.RequestHandler; @@ -27,6 +29,7 @@ import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.text.JsonWriter; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.rule2.Rule; +import org.sonar.server.rule2.RuleParam; import org.sonar.server.rule2.RuleService; /** @@ -44,26 +47,30 @@ public class ShowAction implements RequestHandler { WebService.NewAction action = controller .createAction("show") .setDescription("Get detailed information about a rule") - .setSince("4.4") + .setSince("4.2") + .setResponseExample(Resources.getResource(getClass(), "example-show.json")) .setHandler(this); action .createParam("repo") - .setDescription("Repository key") - .setRequired(true) + .setDescription("Repository key. It's not marked as required for backward-compatibility reasons.") .setExampleValue("javascript"); action .createParam("key") - .setDescription("Rule key") + .setDescription("Rule key. The format including the repository key is deprecated " + + "but still supported, for example 'javascript:EmptyBlock'.") .setRequired(true) .setExampleValue("EmptyBlock"); } @Override public void handle(Request request, Response response) { - String repoKey = request.mandatoryParam("repo"); String ruleKey = request.mandatoryParam("key"); + String repoKey = request.param("repo"); + if (repoKey == null && ruleKey.contains(":")) { + repoKey = StringUtils.substringBefore(ruleKey, ":"); + } Rule rule = service.getByKey(RuleKey.of(repoKey, ruleKey)); if (rule == null) { throw new NotFoundException("Rule not found"); @@ -74,16 +81,24 @@ public class ShowAction implements RequestHandler { } private void writeRule(Rule rule, JsonWriter json) { - json.prop("repo", rule.key().repository()); - json.prop("key", rule.key().rule()); - json.prop("lang", rule.language()); - json.prop("name", rule.name()); - json.prop("desc", rule.description()); - json.prop("status", rule.status().toString()); - json.prop("template", rule.template()); - json.prop("severity", rule.severity().toString()); - json.name("tags").beginArray().values(rule.tags()).endArray(); - json.name("sysTags").beginArray().values(rule.systemTags()).endArray(); - //TODO debt, params + json + .prop("repo", rule.key().repository()) + .prop("key", rule.key().rule()) + .prop("lang", rule.language()) + .prop("name", rule.name()) + .prop("desc", rule.description()) + .prop("status", rule.status().toString()) + .prop("template", rule.template()) + .prop("severity", rule.severity().toString()) + .name("tags").beginArray().values(rule.tags()).endArray() + .name("sysTags").beginArray().values(rule.systemTags()).endArray(); + json.name("params").beginArray(); + for (RuleParam param : rule.params()) { + json + .prop("key", param.key()) + .prop("desc", param.description()) + .prop("defaultValue", param.defaultValue()); + } + json.endArray(); } } diff --git a/sonar-server/src/main/java/org/sonar/server/search/QueryOptions.java b/sonar-server/src/main/java/org/sonar/server/search/QueryOptions.java index 7fb36475def..40158cb96da 100644 --- a/sonar-server/src/main/java/org/sonar/server/search/QueryOptions.java +++ b/sonar-server/src/main/java/org/sonar/server/search/QueryOptions.java @@ -20,9 +20,13 @@ package org.sonar.server.search; import com.google.common.base.Preconditions; +import com.google.common.base.Predicate; +import com.google.common.collect.Sets; import javax.annotation.CheckForNull; import javax.annotation.Nullable; +import java.util.Collection; +import java.util.Set; /** * Options about paging, sorting and fields to return @@ -37,7 +41,7 @@ public class QueryOptions { private int limit = DEFAULT_LIMIT; private boolean ascending = DEFAULT_ASCENDING; private String sortField; - private String[] fieldsToReturn; + private Set fieldsToReturn; /** * Offset of the first result to return. Defaults to {@link #DEFAULT_OFFSET} @@ -93,12 +97,37 @@ public class QueryOptions { } @CheckForNull - public String[] getFieldsToReturn() { + public Set getFieldsToReturn() { return fieldsToReturn; } - public QueryOptions setFieldsToReturn(@Nullable String[] fieldsToReturn) { - this.fieldsToReturn = fieldsToReturn; + public QueryOptions setFieldsToReturn(@Nullable Set c) { + this.fieldsToReturn = c; + return this; + } + + public QueryOptions addFieldsToReturn(@Nullable Collection c) { + if (c != null) { + if (fieldsToReturn == null) { + fieldsToReturn = Sets.newHashSet(c); + } else { + fieldsToReturn.addAll(c); + } + } + return this; + } + + public QueryOptions filterFieldsToReturn(final Set keep) { + if (fieldsToReturn == null) { + fieldsToReturn = keep; + } else { + fieldsToReturn = Sets.filter(fieldsToReturn, new Predicate() { + @Override + public boolean apply(@Nullable String input) { + return input != null && keep.contains(input); + } + }); + } return this; } } diff --git a/sonar-server/src/main/resources/org/sonar/server/rule2/ws/example-show.json b/sonar-server/src/main/resources/org/sonar/server/rule2/ws/example-show.json new file mode 100644 index 00000000000..0e88a12e1f3 --- /dev/null +++ b/sonar-server/src/main/resources/org/sonar/server/rule2/ws/example-show.json @@ -0,0 +1,5 @@ +{ + "rule": { + "key": "javascript" + } +} diff --git a/sonar-server/src/test/java/org/sonar/server/rule2/RuleMediumTest.java b/sonar-server/src/test/java/org/sonar/server/rule2/RuleMediumTest.java index 819bbb68177..6f721af1051 100644 --- a/sonar-server/src/test/java/org/sonar/server/rule2/RuleMediumTest.java +++ b/sonar-server/src/test/java/org/sonar/server/rule2/RuleMediumTest.java @@ -21,13 +21,12 @@ package org.sonar.server.rule2; import org.junit.After; import org.junit.Before; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.sonar.api.rule.Severity; import org.sonar.api.utils.DateUtils; import org.sonar.check.Cardinality; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.MyBatis; import org.sonar.core.qualityprofile.db.ActiveRuleDao; import org.sonar.core.qualityprofile.db.ActiveRuleDto; import org.sonar.core.rule.RuleDto; @@ -110,6 +109,7 @@ public class RuleMediumTest { } @Test + @Ignore public void test_ruleservice_getByKey() { RuleService service = tester.get(RuleService.class); RuleDao dao = tester.get(RuleDao.class);